blob: 72301d5f4b4800b10223ffc0ae18ae92a72b52d2 [file] [log] [blame]
Dave Presottoc5494282016-01-29 14:46:52 -08001// Copyright 2015 The Vanadium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package raft
6
7import (
8 "io"
9 "time"
10
11 "v.io/v23/context"
12 "v.io/v23/security/access"
13)
14
15// Raft provides a consistent log across multiple instances of a client.
16
17// RaftClient defines the call backs from the Raft library to the application.
18type RaftClient interface {
19 // Apply appies a logged command, 'cmd', to the client. The commands will
20 // be delivered in the same order and with the same 'index' to all clients.
21 // 'index' is a monotonically increasing number and is just an index into the
22 // common log.
23 //
24 // Whenever a client restarts (after a crash perhaps) or falls too far behind
25 // (as in a partitioned network) it will be reinitialized with a RestoreFomSnapshot
26 // and then replayed all subsequent logged commands.
27 //
28 // A client that wishes to may return empty snapshots, i.e., just close the error
29 // channel without writing anything and worry about reliably storing its database
30 // itself. It that case it must remember the highest index it has seen if it wishes
31 // to avoid replays. Hence the index is supplied with the Apply().
32 Apply(cmd []byte, index Index) error
33
34 // SaveToSnapshot requests the application to write a snapshot to 'wr'.
35 // Until SaveToSnapshot returns, no commands will be Apply()ed. Closing
36 // the response channel signals that the snapshot is finished. Any
37 // error written to the response channel will be logged by the library
38 // and the library will discard the snapshot if any error is returned.
39 SaveToSnapshot(ctx *context.T, wr io.Writer, response chan<- error) error
40
41 // RestoreFromSnapshot requests the application to rebuild its database from the snapshot
42 // it must read from 'rd'. 'index' is the last index applied to the snapshot. No Apply()s
43 // will be performed until RestoreFromSnapshot() returns. 'index' can be ignored
44 // or used for debugging.
45 RestoreFromSnapshot(ctx *context.T, index Index, rd io.Reader) error
46}
47
48const (
49 RoleCandidate = iota // Requesting to be voted leader.
50 RoleFollower
51 RoleLeader
52 RoleStopped
53)
54
55type Raft interface {
56 // AddMember adds a new member to the server set. "id" is actually a network address for the member,
57 // currently host:port. This has to be done before starting the server.
58 AddMember(ctx *context.T, id string) error
59
60 // Id returns the id of this member.
61 Id() string
62
63 // Start starts the local server communicating with other members.
64 Start()
65
66 // Stop terminates the server. It cannot be Start'ed again.
67 Stop()
68
69 // Append appends a new command to the replicated log. The command will be Apply()ed at each member
70 // once a quorum has logged it. The Append() will terminate once a quorum has logged it and at least
71 // the leader has Apply()ed the command. 'applyError' is the error returned by the Apply() while
72 // 'raftError' is returned by the raft library itself reporting that the Append could not be
73 // performed.
74 Append(ctx *context.T, cmd []byte) (applyError, raftError error)
75
76 // Status returns the state of the raft.
77 Status() (myId string, role int, leader string)
78
79 // StartElection forces an election. Normally just used for debugging.
80 StartElection()
81}
82
83// RaftConfig is passed to NewRaft to avoid lots of parameters.
84type RaftConfig struct {
Benjamin Prosnitze14a5952016-02-02 16:37:49 -080085 LogDir string // Directory in which to put log and snapshot files.
86 HostPort string // For RPCs from other members.
87 ServerName string // Where to mount if not empty.
88 Heartbeat time.Duration // Time between heartbeats.
89 SnapshotThreshold int64 // Approximate number of log entries between snapshots.
90 Acl access.AccessList // For sending RPC to the members.
Dave Presottoc5494282016-01-29 14:46:52 -080091}
92
93// NewRaft creates a new raft server.
94func NewRaft(ctx *context.T, config *RaftConfig, client RaftClient) (Raft, error) {
95 return newRaft(ctx, config, client)
96}