func (t *transport) handlePing(ch *e3x.Channel) { var ( err error pkt *lob.Packet id string alive bool ) defer ch.Close() pkt, err = ch.ReadPacket() if err != nil { // log error // tracef("error: %s", err) return } id, _ = pkt.Header().GetString("vn") rpc := t.lookupRPC(id) if rpc == nil { alive = false } else { alive = true } pkt = &lob.Packet{} pkt.Header().SetBool("alive", alive) err = ch.WritePacket(pkt) if err != nil { // log error // tracef("error: %s", err) return } }
func (t *transport) handleSkipSuccessor(ch *e3x.Channel) { var ( err error stream io.ReadWriteCloser req struct { Target string Self *completeVnode } ) defer ch.Close() stream = newStream(ch) err = json.NewDecoder(stream).Decode(&req) if err != nil { // log // tracef("(SkipSuccessor) error: %s", err) return } rpc := t.lookupRPC(req.Target) if rpc == nil { // log // tracef("(SkipSuccessor) error: %s", "no RPC") return } err = rpc.SkipSuccessor(t.internalVnode(req.Self)) if err != nil { // log // tracef("(SkipSuccessor) error: %s", err) return } }
func (t *transport) handleListVnodes(ch *e3x.Channel) { var ( err error res []*completeVnode ) defer ch.Close() _, err = ch.ReadPacket() if err != nil { // log error // tracef("error: %s", err) return } for _, rpc := range t.localVnodes { res = append(res, t.completeVnode(rpc.vn)) } err = json.NewEncoder(newStream(ch)).Encode(&res) if err != nil { // log error // tracef("error: %s", err) return } // tracef("handle.ListVnodes() => %s", res) }
// Gets a list of the vnodes on the box func (t *transport) ListVnodes(hn string) ([]*chord.Vnode, error) { var ( addr *e3x.Addr ch *e3x.Channel res []*completeVnode err error ) addr = t.lookupAddr(hashname.H(hn)) if addr == nil { return nil, e3x.ErrNoAddress } ch, err = t.e.Open(addr, "chord.list", true) if err != nil { return nil, err } defer ch.Close() // ch.SetReadDeadline(time.Now().Add(30*time.Second)) // ch.SetWriteDeadline(time.Now().Add(30*time.Second)) err = ch.WritePacket(&lob.Packet{}) if err != nil { return nil, err } err = json.NewDecoder(newStream(ch)).Decode(&res) if err != nil { return nil, err } return t.internalVnodes(res), nil }
// Find a successor func (t *transport) FindSuccessors(vn *chord.Vnode, n int, k []byte) ([]*chord.Vnode, error) { var ( addr *e3x.Addr ch *e3x.Channel stream io.ReadWriteCloser res []*completeVnode err error req = struct { Target string N int K []byte }{vn.String(), n, k} ) // tracef("FindSuccessors(target:Vnode(%q))", vn.String()) addr = t.lookupAddr(hashname.H(vn.Host)) if addr == nil { return nil, e3x.ErrNoAddress } ch, err = t.e.Open(addr, "chord.successors.find", true) if err != nil { return nil, err } defer ch.Close() // ch.SetReadDeadline(time.Now().Add(30*time.Second)) // ch.SetWriteDeadline(time.Now().Add(30*time.Second)) stream = newStream(ch) err = json.NewEncoder(stream).Encode(&req) if err != nil { // tracef("(FindSuccessors) error: %s", err) return nil, err } err = json.NewDecoder(stream).Decode(&res) if err != nil { // tracef("(FindSuccessors) error: %s", err) return nil, err } return t.internalVnodes(res), nil }
func (t *transport) handleNotify(ch *e3x.Channel) { var ( err error stream io.ReadWriteCloser req struct { Target string Self *completeVnode } vnodes []*chord.Vnode res []*completeVnode ) defer ch.Close() stream = newStream(ch) err = json.NewDecoder(stream).Decode(&req) if err != nil { // log // tracef("(Notify) error: %s", err) return } rpc := t.lookupRPC(req.Target) if rpc == nil { // log // tracef("(Notify) error: %s", "no RPC") return } vnodes, err = rpc.Notify(t.internalVnode(req.Self)) if err != nil { // log // tracef("(Notify) error: %s", err) return } res = t.completeVnodes(vnodes) err = json.NewEncoder(stream).Encode(&res) if err != nil { // log // tracef("(Notify) error: %s", err) return } // tracef("handle.Notify(target:Vnode(%q), self:Vnode(%q)) => []Vnode(%v)", req.Target, req.Self.Id, res) }
func (t *transport) handleGetPredecessor(ch *e3x.Channel) { var ( err error pkt *lob.Packet id string vnode *chord.Vnode res *completeVnode ) defer ch.Close() pkt, err = ch.ReadPacket() if err != nil { // log error // tracef("error: %s", err) return } id, _ = pkt.Header().GetString("vn") rpc := t.lookupRPC(id) if rpc == nil { // log // tracef("error: %s", "no RPC") return } vnode, err = rpc.GetPredecessor() if err != nil { // log // tracef("error: %s", err) return } res = t.completeVnode(vnode) err = json.NewEncoder(newStream(ch)).Encode(&res) if err != nil { // log // tracef("error: %s", err) return } if res != nil { // tracef("handle.GetPredecessor(Vnode(%q)) => Vnode(%q)", id, res.Id) } }
// Notify our successor of ourselves func (t *transport) Notify(target, self *chord.Vnode) ([]*chord.Vnode, error) { var ( addr *e3x.Addr ch *e3x.Channel stream io.ReadWriteCloser res []*completeVnode err error req = struct { Target string Self *completeVnode }{target.String(), t.completeVnode(self)} ) addr = t.lookupAddr(hashname.H(target.Host)) if addr == nil { return nil, e3x.ErrNoAddress } ch, err = t.e.Open(addr, "chord.notify", true) if err != nil { return nil, err } defer ch.Close() // ch.SetReadDeadline(time.Now().Add(30*time.Second)) // ch.SetWriteDeadline(time.Now().Add(30*time.Second)) stream = newStream(ch) err = json.NewEncoder(stream).Encode(&req) if err != nil { return nil, err } err = json.NewDecoder(stream).Decode(&res) if err != nil { return nil, err } // tracef("Notify(target:Vnode(%q), self:Vnode(%q)) => []Vnode(%v)", target.String(), self.String(), res) return t.internalVnodes(res), nil }
// Request a nodes predecessor func (t *transport) GetPredecessor(vn *chord.Vnode) (*chord.Vnode, error) { var ( addr *e3x.Addr ch *e3x.Channel pkt *lob.Packet res *completeVnode err error ) addr = t.lookupAddr(hashname.H(vn.Host)) if addr == nil { return nil, e3x.ErrNoAddress } ch, err = t.e.Open(addr, "chord.predecessor.get", true) if err != nil { return nil, err } defer ch.Close() // ch.SetReadDeadline(time.Now().Add(30*time.Second)) // ch.SetWriteDeadline(time.Now().Add(30*time.Second)) pkt = &lob.Packet{} pkt.Header().SetString("vn", vn.String()) err = ch.WritePacket(pkt) if err != nil { return nil, err } err = json.NewDecoder(newStream(ch)).Decode(&res) if err != nil { return nil, err } if res != nil { // tracef("GetPredecessor(Vnode(%q)) => Vnode(%q)", vn.String(), res.Id) } return t.internalVnode(res), nil }
func (t *transport) handleFindSuccessors(ch *e3x.Channel) { var ( err error stream io.ReadWriteCloser req struct { Target string N int K []byte } res []*chord.Vnode ) defer ch.Close() stream = newStream(ch) err = json.NewDecoder(stream).Decode(&req) if err != nil { // log // tracef("(FindSuccessors) error: %s", err) return } rpc := t.lookupRPC(req.Target) if rpc != nil { res, err = rpc.FindSuccessors(req.N, req.K) if err != nil { // log // tracef("(FindSuccessors) error: %s", err) return } } err = json.NewEncoder(stream).Encode(t.completeVnodes(res)) if err != nil { // log // tracef("(FindSuccessors) error: %s", err) return } }
func (rt *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { var ( hashname = hashname.H(req.URL.Host) c *e3x.Channel resp *http.Response err error ) x := rt.Endpoint.GetExchange(hashname) if x == nil { return nil, e3x.UnreachableEndpointError(hashname) } c, err = x.Open("thtp", true) if err != nil { c.Close() return nil, err } err = rt.writeRequest(req, c) if err != nil { c.Close() return nil, err } resp, err = rt.readResponse(c) if err != nil { c.Close() return nil, err } resp.Request = req return resp, nil }
func (mod *module) serveTelehash(c *e3x.Channel) { defer c.Close() defer func() { if err := recover(); err != nil { const size = 64 << 10 buf := make([]byte, size) buf = buf[:runtime.Stack(buf, false)] mod.logf("thtp: panic serving %s: %v\n%s", c.RemoteHashname(), err, buf) } }() req, err := mod.readRequest(c) if err != nil { return } rw := newResponseWriter(c) defer rw.Flush() mod.handler.ServeHTTP(rw, req) }
// Ping a Vnode, check for liveness func (t *transport) Ping(vn *chord.Vnode) (bool, error) { var ( addr *e3x.Addr ch *e3x.Channel pkt *lob.Packet alive bool err error ) addr = t.lookupAddr(hashname.H(vn.Host)) if addr == nil { return false, e3x.ErrNoAddress } ch, err = t.e.Open(addr, "chord.ping", true) if err != nil { return false, err } defer ch.Close() // ch.SetReadDeadline(time.Now().Add(30*time.Second)) // ch.SetWriteDeadline(time.Now().Add(30*time.Second)) pkt = &lob.Packet{} pkt.Header().SetString("vn", vn.String()) err = ch.WritePacket(pkt) if err != nil { return false, err } pkt, err = ch.ReadPacket() if err != nil { return false, err } alive, _ = pkt.Header().GetBool("alive") // tracef("Ping(Vnode(%q)) => %v", vn.String(), alive) return alive, nil }
func (d *dht) handle_see(c *e3x.Channel) { defer c.Close() pkt, err := c.ReadPacket() if err != nil { return } key, ok := pkt.Header().GetString("key") if !ok { return } h := d.localLookup(key) pkt = &lob.Packet{} pkt.Header().Set("see", h) pkt.Header().SetBool("end", true) err = c.WritePacket(pkt) if err != nil { return } }
// Instructs a node to skip a given successor. Used to leave. func (t *transport) SkipSuccessor(target, self *chord.Vnode) error { var ( addr *e3x.Addr ch *e3x.Channel stream io.ReadWriteCloser err error req = struct { Target string Self *completeVnode }{target.String(), t.completeVnode(self)} ) addr = t.lookupAddr(hashname.H(target.Host)) if addr == nil { return e3x.ErrNoAddress } ch, err = t.e.Open(addr, "chord.successor.skip", true) if err != nil { return err } defer ch.Close() // ch.SetReadDeadline(time.Now().Add(30*time.Second)) // ch.SetWriteDeadline(time.Now().Add(30*time.Second)) stream = newStream(ch) err = json.NewEncoder(stream).Encode(&req) if err != nil { return err } return nil }