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  }