feat: optimize db queries (#297)

This commit is contained in:
Julian Tölle 2023-09-17 00:31:39 +02:00 committed by GitHub
parent fd28daa37a
commit dd57a52ab6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 104 additions and 33 deletions

View file

@ -53,7 +53,7 @@ export class SchedulerService implements OnApplicationBootstrap {
const INACTIVE_CUTOFF_MSEC = 60 * 60 * 1000;
await Promise.all(
userInfo.map(({ user, lastListen }) => {
userInfo.map(({ userID, lastListen }) => {
let pollRate = POLL_RATE_INACTIVE_SEC;
const timeSinceLastListen = new Date().getTime() - lastListen.getTime();
@ -62,10 +62,10 @@ export class SchedulerService implements OnApplicationBootstrap {
}
this.importSpotifyJobService.sendThrottled(
{ userID: user.id },
{ userID },
{},
pollRate,
user.id,
userID,
);
}),
);

View file

@ -43,27 +43,31 @@ export class SpotifyService {
) {}
@Span()
async getCrawlableUserInfo(): Promise<{ user: User; lastListen: Date }[]> {
// All of this is kinda inefficient, we do two db queries and join in code,
// i can't be bothered to do this properly in the db for now.
// Should be refactored if listory gets hundreds of users (lol).
async getCrawlableUserInfo(): Promise<
{ userID: string; lastListen: Date }[]
> {
const users = await this.usersService
.getQueryBuilder()
.select(`user.id as "userID"`)
.addSelect(`listen."playedAt" as "lastListen"`)
.leftJoin(
(qb) =>
qb
.distinctOn(["listen.userId"])
.select(`listen."userId"`)
.addSelect(`listen."playedAt"`)
.from("listen", "listen")
.orderBy("listen.userId", "DESC")
.addOrderBy("listen.playedAt", "DESC"),
"listen",
`listen."userId" = user.id`,
)
.getRawMany<{ userID: string; lastListen?: Date }>();
const [users, listens] = await Promise.all([
this.usersService.findAll(),
this.listensService.getMostRecentListenPerUser(),
]);
return users.map((user) => {
const lastListen = listens.find((listen) => listen.user.id === user.id);
return {
user,
// Return 1970 if no listen exists
lastListen: lastListen ? lastListen.playedAt : new Date(0),
};
});
return;
return users.map(({ userID, lastListen }) => ({
userID,
lastListen: lastListen || new Date(0),
}));
}
@ImportSpotifyJob.Handle()