Refactor readerLoop to switch on message type directly

This commit is contained in:
Jakob Borg 2015-01-11 13:24:56 +01:00
parent d9ed8e125e
commit 7a0a702ec0
1 changed files with 34 additions and 24 deletions

View File

@ -71,6 +71,10 @@ var (
ErrClosed = errors.New("connection closed") ErrClosed = errors.New("connection closed")
) )
// Specific variants of empty messages...
type pingMessage struct{ EmptyMessage }
type pongMessage struct{ EmptyMessage }
type Model interface { type Model interface {
// An index was received from the peer device // An index was received from the peer device
Index(deviceID DeviceID, folder string, files []FileInfo) Index(deviceID DeviceID, folder string, files []FileInfo)
@ -289,48 +293,51 @@ func (c *rawConnection) readerLoop() (err error) {
return err return err
} }
switch hdr.msgType { switch msg := msg.(type) {
case messageTypeIndex: case IndexMessage:
if c.state < stateCCRcvd { switch hdr.msgType {
return fmt.Errorf("protocol error: index message in state %d", c.state) case messageTypeIndex:
} if c.state < stateCCRcvd {
c.handleIndex(msg.(IndexMessage)) return fmt.Errorf("protocol error: index message in state %d", c.state)
c.state = stateIdxRcvd }
c.handleIndex(msg)
c.state = stateIdxRcvd
case messageTypeIndexUpdate: case messageTypeIndexUpdate:
if c.state < stateIdxRcvd { if c.state < stateIdxRcvd {
return fmt.Errorf("protocol error: index update message in state %d", c.state) return fmt.Errorf("protocol error: index update message in state %d", c.state)
}
c.handleIndexUpdate(msg)
} }
c.handleIndexUpdate(msg.(IndexMessage))
case messageTypeRequest: case RequestMessage:
if c.state < stateIdxRcvd { if c.state < stateIdxRcvd {
return fmt.Errorf("protocol error: request message in state %d", c.state) return fmt.Errorf("protocol error: request message in state %d", c.state)
} }
// Requests are handled asynchronously // Requests are handled asynchronously
go c.handleRequest(hdr.msgID, msg.(RequestMessage)) go c.handleRequest(hdr.msgID, msg)
case messageTypeResponse: case ResponseMessage:
if c.state < stateIdxRcvd { if c.state < stateIdxRcvd {
return fmt.Errorf("protocol error: response message in state %d", c.state) return fmt.Errorf("protocol error: response message in state %d", c.state)
} }
c.handleResponse(hdr.msgID, msg.(ResponseMessage)) c.handleResponse(hdr.msgID, msg)
case messageTypePing: case pingMessage:
c.send(hdr.msgID, messageTypePong, EmptyMessage{}) c.send(hdr.msgID, messageTypePong, pongMessage{})
case messageTypePong: case pongMessage:
c.handlePong(hdr.msgID) c.handlePong(hdr.msgID)
case messageTypeClusterConfig: case ClusterConfigMessage:
if c.state != stateInitial { if c.state != stateInitial {
return fmt.Errorf("protocol error: cluster config message in state %d", c.state) return fmt.Errorf("protocol error: cluster config message in state %d", c.state)
} }
go c.receiver.ClusterConfig(c.id, msg.(ClusterConfigMessage)) go c.receiver.ClusterConfig(c.id, msg)
c.state = stateCCRcvd c.state = stateCCRcvd
case messageTypeClose: case CloseMessage:
return errors.New(msg.(CloseMessage).Reason) return errors.New(msg.Reason)
default: default:
return fmt.Errorf("protocol error: %s: unknown message type %#x", c.id, hdr.msgType) return fmt.Errorf("protocol error: %s: unknown message type %#x", c.id, hdr.msgType)
@ -428,8 +435,11 @@ func (c *rawConnection) readMessage() (hdr header, msg encodable, err error) {
} }
msg = resp msg = resp
case messageTypePing, messageTypePong: case messageTypePing:
msg = EmptyMessage{} msg = pingMessage{}
case messageTypePong:
msg = pongMessage{}
case messageTypeClusterConfig: case messageTypeClusterConfig:
var cc ClusterConfigMessage var cc ClusterConfigMessage