github.com/mailgun/holster/v4@v4.20.0/election/rpc.go (about) 1 package election 2 3 import ( 4 "encoding/json" 5 ) 6 7 type RPC string 8 9 const ( 10 HeartBeatRPC = RPC("heartbeat") 11 VoteRPC = RPC("vote") 12 ResetElectionRPC = RPC("reset-election") 13 ResignRPC = RPC("resign") 14 SetPeersRPC = RPC("set-peers") 15 GetStateRPC = RPC("get-state") 16 UnknownRPC = RPC("unknown") 17 ) 18 19 type RPCPayload struct { 20 RPC RPC `json:"rpc"` 21 Request json.RawMessage `json:"request,omitempty"` 22 Response json.RawMessage `json:"response,omitempty"` 23 Error string `json:"error,omitempty"` 24 } 25 26 type RPCResponse struct { 27 RPC RPC 28 Response interface{} 29 Error string 30 } 31 32 func (r *RPCResponse) UnmarshalJSON(s []byte) error { 33 var in RPCPayload 34 if err := json.Unmarshal(s, &in); err != nil { 35 return err 36 } 37 r.Error = in.Error 38 r.RPC = in.RPC 39 40 switch in.RPC { 41 case HeartBeatRPC: 42 resp := HeartBeatResp{} 43 if err := json.Unmarshal(in.Response, &resp); err != nil { 44 return err 45 } 46 r.Response = resp 47 case VoteRPC: 48 resp := VoteResp{} 49 if err := json.Unmarshal(in.Response, &resp); err != nil { 50 return err 51 } 52 r.Response = resp 53 case ResetElectionRPC: 54 resp := ResetElectionResp{} 55 if err := json.Unmarshal(in.Response, &resp); err != nil { 56 return err 57 } 58 r.Response = resp 59 case ResignRPC: 60 resp := ResignResp{} 61 if err := json.Unmarshal(in.Response, &resp); err != nil { 62 return err 63 } 64 r.Response = resp 65 case SetPeersRPC: 66 resp := SetPeersResp{} 67 if err := json.Unmarshal(in.Response, &resp); err != nil { 68 return err 69 } 70 r.Response = resp 71 case GetStateRPC: 72 resp := GetStateResp{} 73 if err := json.Unmarshal(in.Response, &resp); err != nil { 74 return err 75 } 76 r.Response = resp 77 } 78 return nil 79 } 80 81 func (r RPCResponse) MarshalJSON() ([]byte, error) { 82 out, err := json.Marshal(r.Response) 83 if err != nil { 84 return nil, err 85 } 86 p := RPCPayload{ 87 Error: r.Error, 88 RPC: r.RPC, 89 Response: out, 90 } 91 return json.Marshal(p) 92 } 93 94 type RPCRequest struct { 95 RPC RPC 96 Request interface{} 97 respChan chan RPCResponse 98 } 99 100 func (r RPCRequest) MarshalJSON() ([]byte, error) { 101 out, err := json.Marshal(r.Request) 102 if err != nil { 103 return nil, err 104 } 105 p := RPCPayload{ 106 RPC: r.RPC, 107 Request: out, 108 } 109 return json.Marshal(p) 110 } 111 112 func (r *RPCRequest) UnmarshalJSON(s []byte) error { 113 var in RPCPayload 114 if err := json.Unmarshal(s, &in); err != nil { 115 return err 116 } 117 r.RPC = in.RPC 118 119 switch in.RPC { 120 case HeartBeatRPC: 121 req := HeartBeatReq{} 122 if err := json.Unmarshal(in.Request, &req); err != nil { 123 return err 124 } 125 r.Request = req 126 case VoteRPC: 127 req := VoteReq{} 128 if err := json.Unmarshal(in.Request, &req); err != nil { 129 return err 130 } 131 r.Request = req 132 case ResetElectionRPC: 133 req := ResetElectionReq{} 134 if err := json.Unmarshal(in.Request, &req); err != nil { 135 return err 136 } 137 r.Request = req 138 case ResignRPC: 139 req := ResignReq{} 140 if err := json.Unmarshal(in.Request, &req); err != nil { 141 return err 142 } 143 r.Request = req 144 case SetPeersRPC: 145 req := SetPeersReq{} 146 if err := json.Unmarshal(in.Request, &req); err != nil { 147 return err 148 } 149 r.Request = req 150 case GetStateRPC: 151 req := GetStateReq{} 152 if err := json.Unmarshal(in.Request, &req); err != nil { 153 return err 154 } 155 r.Request = req 156 } 157 return nil 158 } 159 160 // respond is used to respond with a response, error or both 161 func (r *RPCRequest) respond(rpc RPC, resp interface{}, errorMsg string) { 162 r.respChan <- RPCResponse{RPC: rpc, Response: resp, Error: errorMsg} 163 }