fix: use guild active threads for sync
This commit is contained in:
parent
4dcb36be61
commit
9f983581d9
@ -157,6 +157,10 @@ func (f *fakeDiscordClient) ThreadsActive(context.Context, string) ([]*discordgo
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (f *fakeDiscordClient) GuildThreadsActive(context.Context, string) ([]*discordgo.Channel, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (f *fakeDiscordClient) ThreadsArchived(context.Context, string, bool) ([]*discordgo.Channel, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -102,6 +102,16 @@ func (c *Client) ThreadsActive(ctx context.Context, channelID string) ([]*discor
|
||||
return list.Threads, nil
|
||||
}
|
||||
|
||||
func (c *Client) GuildThreadsActive(ctx context.Context, guildID string) ([]*discordgo.Channel, error) {
|
||||
reqCtx, cancel := c.requestContext(ctx)
|
||||
defer cancel()
|
||||
list, err := c.session.GuildThreadsActive(guildID, discordgo.WithContext(reqCtx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return list.Threads, nil
|
||||
}
|
||||
|
||||
func (c *Client) ThreadsArchived(ctx context.Context, channelID string, private bool) ([]*discordgo.Channel, error) {
|
||||
var out []*discordgo.Channel
|
||||
var before *time.Time
|
||||
|
||||
@ -84,7 +84,7 @@ func (s *Syncer) liveChannelList(ctx context.Context, guildID string) ([]*discor
|
||||
if err := s.appendThreadCatalog(ctx, allChannels, parentIDs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if err := s.appendActiveThreadCatalog(ctx, allChannels, parentIDs); err != nil {
|
||||
} else if err := s.appendActiveThreadCatalog(ctx, allChannels, guildID, parentIDs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mapsToSlice(allChannels), nil
|
||||
@ -113,15 +113,30 @@ func (s *Syncer) appendThreadCatalog(ctx context.Context, allChannels map[string
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Syncer) appendActiveThreadCatalog(ctx context.Context, allChannels map[string]*discordgo.Channel, parents []string) error {
|
||||
func (s *Syncer) appendActiveThreadCatalog(ctx context.Context, allChannels map[string]*discordgo.Channel, guildID string, parents []string) error {
|
||||
allowedParents := make(map[string]struct{}, len(parents))
|
||||
for _, parentID := range uniqueIDs(parents) {
|
||||
channel := allChannels[parentID]
|
||||
if !isThreadParent(channel) {
|
||||
continue
|
||||
}
|
||||
if err := s.appendActiveThreads(ctx, allChannels, channel.ID); err != nil {
|
||||
return err
|
||||
allowedParents[parentID] = struct{}{}
|
||||
}
|
||||
if len(allowedParents) == 0 {
|
||||
return nil
|
||||
}
|
||||
active, err := s.client.GuildThreadsActive(ctx, guildID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, thread := range active {
|
||||
if thread == nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := allowedParents[thread.ParentID]; !ok {
|
||||
continue
|
||||
}
|
||||
allChannels[thread.ID] = thread
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -244,6 +244,63 @@ func TestFullSyncReusesStoredThreadParents(t *testing.T) {
|
||||
require.Equal(t, 1, client.messageCalls["t1"])
|
||||
}
|
||||
|
||||
func TestFullSyncUsesGuildActiveThreadsForStoredParents(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx := context.Background()
|
||||
s, err := store.Open(ctx, filepath.Join(t.TempDir(), "discrawl.db"))
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = s.Close() }()
|
||||
|
||||
require.NoError(t, s.UpsertGuild(ctx, store.GuildRecord{ID: "g1", Name: "Guild", RawJSON: `{}`}))
|
||||
require.NoError(t, s.UpsertChannel(ctx, store.ChannelRecord{
|
||||
ID: "c1",
|
||||
GuildID: "g1",
|
||||
Kind: "text",
|
||||
Name: "general",
|
||||
RawJSON: `{"id":"c1"}`,
|
||||
}))
|
||||
require.NoError(t, s.UpsertChannel(ctx, store.ChannelRecord{
|
||||
ID: "t1",
|
||||
GuildID: "g1",
|
||||
ParentID: "c1",
|
||||
Kind: "thread_public",
|
||||
Name: "bug-report",
|
||||
RawJSON: `{"id":"t1"}`,
|
||||
}))
|
||||
require.NoError(t, s.SetSyncState(ctx, channelHistoryCompleteScope("c1"), "1"))
|
||||
require.NoError(t, s.SetSyncState(ctx, channelHistoryCompleteScope("t1"), "1"))
|
||||
require.NoError(t, s.SetSyncState(ctx, channelLatestScope("t1"), "10"))
|
||||
|
||||
client := &fakeClient{
|
||||
guilds: []*discordgo.UserGuild{{ID: "g1", Name: "Guild"}},
|
||||
guildByID: map[string]*discordgo.Guild{
|
||||
"g1": {ID: "g1", Name: "Guild"},
|
||||
},
|
||||
channels: map[string][]*discordgo.Channel{
|
||||
"g1": {
|
||||
{ID: "c1", GuildID: "g1", Name: "general", Type: discordgo.ChannelTypeGuildText},
|
||||
},
|
||||
},
|
||||
guildThreads: map[string][]*discordgo.Channel{
|
||||
"g1": {{
|
||||
ID: "t1",
|
||||
GuildID: "g1",
|
||||
ParentID: "c1",
|
||||
Name: "bug-report",
|
||||
Type: discordgo.ChannelTypeGuildPublicThread,
|
||||
LastMessageID: "10",
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
svc := New(client, s, nil)
|
||||
_, err = svc.Sync(ctx, SyncOptions{Full: true, GuildIDs: []string{"g1"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, client.guildThreadCalls)
|
||||
require.Zero(t, client.threadCalls)
|
||||
}
|
||||
|
||||
func TestFullSyncFallsBackToBroadThreadDiscoveryWithoutStoredThreads(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ type Client interface {
|
||||
Guild(context.Context, string) (*discordgo.Guild, error)
|
||||
GuildChannels(context.Context, string) ([]*discordgo.Channel, error)
|
||||
ThreadsActive(context.Context, string) ([]*discordgo.Channel, error)
|
||||
GuildThreadsActive(context.Context, string) ([]*discordgo.Channel, error)
|
||||
ThreadsArchived(context.Context, string, bool) ([]*discordgo.Channel, error)
|
||||
GuildMembers(context.Context, string) ([]*discordgo.Member, error)
|
||||
ChannelMessages(context.Context, string, int, string, string) ([]*discordgo.Message, error)
|
||||
|
||||
@ -16,25 +16,27 @@ import (
|
||||
)
|
||||
|
||||
type fakeClient struct {
|
||||
guilds []*discordgo.UserGuild
|
||||
guildByID map[string]*discordgo.Guild
|
||||
channels map[string][]*discordgo.Channel
|
||||
activeThreads map[string][]*discordgo.Channel
|
||||
publicArchived map[string][]*discordgo.Channel
|
||||
privateArchive map[string][]*discordgo.Channel
|
||||
members map[string][]*discordgo.Member
|
||||
messages map[string][]*discordgo.Message
|
||||
messageErrors map[string]error
|
||||
messageCalls map[string]int
|
||||
beforeErrors map[string]map[string]error
|
||||
tailCalls int
|
||||
messageDelay time.Duration
|
||||
guildChanCalls int
|
||||
threadCalls int
|
||||
memberCalls int
|
||||
mu sync.Mutex
|
||||
inFlight int
|
||||
maxInFlight int
|
||||
guilds []*discordgo.UserGuild
|
||||
guildByID map[string]*discordgo.Guild
|
||||
channels map[string][]*discordgo.Channel
|
||||
activeThreads map[string][]*discordgo.Channel
|
||||
guildThreads map[string][]*discordgo.Channel
|
||||
publicArchived map[string][]*discordgo.Channel
|
||||
privateArchive map[string][]*discordgo.Channel
|
||||
members map[string][]*discordgo.Member
|
||||
messages map[string][]*discordgo.Message
|
||||
messageErrors map[string]error
|
||||
messageCalls map[string]int
|
||||
beforeErrors map[string]map[string]error
|
||||
tailCalls int
|
||||
messageDelay time.Duration
|
||||
guildChanCalls int
|
||||
threadCalls int
|
||||
guildThreadCalls int
|
||||
memberCalls int
|
||||
mu sync.Mutex
|
||||
inFlight int
|
||||
maxInFlight int
|
||||
}
|
||||
|
||||
func (f *fakeClient) Self(context.Context) (*discordgo.User, error) {
|
||||
@ -59,6 +61,18 @@ func (f *fakeClient) ThreadsActive(_ context.Context, channelID string) ([]*disc
|
||||
return f.activeThreads[channelID], nil
|
||||
}
|
||||
|
||||
func (f *fakeClient) GuildThreadsActive(_ context.Context, guildID string) ([]*discordgo.Channel, error) {
|
||||
f.guildThreadCalls++
|
||||
if f.guildThreads != nil {
|
||||
return f.guildThreads[guildID], nil
|
||||
}
|
||||
var out []*discordgo.Channel
|
||||
for _, threads := range f.activeThreads {
|
||||
out = append(out, threads...)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (f *fakeClient) ThreadsArchived(_ context.Context, channelID string, private bool) ([]*discordgo.Channel, error) {
|
||||
f.threadCalls++
|
||||
if private {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user