mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-08 22:31:04 +00:00
Simplify async results
This commit is contained in:
parent
e86296884a
commit
768a7d5052
@ -18,8 +18,6 @@ const (
|
|||||||
messageTypePong
|
messageTypePong
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrClosed = errors.New("Connection closed")
|
|
||||||
|
|
||||||
type FileInfo struct {
|
type FileInfo struct {
|
||||||
Name string
|
Name string
|
||||||
Flags uint32
|
Flags uint32
|
||||||
@ -50,11 +48,18 @@ type Connection struct {
|
|||||||
wLock sync.RWMutex
|
wLock sync.RWMutex
|
||||||
closed bool
|
closed bool
|
||||||
closedLock sync.RWMutex
|
closedLock sync.RWMutex
|
||||||
awaiting map[int]chan interface{}
|
awaiting map[int]chan asyncResult
|
||||||
nextId int
|
nextId int
|
||||||
ID string
|
ID string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ErrClosed = errors.New("Connection closed")
|
||||||
|
|
||||||
|
type asyncResult struct {
|
||||||
|
val []byte
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
func NewConnection(nodeID string, reader io.Reader, writer io.Writer, receiver Model) *Connection {
|
func NewConnection(nodeID string, reader io.Reader, writer io.Writer, receiver Model) *Connection {
|
||||||
flrd := flate.NewReader(reader)
|
flrd := flate.NewReader(reader)
|
||||||
flwr, err := flate.NewWriter(writer, flate.BestSpeed)
|
flwr, err := flate.NewWriter(writer, flate.BestSpeed)
|
||||||
@ -68,7 +73,7 @@ func NewConnection(nodeID string, reader io.Reader, writer io.Writer, receiver M
|
|||||||
mreader: &marshalReader{flrd, 0, nil},
|
mreader: &marshalReader{flrd, 0, nil},
|
||||||
writer: flwr,
|
writer: flwr,
|
||||||
mwriter: &marshalWriter{flwr, 0, nil},
|
mwriter: &marshalWriter{flwr, 0, nil},
|
||||||
awaiting: make(map[int]chan interface{}),
|
awaiting: make(map[int]chan asyncResult),
|
||||||
ID: nodeID,
|
ID: nodeID,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +96,7 @@ func (c *Connection) Index(idx []FileInfo) {
|
|||||||
// Request returns the bytes for the specified block after fetching them from the connected peer.
|
// Request returns the bytes for the specified block after fetching them from the connected peer.
|
||||||
func (c *Connection) Request(name string, offset uint64, size uint32, hash []byte) ([]byte, error) {
|
func (c *Connection) Request(name string, offset uint64, size uint32, hash []byte) ([]byte, error) {
|
||||||
c.wLock.Lock()
|
c.wLock.Lock()
|
||||||
rc := make(chan interface{})
|
rc := make(chan asyncResult)
|
||||||
c.awaiting[c.nextId] = rc
|
c.awaiting[c.nextId] = rc
|
||||||
c.mwriter.writeHeader(header{0, c.nextId, messageTypeRequest})
|
c.mwriter.writeHeader(header{0, c.nextId, messageTypeRequest})
|
||||||
c.mwriter.writeRequest(request{name, offset, size, hash})
|
c.mwriter.writeRequest(request{name, offset, size, hash})
|
||||||
@ -99,30 +104,16 @@ func (c *Connection) Request(name string, offset uint64, size uint32, hash []byt
|
|||||||
c.nextId = (c.nextId + 1) & 0xfff
|
c.nextId = (c.nextId + 1) & 0xfff
|
||||||
c.wLock.Unlock()
|
c.wLock.Unlock()
|
||||||
|
|
||||||
// Reading something that might be nil from a possibly closed channel...
|
res, ok := <-rc
|
||||||
// r0<~
|
if !ok {
|
||||||
|
return nil, ErrClosed
|
||||||
var data []byte
|
|
||||||
i, ok := <-rc
|
|
||||||
if ok {
|
|
||||||
if d, ok := i.([]byte); ok {
|
|
||||||
data = d
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return res.val, res.err
|
||||||
var err error
|
|
||||||
i, ok = <-rc
|
|
||||||
if ok {
|
|
||||||
if e, ok := i.(error); ok {
|
|
||||||
err = e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Connection) Ping() bool {
|
func (c *Connection) Ping() bool {
|
||||||
c.wLock.Lock()
|
c.wLock.Lock()
|
||||||
rc := make(chan interface{})
|
rc := make(chan asyncResult)
|
||||||
c.awaiting[c.nextId] = rc
|
c.awaiting[c.nextId] = rc
|
||||||
c.mwriter.writeHeader(header{0, c.nextId, messageTypePing})
|
c.mwriter.writeHeader(header{0, c.nextId, messageTypePing})
|
||||||
c.flush()
|
c.flush()
|
||||||
@ -150,12 +141,14 @@ func (c *Connection) close() {
|
|||||||
c.closedLock.Lock()
|
c.closedLock.Lock()
|
||||||
c.closed = true
|
c.closed = true
|
||||||
c.closedLock.Unlock()
|
c.closedLock.Unlock()
|
||||||
|
|
||||||
c.wLock.Lock()
|
c.wLock.Lock()
|
||||||
for _, ch := range c.awaiting {
|
for _, ch := range c.awaiting {
|
||||||
close(ch)
|
close(ch)
|
||||||
}
|
}
|
||||||
c.awaiting = nil
|
c.awaiting = nil
|
||||||
c.wLock.Unlock()
|
c.wLock.Unlock()
|
||||||
|
|
||||||
c.receiver.Close(c.ID)
|
c.receiver.Close(c.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,10 +189,12 @@ func (c *Connection) readerLoop() {
|
|||||||
c.wLock.RUnlock()
|
c.wLock.RUnlock()
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
rc <- data
|
rc <- asyncResult{data, c.mreader.err}
|
||||||
rc <- c.mreader.err
|
|
||||||
delete(c.awaiting, hdr.msgID)
|
|
||||||
close(rc)
|
close(rc)
|
||||||
|
|
||||||
|
c.wLock.Lock()
|
||||||
|
delete(c.awaiting, hdr.msgID)
|
||||||
|
c.wLock.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,13 +205,18 @@ func (c *Connection) readerLoop() {
|
|||||||
c.wLock.Unlock()
|
c.wLock.Unlock()
|
||||||
|
|
||||||
case messageTypePong:
|
case messageTypePong:
|
||||||
c.wLock.Lock()
|
c.wLock.RLock()
|
||||||
if rc, ok := c.awaiting[hdr.msgID]; ok {
|
rc, ok := c.awaiting[hdr.msgID]
|
||||||
rc <- true
|
c.wLock.RUnlock()
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
rc <- asyncResult{}
|
||||||
close(rc)
|
close(rc)
|
||||||
|
|
||||||
|
c.wLock.Lock()
|
||||||
delete(c.awaiting, hdr.msgID)
|
delete(c.awaiting, hdr.msgID)
|
||||||
|
c.wLock.Unlock()
|
||||||
}
|
}
|
||||||
c.wLock.Unlock()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user