1 /*
2  * CoordinationInterface.h
3  *
4  * This source file is part of the FoundationDB open source project
5  *
6  * Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef FDBSERVER_COORDINATIONINTERFACE_H
22 #define FDBSERVER_COORDINATIONINTERFACE_H
23 #pragma once
24 
25 #include "fdbclient/CoordinationInterface.h"
26 
27 struct GenerationRegInterface {
28 	RequestStream< struct GenerationRegReadRequest > read;
29 	RequestStream< struct GenerationRegWriteRequest > write;
30 
31 	// read(key,gen2) returns (value,gen,rgen).
32 	//   If there was no prior write(_,_,0) or a data loss fault,
33 	//     returns (Optional(),0,0)   //< FIXME: The returned rgen is not zero, but >= gen2!  (Specification bug)
34 	//   Else
35 	//     There was some earlier or concurrent write(key,value,gen).
36 	//     There was some earlier or concurrent read(key,rgen).
37 	//     If there is a write(key,_,gen1)=>gen1 s.t. gen1 < gen2 OR the write completed before this read started, then gen >= gen1.
38 	//     If there is a read(key,gen1) that completed before this read started, then rgen >= gen1
39 	// write(key,value,gen) returns gen1.
40 	//   If gen>0 and there was no prior write(_,_,0) or a data loss fault, throws not_created()?
41 	//   (gen1==gen is considered a "successful" write)
42 	//   There is some earlier or concurrent read(key,gen1) or write(key,_,gen1).  (In the successful case, the concurrent write is this one)
43 
44 	// All instances of the pattern
45 	//    read(key, g)=>v1 and write(key, v2, g)=>true
46 	// thus form a totally ordered sequence of modifications, in which
47 	// the v2 of the previous generation is the v1 of the next.
48 
GenerationRegInterfaceGenerationRegInterface49 	GenerationRegInterface() {}
50 	GenerationRegInterface( NetworkAddress remote );
51 	GenerationRegInterface( INetwork* local );
52 };
53 
54 struct UniqueGeneration {
55 	uint64_t generation;
56 	UID uid;
UniqueGenerationUniqueGeneration57 	UniqueGeneration() : generation(0) {}
UniqueGenerationUniqueGeneration58 	UniqueGeneration( uint64_t generation, UID uid ) : generation(generation), uid(uid) {}
59 	bool operator < (UniqueGeneration const& r) const {
60 		if (generation < r.generation) return true;
61 		if (r.generation < generation) return false;
62 		return uid < r.uid;
63 	}
64 	bool operator == (UniqueGeneration const& r) const {
65 		return generation == r.generation && uid == r.uid;
66 	}
67 	template <class Ar>
serializeUniqueGeneration68 	void serialize(Ar& ar) {
69 		serializer(ar, generation, uid);
70 	}
71 };
72 
73 struct GenerationRegReadRequest {
74 	Key key;
75 	UniqueGeneration gen;
76 	ReplyPromise<struct GenerationRegReadReply> reply;
GenerationRegReadRequestGenerationRegReadRequest77 	GenerationRegReadRequest(){}
GenerationRegReadRequestGenerationRegReadRequest78 	GenerationRegReadRequest( Key key, UniqueGeneration gen ) : key(key), gen(gen) {}
79 	template <class Ar>
serializeGenerationRegReadRequest80 	void serialize(Ar& ar) {
81 		serializer(ar, key, gen, reply);
82 	}
83 };
84 
85 struct GenerationRegReadReply {
86 	Optional<Value> value;
87 	UniqueGeneration gen, rgen;
GenerationRegReadReplyGenerationRegReadReply88 	GenerationRegReadReply() {}
GenerationRegReadReplyGenerationRegReadReply89 	GenerationRegReadReply( Optional<Value> value, UniqueGeneration gen, UniqueGeneration rgen ) : value(value), gen(gen), rgen(rgen) {}
90 	template <class Ar>
serializeGenerationRegReadReply91 	void serialize(Ar& ar) {
92 		serializer(ar, value, gen, rgen);
93 	}
94 };
95 
96 struct GenerationRegWriteRequest {
97 	KeyValue kv;
98 	UniqueGeneration gen;
99 	ReplyPromise< UniqueGeneration > reply;
GenerationRegWriteRequestGenerationRegWriteRequest100 	GenerationRegWriteRequest() {}
GenerationRegWriteRequestGenerationRegWriteRequest101 	GenerationRegWriteRequest(KeyValue kv, UniqueGeneration gen) : kv(kv), gen(gen) {}
102 	template <class Ar>
serializeGenerationRegWriteRequest103 	void serialize(Ar& ar) {
104 		serializer(ar, kv, gen, reply);
105 	}
106 };
107 
108 struct LeaderElectionRegInterface : ClientLeaderRegInterface {
109 	RequestStream< struct CandidacyRequest > candidacy;
110 	RequestStream< struct LeaderHeartbeatRequest > leaderHeartbeat;
111 	RequestStream< struct ForwardRequest > forward;
112 
LeaderElectionRegInterfaceLeaderElectionRegInterface113 	LeaderElectionRegInterface() {}
114 	LeaderElectionRegInterface(NetworkAddress remote);
115 	LeaderElectionRegInterface(INetwork* local);
116 };
117 
118 struct CandidacyRequest {
119 	Key key;
120 	LeaderInfo myInfo;
121 	UID knownLeader, prevChangeID;
122 	ReplyPromise<Optional<LeaderInfo>> reply;
123 
CandidacyRequestCandidacyRequest124 	CandidacyRequest() {}
CandidacyRequestCandidacyRequest125 	CandidacyRequest(Key key, LeaderInfo const& myInfo, UID const& knownLeader, UID const& prevChangeID) : key(key), myInfo(myInfo), knownLeader(knownLeader), prevChangeID(prevChangeID) {}
126 
127 	template <class Ar>
serializeCandidacyRequest128 	void serialize(Ar& ar) {
129 		serializer(ar, key, myInfo, knownLeader, prevChangeID, reply);
130 	}
131 };
132 
133 struct LeaderHeartbeatRequest {
134 	Key key;
135 	LeaderInfo myInfo;
136 	UID prevChangeID;
137 	ReplyPromise<bool> reply;
138 
LeaderHeartbeatRequestLeaderHeartbeatRequest139 	LeaderHeartbeatRequest() {}
LeaderHeartbeatRequestLeaderHeartbeatRequest140 	explicit LeaderHeartbeatRequest( Key key, LeaderInfo const& myInfo, UID prevChangeID ) : key(key), myInfo(myInfo), prevChangeID(prevChangeID) {}
141 
142 	template <class Ar>
serializeLeaderHeartbeatRequest143 	void serialize(Ar& ar) {
144 		serializer(ar, key, myInfo, prevChangeID, reply);
145 	}
146 };
147 
148 struct ForwardRequest {
149 	Key key;
150 	Value conn;  // a cluster connection string
151 	ReplyPromise<Void> reply;
152 
ForwardRequestForwardRequest153 	ForwardRequest() {}
ForwardRequestForwardRequest154 	ForwardRequest( Key key, Value conn ) : key(key), conn(conn) {}
155 
156 	template <class Ar>
serializeForwardRequest157 	void serialize(Ar& ar) {
158 		serializer(ar, key, conn, reply);
159 	}
160 };
161 
162 class ServerCoordinators : public ClientCoordinators {
163 public:
164 	explicit ServerCoordinators( Reference<ClusterConnectionFile> );
165 
166 	vector<LeaderElectionRegInterface> leaderElectionServers;
167 	vector<GenerationRegInterface> stateServers;
168 };
169 
170 Future<Void> coordinationServer( std::string const& dataFolder );
171 
172 #endif
173