lib/protocol: Don't send any messages before cluster config (#5646)

* lib/model: Send cluster config before releasing pmut

* reshuffle

* add model.connReady to track cluster-config status

* Corrected comments/strings

* do it in protocol
This commit is contained in:
Simon Frei 2019-04-23 21:47:11 +02:00 committed by Audrius Butkevicius
parent 110806842c
commit 04b927104f
1 changed files with 39 additions and 19 deletions

View File

@ -182,11 +182,12 @@ type rawConnection struct {
nextID int32
nextIDMut sync.Mutex
outbox chan asyncMessage
closed chan struct{}
closeOnce sync.Once
sendCloseOnce sync.Once
compression Compression
sentClusterConfig chan struct{}
outbox chan asyncMessage
closed chan struct{}
closeOnce sync.Once
sendCloseOnce sync.Once
compression Compression
}
type asyncResult struct {
@ -220,15 +221,16 @@ func NewConnection(deviceID DeviceID, reader io.Reader, writer io.Writer, receiv
cw := &countingWriter{Writer: writer}
c := rawConnection{
id: deviceID,
name: name,
receiver: nativeModel{receiver},
cr: cr,
cw: cw,
awaiting: make(map[int32]chan asyncResult),
outbox: make(chan asyncMessage),
closed: make(chan struct{}),
compression: compress,
id: deviceID,
name: name,
receiver: nativeModel{receiver},
cr: cr,
cw: cw,
awaiting: make(map[int32]chan asyncResult),
sentClusterConfig: make(chan struct{}),
outbox: make(chan asyncMessage),
closed: make(chan struct{}),
compression: compress,
}
return wireFormatConnection{&c}
@ -322,9 +324,20 @@ func (c *rawConnection) Request(folder string, name string, offset int64, size i
return res.val, res.err
}
// ClusterConfig send the cluster configuration message to the peer and returns any error
// ClusterConfig sends the cluster configuration message to the peer.
// It must be called just once (as per BEP).
func (c *rawConnection) ClusterConfig(config ClusterConfig) {
c.send(&config, nil)
select {
case <-c.sentClusterConfig:
return
case <-c.closed:
return
default:
}
if err := c.writeMessage(asyncMessage{&config, nil}); err != nil {
c.internalClose(err)
}
close(c.sentClusterConfig)
}
func (c *rawConnection) Closed() bool {
@ -628,13 +641,20 @@ func (c *rawConnection) handleResponse(resp Response) {
}
func (c *rawConnection) send(msg message, done chan struct{}) bool {
defer func() {
if done != nil {
close(done)
}
}()
select {
case <-c.sentClusterConfig:
case <-c.closed:
return false
}
select {
case c.outbox <- asyncMessage{msg, done}:
return true
case <-c.closed:
if done != nil {
close(done)
}
return false
}
}