Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pkg/connector/backfill.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,12 @@ func (s *SlackClient) FetchMessages(ctx context.Context, params bridgev2.FetchMe
if !ok {
return nil, fmt.Errorf("invalid thread root ID")
}
s.threadFetchLock.Lock()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Bug · Global thread lock stalls every portal's event loop, and waiters ignore ctx

bridgev2 runs thread backfill inside forward backfill, in the portal event loop (createMatrixRoomInLoop with roomCreateLock held, and handleChatResync). With this per-login lock, every portal's loop blocks until all threads queued ahead of it, in any channel, are fetched. The holder keeps the lock through slackgo's retry loop (OptionRetry(5)), which sleeps for each 429's Retry-After (60s default if missing), so one call can hold it for minutes and late channels can't process live messages, edits or reactions. sync.Mutex.Lock also ignores ctx, so a waiter whose context was cancelled (portal deleted, shutdown) keeps waiting and then makes a request anyway. Use a ctx-aware semaphore or a rate limiter (Wait(ctx)) instead.

Found by Indent Review Agent

chunk, err = s.Client.GetConversationRepliesContext(ctx, &slack.GetConversationRepliesParameters{
GetConversationHistoryParameters: *slackParams,
Timestamp: threadTS,
})
s.threadFetchLock.Unlock()
} else {
chunk, err = s.Client.GetConversationHistoryContext(ctx, slackParams)
if chunk != nil {
Expand Down
1 change: 1 addition & 0 deletions pkg/connector/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ type SlackClient struct {
userGroupInfoCacheLock sync.Mutex
lastReadCache map[string]string
lastReadCacheLock sync.Mutex
threadFetchLock sync.Mutex
}

var (
Expand Down
Loading