From 892aa7c66165eee8110adb0946eaa6cf4a5d77a0 Mon Sep 17 00:00:00 2001 From: Haw Loeung Date: Sat, 27 Jun 2026 18:59:06 +1000 Subject: [PATCH 1/2] Refactor pagination slightly reducing Mattermost API calls --- channels.go | 48 ++++++++++++++++-------------------------------- matterclient.go | 24 +++++++++++++----------- users.go | 34 +++++++++++----------------------- 3 files changed, 40 insertions(+), 66 deletions(-) diff --git a/channels.go b/channels.go index 7439961..96f9f8d 100644 --- a/channels.go +++ b/channels.go @@ -226,52 +226,36 @@ func (m *Client) UpdateChannelsTeam(teamID string) error { } } - for idx, t := range m.OtherTeams { - if t.ID == teamID { - m.Lock() - m.OtherTeams[idx].Channels = mmchannels - m.Unlock() - } - } - idx := 0 - max := 200 + const batchSize = 200 var moreChannels []*model.Channel for { - mmchannels, resp, err = m.Client.GetPublicChannelsForTeam(ctx, teamID, idx, max, "") - if err == nil { - break - } - - if err := m.HandleRatelimit("GetPublicChannelsForTeam", resp); err != nil { - return err + channels, resp, err := m.Client.GetPublicChannelsForTeam(ctx, teamID, idx, batchSize, "") + if err != nil { + if rlErr := m.HandleRatelimit("GetPublicChannelsForTeam", resp); rlErr != nil { + return rlErr + } + continue } - } - for len(mmchannels) > 0 { - moreChannels = append(moreChannels, mmchannels...) - - for { - mmchannels, resp, err = m.Client.GetPublicChannelsForTeam(ctx, teamID, idx, max, "") - if err == nil { - idx++ - - break - } + moreChannels = append(moreChannels, channels...) - if err := m.HandleRatelimit("GetPublicChannelsForTeam", resp); err != nil { - return err - } + if len(channels) < batchSize { + break } + idx++ } + m.Lock() + defer m.Unlock() + for idx, t := range m.OtherTeams { if t.ID == teamID { - m.Lock() + m.OtherTeams[idx].Channels = mmchannels m.OtherTeams[idx].MoreChannels = moreChannels - m.Unlock() + break } } diff --git a/matterclient.go b/matterclient.go index 60100ee..a80eaac 100644 --- a/matterclient.go +++ b/matterclient.go @@ -305,8 +305,6 @@ func (m *Client) serverAlive(b *backoff.Backoff) error { func (m *Client) initUser() error { ctx := context.TODO() - m.Lock() - defer m.Unlock() // we only load all team data on initial login. // all other updates are for channels from our (primary) team only. teams, _, err := m.Client.GetTeamsForUser(ctx, m.User.Id, "") @@ -316,22 +314,21 @@ func (m *Client) initUser() error { for _, team := range teams { idx := 0 - max := 200 + const batchSize = 200 usermap := make(map[string]*model.User) - mmusers, _, err := m.Client.GetUsersInTeam(ctx, team.Id, idx, max, "") - if err != nil { - return err - } + for { + mmusers, _, err := m.Client.GetUsersInTeam(ctx, team.Id, idx, batchSize, "") + if err != nil { + return err + } - for len(mmusers) > 0 { for _, user := range mmusers { usermap[user.Id] = user } - mmusers, _, err = m.Client.GetUsersInTeam(ctx, team.Id, idx, max, "") - if err != nil { - return err + if len(mmusers) < batchSize { + break } idx++ @@ -339,6 +336,9 @@ func (m *Client) initUser() error { time.Sleep(time.Millisecond * 200) } m.logger.Debugf("found %d users in team %s", len(usermap), team.Name) + + m.Lock() + // add all users for k, v := range usermap { m.Users[k] = v @@ -356,6 +356,8 @@ func (m *Client) initUser() error { m.Team = t m.logger.Debugf("initUser(): found our team %s (id: %s)", team.Name, team.Id) } + + m.Unlock() } return nil diff --git a/users.go b/users.go index c8fae85..a2d51aa 100644 --- a/users.go +++ b/users.go @@ -117,7 +117,7 @@ func (m *Client) GetUsers() map[string]*model.User { func (m *Client) UpdateUsers() error { idx := 0 - max := 200 + const batchSize = 200 var ( mmusers []*model.User @@ -126,37 +126,25 @@ func (m *Client) UpdateUsers() error { ) for { - mmusers, resp, err = m.Client.GetUsers(context.TODO(), idx, max, "") - if err == nil { - break - } - - if err = m.HandleRatelimit("GetUsers", resp); err != nil { - return err + mmusers, resp, err = m.Client.GetUsers(context.TODO(), idx, batchSize, "") + if err != nil { + if rlErr := m.HandleRatelimit("GetUsers", resp); rlErr != nil { + return rlErr + } + continue } - } - for len(mmusers) > 0 { m.Lock() - for _, user := range mmusers { m.Users[user.Id] = user } - m.Unlock() - for { - mmusers, resp, err = m.Client.GetUsers(context.TODO(), idx, max, "") - if err == nil { - idx++ - - break - } - - if err := m.HandleRatelimit("GetUsers", resp); err != nil { - return err - } + if len(mmusers) < batchSize { + break } + + idx++ } return nil From 46a857f3141747599dd320ff5356672765cb2220 Mon Sep 17 00:00:00 2001 From: Haw Loeung Date: Mon, 29 Jun 2026 12:52:40 +1000 Subject: [PATCH 2/2] Reduce memory allocations by preallocating slices --- channels.go | 13 ++++++------- matterclient.go | 4 ++-- users.go | 12 ++++++------ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/channels.go b/channels.go index 96f9f8d..bd72369 100644 --- a/channels.go +++ b/channels.go @@ -208,13 +208,15 @@ func (m *Client) JoinChannel(channelID string) error { func (m *Client) UpdateChannelsTeam(teamID string) error { var ( - mmchannels []*model.Channel - resp *model.Response - err error + resp *model.Response + err error ) ctx := context.TODO() + const batchSize = 200 + + mmchannels := make([]*model.Channel, 0, batchSize) for { mmchannels, resp, err = m.Client.GetChannelsForTeamForUser(ctx, teamID, m.User.Id, false, "") if err == nil { @@ -227,10 +229,7 @@ func (m *Client) UpdateChannelsTeam(teamID string) error { } idx := 0 - const batchSize = 200 - - var moreChannels []*model.Channel - + moreChannels := make([]*model.Channel, 0, batchSize) for { channels, resp, err := m.Client.GetPublicChannelsForTeam(ctx, teamID, idx, batchSize, "") if err != nil { diff --git a/matterclient.go b/matterclient.go index a80eaac..f2274c4 100644 --- a/matterclient.go +++ b/matterclient.go @@ -312,11 +312,11 @@ func (m *Client) initUser() error { return err } + const batchSize = 200 + for _, team := range teams { idx := 0 - const batchSize = 200 usermap := make(map[string]*model.User) - for { mmusers, _, err := m.Client.GetUsersInTeam(ctx, team.Id, idx, batchSize, "") if err != nil { diff --git a/users.go b/users.go index a2d51aa..73914c4 100644 --- a/users.go +++ b/users.go @@ -116,15 +116,15 @@ func (m *Client) GetUsers() map[string]*model.User { } func (m *Client) UpdateUsers() error { - idx := 0 - const batchSize = 200 - var ( - mmusers []*model.User - resp *model.Response - err error + resp *model.Response + err error ) + const batchSize = 200 + + idx := 0 + mmusers := make([]*model.User, 0, batchSize) for { mmusers, resp, err = m.Client.GetUsers(context.TODO(), idx, batchSize, "") if err != nil {