Fix issue #160
This commit is contained in:
parent
ef6de6000a
commit
0a4acd12c3
|
@ -42,12 +42,12 @@ func (scs *SyncConnState) setState(cs ConnState) {
|
||||||
// This is a the list of events happening on the connection that the
|
// This is a the list of events happening on the connection that the
|
||||||
// client can be notified about.
|
// client can be notified about.
|
||||||
const (
|
const (
|
||||||
InitialPresence = "<presence/>"
|
|
||||||
StateDisconnected ConnState = iota
|
StateDisconnected ConnState = iota
|
||||||
StateResuming
|
StateResuming
|
||||||
StateSessionEstablished
|
StateSessionEstablished
|
||||||
StateStreamError
|
StateStreamError
|
||||||
StatePermanentError
|
StatePermanentError
|
||||||
|
InitialPresence = "<presence/>"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Event is a structure use to convey event changes related to client state. This
|
// Event is a structure use to convey event changes related to client state. This
|
||||||
|
@ -285,7 +285,7 @@ func (c *Client) Resume() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Execute post reconnect hook. This can be different from the first connection hook, and not trigger roster retrival
|
// Execute post reconnect hook. This can be different from the first connection hook, and not trigger roster retrieval
|
||||||
// for example.
|
// for example.
|
||||||
if c.PostResumeHook != nil {
|
if c.PostResumeHook != nil {
|
||||||
err = c.PostResumeHook()
|
err = c.PostResumeHook()
|
||||||
|
|
|
@ -80,13 +80,13 @@ func (sm *StreamManager) Run() error {
|
||||||
sm.Metrics.setLoginTime()
|
sm.Metrics.setLoginTime()
|
||||||
case StateDisconnected:
|
case StateDisconnected:
|
||||||
// Reconnect on disconnection
|
// Reconnect on disconnection
|
||||||
return sm.resume(e.SMState)
|
return sm.resume()
|
||||||
case StateStreamError:
|
case StateStreamError:
|
||||||
sm.client.Disconnect()
|
sm.client.Disconnect()
|
||||||
// Only try reconnecting if we have not been kicked by another session to avoid connection loop.
|
// Only try reconnecting if we have not been kicked by another session to avoid connection loop.
|
||||||
// TODO: Make this conflict exception a permanent error
|
// TODO: Make this conflict exception a permanent error
|
||||||
if e.StreamError != "conflict" {
|
if e.StreamError != "conflict" {
|
||||||
return sm.connect()
|
return sm.resume()
|
||||||
}
|
}
|
||||||
case StatePermanentError:
|
case StatePermanentError:
|
||||||
// Do not attempt to reconnect
|
// Do not attempt to reconnect
|
||||||
|
@ -113,19 +113,32 @@ func (sm *StreamManager) Stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StreamManager) connect() error {
|
func (sm *StreamManager) connect() error {
|
||||||
var state SMState
|
if sm.client != nil {
|
||||||
return sm.resume(state)
|
if c, ok := sm.client.(*Client); ok {
|
||||||
|
if c.CurrentState.getState() == StateDisconnected {
|
||||||
|
sm.Metrics = initMetrics()
|
||||||
|
err := c.Connect()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if sm.PostConnect != nil {
|
||||||
|
sm.PostConnect(sm.client)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors.New("client is not disconnected")
|
||||||
}
|
}
|
||||||
|
|
||||||
// resume manages the reconnection loop and apply the define backoff to avoid overloading the server.
|
// resume manages the reconnection loop and apply the define backoff to avoid overloading the server.
|
||||||
func (sm *StreamManager) resume(state SMState) error {
|
func (sm *StreamManager) resume() error {
|
||||||
var backoff backoff // TODO: Group backoff calculation features with connection manager?
|
var backoff backoff // TODO: Group backoff calculation features with connection manager?
|
||||||
|
|
||||||
for {
|
for {
|
||||||
var err error
|
var err error
|
||||||
// TODO: Make it possible to define logger to log disconnect and reconnection attempts
|
// TODO: Make it possible to define logger to log disconnect and reconnection attempts
|
||||||
sm.Metrics = initMetrics()
|
sm.Metrics = initMetrics()
|
||||||
|
|
||||||
if err = sm.client.Resume(); err != nil {
|
if err = sm.client.Resume(); err != nil {
|
||||||
var actualErr ConnError
|
var actualErr ConnError
|
||||||
if xerrors.As(err, &actualErr) {
|
if xerrors.As(err, &actualErr) {
|
||||||
|
|
Loading…
Reference in a new issue