Fix a race between connect and disconnect
If we get an auth error during connect we did deadlock.
This commit is contained in:
+25
-8
@@ -66,7 +66,7 @@ type TelegramClient struct {
|
|||||||
updatesCloseC chan struct{}
|
updatesCloseC chan struct{}
|
||||||
clientCtx context.Context
|
clientCtx context.Context
|
||||||
clientCancel context.CancelFunc
|
clientCancel context.CancelFunc
|
||||||
clientCloseC <-chan struct{}
|
clientCloseC chan struct{}
|
||||||
initialized chan struct{}
|
initialized chan struct{}
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
|
||||||
@@ -491,25 +491,34 @@ func (t *TelegramClient) Connect(ctx context.Context) {
|
|||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
defer t.mu.Unlock()
|
||||||
|
|
||||||
|
log := zerolog.Ctx(ctx).With().Int64("user_id", t.telegramUserID).Logger()
|
||||||
|
|
||||||
if !t.userLogin.Metadata.(*UserLoginMetadata).Session.HasAuthKey() {
|
if !t.userLogin.Metadata.(*UserLoginMetadata).Session.HasAuthKey() {
|
||||||
zerolog.Ctx(ctx).Warn().Msg("user does not have an auth key, sending bad credentials state")
|
log.Warn().Msg("user does not have an auth key, sending bad credentials state")
|
||||||
t.sendBadCredentialsOrUnknownError(ErrNoAuthKey)
|
t.sendBadCredentialsOrUnknownError(ErrNoAuthKey)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
zerolog.Ctx(ctx).Info().Int64("user_id", t.telegramUserID).Msg("Connecting client")
|
log.Info().Msg("Connecting client")
|
||||||
|
|
||||||
var err error
|
|
||||||
t.clientCtx, t.clientCancel = context.WithCancel(ctx)
|
t.clientCtx, t.clientCancel = context.WithCancel(ctx)
|
||||||
|
t.clientCloseC = make(chan struct{})
|
||||||
t.updatesCloseC = make(chan struct{})
|
t.updatesCloseC = make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
defer close(t.initialized)
|
defer close(t.initialized)
|
||||||
if t.clientCloseC, err = connectTelegramClient(t.clientCtx, t.clientCancel, t.client); err != nil {
|
connectClientCloseC, err := connectTelegramClient(t.clientCtx, t.clientCancel, t.client)
|
||||||
|
if err != nil {
|
||||||
t.sendBadCredentialsOrUnknownError(err)
|
t.sendBadCredentialsOrUnknownError(err)
|
||||||
close(t.updatesCloseC)
|
close(t.updatesCloseC)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// awful hack to prevent assigning clientCloseC from racing Disconnect()
|
||||||
|
go func() {
|
||||||
|
<-connectClientCloseC
|
||||||
|
close(t.clientCloseC)
|
||||||
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer close(t.updatesCloseC)
|
defer close(t.updatesCloseC)
|
||||||
for {
|
for {
|
||||||
@@ -554,19 +563,24 @@ func (t *TelegramClient) Disconnect() {
|
|||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
defer t.mu.Unlock()
|
||||||
|
|
||||||
t.userLogin.Log.Info().Msg("disconnecting client")
|
t.userLogin.Log.Info().Msg("Disconnecting client")
|
||||||
|
|
||||||
if t.clientCancel != nil {
|
if t.clientCancel != nil {
|
||||||
t.clientCancel()
|
t.clientCancel()
|
||||||
t.clientCancel = nil
|
t.clientCancel = nil
|
||||||
}
|
}
|
||||||
if t.clientCloseC != nil {
|
if t.clientCloseC != nil {
|
||||||
|
t.userLogin.Log.Debug().Msg("Waiting for client to finish")
|
||||||
<-t.clientCloseC
|
<-t.clientCloseC
|
||||||
t.clientCloseC = nil
|
t.clientCloseC = nil
|
||||||
}
|
}
|
||||||
if t.updatesCloseC != nil {
|
if t.updatesCloseC != nil {
|
||||||
|
t.userLogin.Log.Debug().Msg("Waiting for updates to finish")
|
||||||
<-t.updatesCloseC
|
<-t.updatesCloseC
|
||||||
t.updatesCloseC = nil
|
t.updatesCloseC = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.userLogin.Log.Info().Msg("Disconnect complete")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) getInputUser(ctx context.Context, id int64) (*tg.InputUser, error) {
|
func (t *TelegramClient) getInputUser(ctx context.Context, id int64) (*tg.InputUser, error) {
|
||||||
@@ -726,7 +740,8 @@ func (t *TelegramClient) LogoutRemote(ctx context.Context) {
|
|||||||
Str("action", "logout_remote").
|
Str("action", "logout_remote").
|
||||||
Int64("user_id", t.telegramUserID).
|
Int64("user_id", t.telegramUserID).
|
||||||
Logger()
|
Logger()
|
||||||
log.Info().Msg("Logging out")
|
|
||||||
|
log.Info().Msg("Logging out and disconnecting")
|
||||||
|
|
||||||
if t.userLogin.Metadata.(*UserLoginMetadata).Session.HasAuthKey() {
|
if t.userLogin.Metadata.(*UserLoginMetadata).Session.HasAuthKey() {
|
||||||
log.Info().Msg("User has an auth key, logging out")
|
log.Info().Msg("User has an auth key, logging out")
|
||||||
@@ -743,6 +758,8 @@ func (t *TelegramClient) LogoutRemote(ctx context.Context) {
|
|||||||
|
|
||||||
t.Disconnect()
|
t.Disconnect()
|
||||||
|
|
||||||
|
log.Info().Msg("Deleting user state")
|
||||||
|
|
||||||
err := t.ScopedStore.DeleteUserState(ctx)
|
err := t.ScopedStore.DeleteUserState(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg("failed to delete user state")
|
log.Err(err).Msg("failed to delete user state")
|
||||||
@@ -758,7 +775,7 @@ func (t *TelegramClient) LogoutRemote(ctx context.Context) {
|
|||||||
log.Err(err).Msg("failed to delete access hashes for user")
|
log.Err(err).Msg("failed to delete access hashes for user")
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info().Msg("successfully logged out and deleted user state")
|
log.Info().Msg("Logged out and deleted user state")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) IsThisUser(ctx context.Context, userID networkid.UserID) bool {
|
func (t *TelegramClient) IsThisUser(ctx context.Context, userID networkid.UserID) bool {
|
||||||
|
|||||||
Reference in New Issue
Block a user