GetStream/stream-chat-angular

429 errors with lots of users

nvahalik opened this issue ยท 2 comments

If a user has lots of channels (hundreds) and loads pages of those channels in rapid succession, along with loading the channel preview (which in turn shows the avatar), you will very quickly run into 429 errors as the avatar makes calls to queryUsers() individually:

const response = await this.chatClientService.chatClient.queryUsers(
{
id: { $eq: otherMember.id },
}
);

This is a MAJOR problem as individual users only get 60 requests per minute. So if you load 2 screens of 30 users, you will immediately hit the API rate limit for the user.

Internally, we fixed this by overriding the AvatarComponent and creating a buffering/queue system where calls to our getUserDetails() get combined:

#pendingUserQuery$ = new BehaviorSubject<string[]>([]);

#userQueryResults = this.#pendingUserQuery$
  .pipe(
    filter((i) => i.length > 0),
    debounceTime(50),
    // Reset it.
    tap(() => this.#pendingUserQuery$.next([])),
    switchMap(userIds => this.chatService.chatClient.queryUsers({id: {$in: userIds}})),
    share(),
  );

getUserDetails(id: string) {
  // We have a user ID. We want to combine a LOT of user information requests INTO a single request.
  this.#pendingUserQuery$.next([...this.#pendingUserQuery$.getValue(), id]);

  // Then, we want to return those results to each individual caller.
  return this.#userQueryResults.pipe(
    map(i => i.users.find(u => u.id === id))
  );
}

We then updated our AvatarComponent to call our custom service:

this.streamChatService.getUserDetails(otherMember.id)
  .subscribe((user) => {
    this.isOnline = user?.online || false;
  })

This has pretty much completely resolved the issues.

Thanks for reporting this issue. It is indeed problematic. I've scheduled the fix for the end of next week at the latest.

๐ŸŽ‰ This issue has been resolved in version 4.45.1 ๐ŸŽ‰

The release is available on:

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€