So many changes. Broken.
[invirt/third/libt4.git] / include / rsm_client.h
1 #ifndef rsm_client_h
2 #define rsm_client_h
3
4 #include "include/types.h"
5 #include "include/rsm_protocol.h"
6
7 //
8 // rsm client interface.
9 //
10 // The client stubs package up an rpc, and then call the invoke procedure
11 // on the replicated state machine passing the RPC as an argument.  This way
12 // the replicated state machine isn't service specific; any server can use it.
13 //
14
15 class rsm_client {
16     protected:
17         string primary;
18         std::vector<string> known_mems;
19         std::mutex rsm_client_mutex;
20         bool init_members(lock & rsm_client_mutex_lock);
21         rsm_protocol::status invoke(rpc_protocol::proc_id_t proc, string & rep, const string & req);
22         template<class R> int call_marshalled(rpc_protocol::proc_t & proc, R & r, const marshall & req);
23     public:
24         rsm_client(string dst);
25
26         template<class P, class R, class ...Args>
27         inline int call(rpc_protocol::proc_checked_t<P> proc, R & r, const Args & ...a1) {
28             static_assert(is_valid_call<P, R, Args...>::value, "RSM method invoked with incorrect argument types");
29             return call_marshalled(proc, r, marshall(a1...));
30         }
31 };
32
33 template<class R>
34 int rsm_client::call_marshalled(rpc_protocol::proc_t & proc, R & r, const marshall & req) {
35     string rep, res;
36     int intret = invoke(proc.id, rep, req);
37     VERIFY( intret == rsm_client_protocol::OK );
38     auto u = unmarshall(rep, intret);
39     if (intret < 0) return intret;
40     if ((u >> res).okdone() && unmarshall(res, r).okdone())
41         return intret;
42     LOG << "failed to unmarshall reply \"" << hex_string(rep) << "\" for proceduce "
43         << proc.name << " (0x" << std::hex << proc.id << ").";
44     return rpc_protocol::unmarshall_reply_failure;
45 }
46
47 #endif