Error handling, testing
This commit is contained in:
@@ -49,7 +49,6 @@ type Connection struct {
|
||||
mwriter *marshalWriter
|
||||
wLock sync.RWMutex
|
||||
closed bool
|
||||
closedLock sync.RWMutex
|
||||
awaiting map[int]chan asyncResult
|
||||
nextId int
|
||||
lastReceive time.Time
|
||||
@@ -74,13 +73,14 @@ func NewConnection(nodeID string, reader io.Reader, writer io.Writer, receiver M
|
||||
}
|
||||
|
||||
c := Connection{
|
||||
receiver: receiver,
|
||||
reader: flrd,
|
||||
mreader: &marshalReader{flrd, 0, nil},
|
||||
writer: flwr,
|
||||
mwriter: &marshalWriter{flwr, 0, nil},
|
||||
awaiting: make(map[int]chan asyncResult),
|
||||
ID: nodeID,
|
||||
receiver: receiver,
|
||||
reader: flrd,
|
||||
mreader: &marshalReader{flrd, 0, nil},
|
||||
writer: flwr,
|
||||
mwriter: &marshalWriter{flwr, 0, nil},
|
||||
awaiting: make(map[int]chan asyncResult),
|
||||
lastReceive: time.Now(),
|
||||
ID: nodeID,
|
||||
}
|
||||
|
||||
go c.readerLoop()
|
||||
@@ -92,12 +92,15 @@ func NewConnection(nodeID string, reader io.Reader, writer io.Writer, receiver M
|
||||
// Index writes the list of file information to the connected peer node
|
||||
func (c *Connection) Index(idx []FileInfo) {
|
||||
c.wLock.Lock()
|
||||
defer c.wLock.Unlock()
|
||||
|
||||
c.mwriter.writeHeader(header{0, c.nextId, messageTypeIndex})
|
||||
c.nextId = (c.nextId + 1) & 0xfff
|
||||
c.mwriter.writeIndex(idx)
|
||||
c.flush()
|
||||
err := c.flush()
|
||||
c.nextId = (c.nextId + 1) & 0xfff
|
||||
c.wLock.Unlock()
|
||||
if err != nil || c.mwriter.err != nil {
|
||||
c.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Request returns the bytes for the specified block after fetching them from the connected peer.
|
||||
@@ -107,7 +110,17 @@ func (c *Connection) Request(name string, offset uint64, size uint32, hash []byt
|
||||
c.awaiting[c.nextId] = rc
|
||||
c.mwriter.writeHeader(header{0, c.nextId, messageTypeRequest})
|
||||
c.mwriter.writeRequest(request{name, offset, size, hash})
|
||||
c.flush()
|
||||
if c.mwriter.err != nil {
|
||||
c.wLock.Unlock()
|
||||
c.close()
|
||||
return nil, c.mwriter.err
|
||||
}
|
||||
err := c.flush()
|
||||
if err != nil {
|
||||
c.wLock.Unlock()
|
||||
c.close()
|
||||
return nil, err
|
||||
}
|
||||
c.nextId = (c.nextId + 1) & 0xfff
|
||||
c.wLock.Unlock()
|
||||
|
||||
@@ -123,7 +136,12 @@ func (c *Connection) Ping() bool {
|
||||
rc := make(chan asyncResult)
|
||||
c.awaiting[c.nextId] = rc
|
||||
c.mwriter.writeHeader(header{0, c.nextId, messageTypePing})
|
||||
c.flush()
|
||||
err := c.flush()
|
||||
if err != nil || c.mwriter.err != nil {
|
||||
c.wLock.Unlock()
|
||||
c.close()
|
||||
return false
|
||||
}
|
||||
c.nextId = (c.nextId + 1) & 0xfff
|
||||
c.wLock.Unlock()
|
||||
|
||||
@@ -138,18 +156,20 @@ type flusher interface {
|
||||
Flush() error
|
||||
}
|
||||
|
||||
func (c *Connection) flush() {
|
||||
func (c *Connection) flush() error {
|
||||
if f, ok := c.writer.(flusher); ok {
|
||||
f.Flush()
|
||||
return f.Flush()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Connection) close() {
|
||||
c.closedLock.Lock()
|
||||
c.closed = true
|
||||
c.closedLock.Unlock()
|
||||
|
||||
c.wLock.Lock()
|
||||
if c.closed {
|
||||
c.wLock.Unlock()
|
||||
return
|
||||
}
|
||||
c.closed = true
|
||||
for _, ch := range c.awaiting {
|
||||
close(ch)
|
||||
}
|
||||
@@ -160,8 +180,8 @@ func (c *Connection) close() {
|
||||
}
|
||||
|
||||
func (c *Connection) isClosed() bool {
|
||||
c.closedLock.RLock()
|
||||
defer c.closedLock.RUnlock()
|
||||
c.wLock.RLock()
|
||||
defer c.wLock.RUnlock()
|
||||
return c.closed
|
||||
}
|
||||
|
||||
@@ -215,9 +235,9 @@ func (c *Connection) readerLoop() {
|
||||
case messageTypePing:
|
||||
c.wLock.Lock()
|
||||
c.mwriter.writeUint32(encodeHeader(header{0, hdr.msgID, messageTypePong}))
|
||||
c.flush()
|
||||
err := c.flush()
|
||||
c.wLock.Unlock()
|
||||
if c.mwriter.err != nil {
|
||||
if err != nil || c.mwriter.err != nil {
|
||||
c.close()
|
||||
}
|
||||
|
||||
@@ -248,9 +268,12 @@ func (c *Connection) processRequest(msgID int) {
|
||||
c.wLock.Lock()
|
||||
c.mwriter.writeUint32(encodeHeader(header{0, msgID, messageTypeResponse}))
|
||||
c.mwriter.writeResponse(data)
|
||||
buffers.Put(data)
|
||||
c.flush()
|
||||
err := c.flush()
|
||||
c.wLock.Unlock()
|
||||
buffers.Put(data)
|
||||
if c.mwriter.err != nil || err != nil {
|
||||
c.close()
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user