// Start starts serving the responses for the client. func (c *Client) Start() error { defer func() { if closer, ok := c.rw.(io.Closer); ok { closer.Close() } }() for { var ( size uint32 mt protocol.MessageType err error ) if size, mt, err = protocol.DecodeHdr(c.rw); err != nil { return err } limiter := &io.LimitedReader{R: c.rw, N: int64(size) - protocol.HeaderSize} var r protocol.Message if r, err = protocol.MessageTypeToMessage(mt); err != nil { return err } if err = r.Decode(limiter); err != nil { return err } c.handleResponse(r) } }
func (c *Client) handleResponse(d protocol.Message) error { c.queueLock.Lock() defer c.queueLock.Unlock() t := d.GetTag() if ch, ok := c.queue[t]; ok { ch <- d delete(c.queue, t) return nil } return ErrNoSuchTag }
func (fs *FileServer) flushed(d protocol.Message) bool { fs.tagLock.Lock() defer fs.tagLock.Unlock() t := d.GetTag() if _, ok := fs.tags[t]; ok { delete(fs.tags, t) return false } return true }
func (fs *FileServer) register(d protocol.Message) error { fs.tagLock.Lock() defer fs.tagLock.Unlock() t := d.GetTag() if _, ok := fs.tags[t]; ok { return fmt.Errorf("tag already in use") } fs.tags[t] = true return nil }
func (c *Client) send(d protocol.Message) (protocol.Message, error) { t := d.GetTag() ch, err := c.getTag(t) if err != nil { return nil, err } c.write(t, d) resp := <-ch if resp == nil { return nil, ErrFlushed } if e, ok := resp.(*protocol.ErrorResponse); ok { return nil, errors.New(e.Error) } return resp, nil }