connector: implement user cache
* Fixes the totally broken UserInfo resolution in guilds. * Adds support for USER_UPDATE from the gateway. Design considerations behind the user cache: * Explicitly handle deleted user IDs by short circuiting the lookup logic and returning a singleton. * The cache map is protected during HTTP requests to the Discord API. * The nonexistence of a user is cached. This is to prevent excessive requests (a user can't suddenly begin existing at a given ID). The user cache is upserted on READY, incoming messages, backfill, etc.
This commit is contained in:
@@ -37,16 +37,17 @@ import (
|
||||
)
|
||||
|
||||
type DiscordClient struct {
|
||||
connector *DiscordConnector
|
||||
usersFromReady map[string]*discordgo.User
|
||||
UserLogin *bridgev2.UserLogin
|
||||
Session *discordgo.Session
|
||||
client *http.Client
|
||||
connector *DiscordConnector
|
||||
UserLogin *bridgev2.UserLogin
|
||||
Session *discordgo.Session
|
||||
client *http.Client
|
||||
|
||||
hasBegunSyncing bool
|
||||
|
||||
markedOpened map[string]time.Time
|
||||
markedOpenedLock sync.Mutex
|
||||
|
||||
userCache *UserCache
|
||||
}
|
||||
|
||||
func (d *DiscordConnector) LoadUserLogin(ctx context.Context, login *bridgev2.UserLogin) error {
|
||||
@@ -63,6 +64,7 @@ func (d *DiscordConnector) LoadUserLogin(ctx context.Context, login *bridgev2.Us
|
||||
UserLogin: login,
|
||||
Session: session,
|
||||
client: d.Bridge.GetHTTPClientSettings().Compile(),
|
||||
userCache: NewUserCache(session),
|
||||
}
|
||||
|
||||
login.Client = &cl
|
||||
@@ -128,12 +130,9 @@ func (cl *DiscordClient) connect(ctx context.Context) error {
|
||||
user := cl.Session.State.User
|
||||
log.Info().Str("user_id", user.ID).Str("user_username", user.Username).Msg("Connected to Discord")
|
||||
|
||||
// Stash all of the users we received in READY so we can perform quick lookups
|
||||
// keyed by user ID.
|
||||
cl.usersFromReady = make(map[string]*discordgo.User)
|
||||
for _, user := range cl.Session.State.Ready.Users {
|
||||
cl.usersFromReady[user.ID] = user
|
||||
}
|
||||
// Populate the user cache with the users from the READY payload.
|
||||
log.Debug().Int("n_users", len(cl.Session.State.Ready.Users)).Msg("Inserting users from READY into cache")
|
||||
cl.userCache.HandleReady(&cl.Session.State.Ready)
|
||||
|
||||
cl.BeginSyncing(ctx)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user