func (r *nodeRPC) handleConn(conn net.Conn) { defer conn.Close() var req rpc.Request if err := api.Decode(&req, conn); err != nil { logrus.Errorf("error handling K/V RPC connection: %v", err) return } logrus.Debugf("Got: %s(%s)", req.Method, req.Args) var h rpcHandlerFunc switch req.Method { case addNode: h = r.addNode case removeNode: h = r.removeNode } if !r.r.IsLeader() { r.ProxyRequest(r.r.GetLeader(), &req, conn) return } var res rpc.Response if err := h(&req); err != nil { res.Err = err.Error() } api.Encode(&res, conn) }
// RPC is a helper function for performing RPC requests between nodes func (l *StreamLayer) RPC(addr string, msg *Request) (*Response, error) { conn, err := l.DialWithRetry(addr, time.Duration(retryTimeout)*time.Second, true) if err != nil { return nil, err } if err := api.Encode(msg, conn); err != nil { return nil, err } var res Response if err := api.Decode(&res, conn); err != nil { return nil, err } return &res, nil }
func (s *storeFSM) Apply(l *raft.Log) interface{} { var ax api.Request if err := api.Decode(&ax, bytes.NewBuffer(l.Data)); err != nil { return err } switch ax.Action { case api.Delete: delete(s.data.KV, ax.Key) delete(s.data.TTLs, ax.Key) s.closeWatches(ax.Key) case api.Put: kv := &libkvstore.KVPair{Key: ax.Key, Value: ax.Value, LastIndex: l.Index} s.data.KV[ax.Key] = kv if ax.TTL != 0 { s.ttlLock.Lock() s.data.TTLs[ax.Key] = &ttl{CreateTime: time.Now(), TTL: ax.TTL, CreateIndex: l.Index} s.ttlLock.Unlock() } s.checkWatches(ax.Key, kv) s.checkTreeWatches(ax.Key, []*libkvstore.KVPair{kv}) case api.DeleteTree: for k := range s.data.KV { if !strings.HasPrefix(k, ax.Key) { continue } delete(s.data.KV, k) delete(s.data.TTLs, k) s.closeWatches(ax.Key) } case reapKeys: s.mu.Lock() for _, k := range ax.Args { delete(s.data.KV, k) delete(s.data.TTLs, k) } s.mu.Unlock() default: return fmt.Errorf("unknown api.Request") } return nil }
func (c *Client) do(req *api.Request) (*api.Response, error) { conn, err := c.dial() if err != nil { return nil, err } defer conn.Close() if err := api.Encode(&req, conn); err != nil { return nil, err } var res api.Response if err := api.Decode(&res, conn); err != nil { return nil, fmt.Errorf("error decoding response: %v", err) } if res.Err != nil { return nil, getErr(res.Err) } return &res, nil }
func (r *clientRPC) handleConn(conn net.Conn) { defer conn.Close() var req api.Request if err := api.Decode(&req, conn); err != nil { logrus.Errorf("error handling K/V RPC connection: %v", err) return } logrus.Debugf("Got: %s(%s)", req.Action, req.Key) var h clientRPCHandlerFn switch req.Action { case api.Get: h = r.Get case api.Put: h = r.Put case api.Watch: h = r.Watch case api.WatchTree: h = r.WatchTree case api.List: h = r.List case api.Delete: h = r.Delete case api.DeleteTree: h = r.DeleteTree case api.AtomicPut: h = r.AtomicPut case api.AtomicDelete: h = r.AtomicDelete case api.Exists: h = r.Exists default: logrus.Errorf("can't handle action: %s", req.Action) return } h(conn, &clientRequest{&req, conn}) }
func (s *storeFSM) Restore(r io.ReadCloser) error { defer r.Close() s.data = newDB() return api.Decode(s.data, r) }