mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-08 22:31:04 +00:00
Serialize incoming indexes (fixes #344)
This commit is contained in:
parent
70fc8a3064
commit
38ac4e8f79
@ -128,6 +128,7 @@ func NewConnection(nodeID string, reader io.Reader, writer io.Writer, receiver M
|
|||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
go c.indexSerializerLoop()
|
||||||
go c.readerLoop()
|
go c.readerLoop()
|
||||||
go c.writerLoop()
|
go c.writerLoop()
|
||||||
go c.pingerLoop()
|
go c.pingerLoop()
|
||||||
@ -285,6 +286,31 @@ func (c *rawConnection) readerLoop() (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type incomingIndex struct {
|
||||||
|
update bool
|
||||||
|
id string
|
||||||
|
repo string
|
||||||
|
files []FileInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
var incomingIndexes = make(chan incomingIndex, 100) // should be enough for anyone, right?
|
||||||
|
|
||||||
|
func (c *rawConnection) indexSerializerLoop() {
|
||||||
|
// We must avoid blocking the reader loop when processing large indexes.
|
||||||
|
// There is otherwise a potential deadlock where both sides has the model
|
||||||
|
// locked because it's sending a large index update and can't receive the
|
||||||
|
// large index update from the other side. But we must also ensure to
|
||||||
|
// process the indexes in the order they are received, hence the separate
|
||||||
|
// routine and buffered channel.
|
||||||
|
for ii := range incomingIndexes {
|
||||||
|
if ii.update {
|
||||||
|
c.receiver.IndexUpdate(ii.id, ii.repo, ii.files)
|
||||||
|
} else {
|
||||||
|
c.receiver.Index(ii.id, ii.repo, ii.files)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *rawConnection) handleIndex() error {
|
func (c *rawConnection) handleIndex() error {
|
||||||
var im IndexMessage
|
var im IndexMessage
|
||||||
im.decodeXDR(c.xr)
|
im.decodeXDR(c.xr)
|
||||||
@ -299,7 +325,7 @@ func (c *rawConnection) handleIndex() error {
|
|||||||
// update and can't receive the large index update from the
|
// update and can't receive the large index update from the
|
||||||
// other side.
|
// other side.
|
||||||
|
|
||||||
go c.receiver.Index(c.id, im.Repository, im.Files)
|
incomingIndexes <- incomingIndex{false, c.id, im.Repository, im.Files}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -310,7 +336,7 @@ func (c *rawConnection) handleIndexUpdate() error {
|
|||||||
if err := c.xr.Error(); err != nil {
|
if err := c.xr.Error(); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
go c.receiver.IndexUpdate(c.id, im.Repository, im.Files)
|
incomingIndexes <- incomingIndex{true, c.id, im.Repository, im.Files}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user