xref: /aosp_15_r20/external/federated-compute/fcp/aggregation/protocol/aggregation_protocol.h (revision 14675a029014e728ec732f129a32e299b2da0601)
1*14675a02SAndroid Build Coastguard Worker /*
2*14675a02SAndroid Build Coastguard Worker  * Copyright 2022 Google LLC
3*14675a02SAndroid Build Coastguard Worker  *
4*14675a02SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*14675a02SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*14675a02SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*14675a02SAndroid Build Coastguard Worker  *
8*14675a02SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*14675a02SAndroid Build Coastguard Worker  *
10*14675a02SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*14675a02SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*14675a02SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*14675a02SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*14675a02SAndroid Build Coastguard Worker  * limitations under the License.
15*14675a02SAndroid Build Coastguard Worker  */
16*14675a02SAndroid Build Coastguard Worker 
17*14675a02SAndroid Build Coastguard Worker #ifndef FCP_AGGREGATION_PROTOCOL_AGGREGATION_PROTOCOL_H_
18*14675a02SAndroid Build Coastguard Worker #define FCP_AGGREGATION_PROTOCOL_AGGREGATION_PROTOCOL_H_
19*14675a02SAndroid Build Coastguard Worker 
20*14675a02SAndroid Build Coastguard Worker #include "absl/status/status.h"
21*14675a02SAndroid Build Coastguard Worker #include "absl/strings/cord.h"
22*14675a02SAndroid Build Coastguard Worker #include "fcp/aggregation/protocol/aggregation_protocol_messages.pb.h"
23*14675a02SAndroid Build Coastguard Worker 
24*14675a02SAndroid Build Coastguard Worker namespace fcp::aggregation {
25*14675a02SAndroid Build Coastguard Worker 
26*14675a02SAndroid Build Coastguard Worker // Describes a abstract aggregation protocol interface between a networking
27*14675a02SAndroid Build Coastguard Worker // layer (e.g. a service that handles receiving and sending messages with the
28*14675a02SAndroid Build Coastguard Worker // client devices) and an implementation of an aggregation algorithm.
29*14675a02SAndroid Build Coastguard Worker //
30*14675a02SAndroid Build Coastguard Worker // The design of the AggregationProtocol follows a Bridge Pattern
31*14675a02SAndroid Build Coastguard Worker // (https://en.wikipedia.org/wiki/Bridge_pattern) in that it is meant to
32*14675a02SAndroid Build Coastguard Worker // decouple an abstraction of the layers above and below the AggregationProtocol
33*14675a02SAndroid Build Coastguard Worker // from the implementation.
34*14675a02SAndroid Build Coastguard Worker //
35*14675a02SAndroid Build Coastguard Worker // In this interface the receiving and sending contributing inputs or
36*14675a02SAndroid Build Coastguard Worker // messages is abstracted from the actual mechanism for sending and receiving
37*14675a02SAndroid Build Coastguard Worker // data over the network and from the actual aggregation mechanism.
38*14675a02SAndroid Build Coastguard Worker //
39*14675a02SAndroid Build Coastguard Worker // Client identification: the real client identities are hidden from the
40*14675a02SAndroid Build Coastguard Worker // protocol implementations. Instead each client is identified by a client_id
41*14675a02SAndroid Build Coastguard Worker // number in a range [0, num_clients) where num_clients is the number of clients
42*14675a02SAndroid Build Coastguard Worker // the protocol started with or the extended number of clients, which is the
43*14675a02SAndroid Build Coastguard Worker // sum of the starting num_clients and num_clients passed to each subsequent
44*14675a02SAndroid Build Coastguard Worker // AddClients call.
45*14675a02SAndroid Build Coastguard Worker //
46*14675a02SAndroid Build Coastguard Worker // Thread safety: for any given client identified by a unique client_id, the
47*14675a02SAndroid Build Coastguard Worker // protocol methods are expected to be called sequentially. But there are no
48*14675a02SAndroid Build Coastguard Worker // assumptions about concurrent calls made for different clients. Specific
49*14675a02SAndroid Build Coastguard Worker // implementations of AggregationProtocol are expected to handle concurrent
50*14675a02SAndroid Build Coastguard Worker // calls. The caller side of the protocol isn't expected to queue messages.
51*14675a02SAndroid Build Coastguard Worker class AggregationProtocol {
52*14675a02SAndroid Build Coastguard Worker  public:
53*14675a02SAndroid Build Coastguard Worker   AggregationProtocol() = default;
54*14675a02SAndroid Build Coastguard Worker   virtual ~AggregationProtocol() = default;
55*14675a02SAndroid Build Coastguard Worker 
56*14675a02SAndroid Build Coastguard Worker   // Instructs the protocol to start with the specified number of clients.
57*14675a02SAndroid Build Coastguard Worker   //
58*14675a02SAndroid Build Coastguard Worker   // Depending on the protocol implementation, the starting number of clients
59*14675a02SAndroid Build Coastguard Worker   // may be zero.  This method is guaranteed to be the first method called on
60*14675a02SAndroid Build Coastguard Worker   // the protocol.
61*14675a02SAndroid Build Coastguard Worker   //
62*14675a02SAndroid Build Coastguard Worker   // AcceptClients callback is expected in response to this method.
63*14675a02SAndroid Build Coastguard Worker   virtual absl::Status Start(int64_t num_clients) = 0;
64*14675a02SAndroid Build Coastguard Worker 
65*14675a02SAndroid Build Coastguard Worker   // Adds an additional batch of clients to the protocol.
66*14675a02SAndroid Build Coastguard Worker   //
67*14675a02SAndroid Build Coastguard Worker   // Depending on the protocol implementation, adding clients may not be allowed
68*14675a02SAndroid Build Coastguard Worker   // and this method might return an error Status.
69*14675a02SAndroid Build Coastguard Worker   //
70*14675a02SAndroid Build Coastguard Worker   // AcceptClients callback is expected in response to this method.
71*14675a02SAndroid Build Coastguard Worker   virtual absl::Status AddClients(int64_t num_clients) = 0;
72*14675a02SAndroid Build Coastguard Worker 
73*14675a02SAndroid Build Coastguard Worker   // Handles a message from a given client.
74*14675a02SAndroid Build Coastguard Worker   //
75*14675a02SAndroid Build Coastguard Worker   // Depending on the specific protocol implementation there may be multiple
76*14675a02SAndroid Build Coastguard Worker   // messages exchanged with each clients.
77*14675a02SAndroid Build Coastguard Worker   //
78*14675a02SAndroid Build Coastguard Worker   // This method should return an error status only if there is an unrecoverable
79*14675a02SAndroid Build Coastguard Worker   // error which must result in aborting the protocol.  Any client specific
80*14675a02SAndroid Build Coastguard Worker   // error, like an invalid message, should result in closing the protocol with
81*14675a02SAndroid Build Coastguard Worker   // that specific client only, but this method should still return OK status.
82*14675a02SAndroid Build Coastguard Worker   virtual absl::Status ReceiveClientMessage(int64_t client_id,
83*14675a02SAndroid Build Coastguard Worker                                             const ClientMessage& message) = 0;
84*14675a02SAndroid Build Coastguard Worker 
85*14675a02SAndroid Build Coastguard Worker   // Notifies the protocol about a communication with a given client being
86*14675a02SAndroid Build Coastguard Worker   // closed, either normally or abnormally.
87*14675a02SAndroid Build Coastguard Worker   //
88*14675a02SAndroid Build Coastguard Worker   // The client_status indicates whether the client connection was closed
89*14675a02SAndroid Build Coastguard Worker   // normally.
90*14675a02SAndroid Build Coastguard Worker   //
91*14675a02SAndroid Build Coastguard Worker   // No further calls or callbacks specific to the given client are expected
92*14675a02SAndroid Build Coastguard Worker   // after this method.
93*14675a02SAndroid Build Coastguard Worker   virtual absl::Status CloseClient(int64_t client_id,
94*14675a02SAndroid Build Coastguard Worker                                    absl::Status client_status) = 0;
95*14675a02SAndroid Build Coastguard Worker 
96*14675a02SAndroid Build Coastguard Worker   // Forces the protocol to complete.
97*14675a02SAndroid Build Coastguard Worker   //
98*14675a02SAndroid Build Coastguard Worker   // Once the protocol has completed successfully, the Complete callback will
99*14675a02SAndroid Build Coastguard Worker   // be invoked and provide the aggregation result.  If the protocol cannot be
100*14675a02SAndroid Build Coastguard Worker   // completed in its current state, this method should return an error status.
101*14675a02SAndroid Build Coastguard Worker   // It is also possible for the completion to fail eventually due to finishing
102*14675a02SAndroid Build Coastguard Worker   // some asynchronous work, in which case the Abort callback will be invoked.
103*14675a02SAndroid Build Coastguard Worker   //
104*14675a02SAndroid Build Coastguard Worker   // No further protocol method calls except Abort and GetStatus are expected
105*14675a02SAndroid Build Coastguard Worker   // after this method.
106*14675a02SAndroid Build Coastguard Worker   virtual absl::Status Complete() = 0;
107*14675a02SAndroid Build Coastguard Worker 
108*14675a02SAndroid Build Coastguard Worker   // Forces the protocol to Abort.
109*14675a02SAndroid Build Coastguard Worker   //
110*14675a02SAndroid Build Coastguard Worker   // No further protocol method calls except GetStatus are expected after this
111*14675a02SAndroid Build Coastguard Worker   // method.
112*14675a02SAndroid Build Coastguard Worker   virtual absl::Status Abort() = 0;
113*14675a02SAndroid Build Coastguard Worker 
114*14675a02SAndroid Build Coastguard Worker   // Called periodically to receive the protocol status.
115*14675a02SAndroid Build Coastguard Worker   //
116*14675a02SAndroid Build Coastguard Worker   // This method can still be called after the protocol has been completed or
117*14675a02SAndroid Build Coastguard Worker   // aborted.
118*14675a02SAndroid Build Coastguard Worker   virtual StatusMessage GetStatus() = 0;
119*14675a02SAndroid Build Coastguard Worker 
120*14675a02SAndroid Build Coastguard Worker   // Callback interface which methods are implemented by the protocol host.
121*14675a02SAndroid Build Coastguard Worker   class Callback {
122*14675a02SAndroid Build Coastguard Worker    public:
123*14675a02SAndroid Build Coastguard Worker     Callback() = default;
124*14675a02SAndroid Build Coastguard Worker     virtual ~Callback() = default;
125*14675a02SAndroid Build Coastguard Worker 
126*14675a02SAndroid Build Coastguard Worker     // Called in response to either StartProtocol or AddClients methods being
127*14675a02SAndroid Build Coastguard Worker     // called and provides protocol parameters to be broadcasted to all newly
128*14675a02SAndroid Build Coastguard Worker     // joined clients.
129*14675a02SAndroid Build Coastguard Worker     virtual void OnAcceptClients(int64_t start_client_id, int64_t num_clients,
130*14675a02SAndroid Build Coastguard Worker                                  const AcceptanceMessage& message) = 0;
131*14675a02SAndroid Build Coastguard Worker 
132*14675a02SAndroid Build Coastguard Worker     // Called by the protocol to deliver a message to a given client.
133*14675a02SAndroid Build Coastguard Worker     //
134*14675a02SAndroid Build Coastguard Worker     // Depending on the specific protocol implementation there may be multiple
135*14675a02SAndroid Build Coastguard Worker     // messages exchanged with each clients, but not all protocols need to
136*14675a02SAndroid Build Coastguard Worker     // send messages to clients.
137*14675a02SAndroid Build Coastguard Worker     virtual void OnSendServerMessage(int64_t client_id,
138*14675a02SAndroid Build Coastguard Worker                                      const ServerMessage& message) = 0;
139*14675a02SAndroid Build Coastguard Worker 
140*14675a02SAndroid Build Coastguard Worker     // Called by the protocol to force communication with a client to be closed,
141*14675a02SAndroid Build Coastguard Worker     // for example due to a client specific error or due to the protocol getting
142*14675a02SAndroid Build Coastguard Worker     // into a state where no further input for that client is needed.
143*14675a02SAndroid Build Coastguard Worker     //
144*14675a02SAndroid Build Coastguard Worker     // No further calls or callbacks specific to the given client are expected
145*14675a02SAndroid Build Coastguard Worker     // after this method.
146*14675a02SAndroid Build Coastguard Worker     virtual void OnCloseClient(int64_t client_id,
147*14675a02SAndroid Build Coastguard Worker                                absl::Status diagnostic_status) = 0;
148*14675a02SAndroid Build Coastguard Worker 
149*14675a02SAndroid Build Coastguard Worker     // Indicates successful completion of the aggregation protocol, contains
150*14675a02SAndroid Build Coastguard Worker     // the result of the aggregation.
151*14675a02SAndroid Build Coastguard Worker     //
152*14675a02SAndroid Build Coastguard Worker     // The format of the result blob is unspecified and can be different for
153*14675a02SAndroid Build Coastguard Worker     // each specific aggregation protocol implementation.  Completing the
154*14675a02SAndroid Build Coastguard Worker     // protocol should close communications with all remaining clients.
155*14675a02SAndroid Build Coastguard Worker     virtual void OnComplete(absl::Cord result) = 0;
156*14675a02SAndroid Build Coastguard Worker 
157*14675a02SAndroid Build Coastguard Worker     // Called by the protocol to indicate that the protocol has been aborted
158*14675a02SAndroid Build Coastguard Worker     // for internal reasons (e.g. the number of remaining clients dropping
159*14675a02SAndroid Build Coastguard Worker     // too low).
160*14675a02SAndroid Build Coastguard Worker     //
161*14675a02SAndroid Build Coastguard Worker     // Aborting the protocol should close communications with all remaining
162*14675a02SAndroid Build Coastguard Worker     // clients.
163*14675a02SAndroid Build Coastguard Worker     virtual void OnAbort(absl::Status diagnostic_status) = 0;
164*14675a02SAndroid Build Coastguard Worker   };
165*14675a02SAndroid Build Coastguard Worker };
166*14675a02SAndroid Build Coastguard Worker 
167*14675a02SAndroid Build Coastguard Worker }  // namespace fcp::aggregation
168*14675a02SAndroid Build Coastguard Worker 
169*14675a02SAndroid Build Coastguard Worker #endif  // FCP_AGGREGATION_PROTOCOL_AGGREGATION_PROTOCOL_H_
170