85 lines
2.7 KiB
TypeScript
85 lines
2.7 KiB
TypeScript
import { Injectable, Logger } from '@nestjs/common';
|
|
import { Users } from '../couchdb-datasources/users';
|
|
import { RedmineDataLoader } from '../redmine-data-loader/redmine-data-loader';
|
|
import { RedmineUserCacheWriterService } from '../user-cache-writer/user-cache-writer.service';
|
|
import { RedmineTypes } from '../models/redmine-types';
|
|
import { MemoryCache } from '../utils/memory-cache';
|
|
|
|
export const USER_MEMORY_CACHE_LIFETIME = 24 * 60 * 60 * 1000;
|
|
const USER_MEMORY_CACHE_AUTOCLEAN_INTERVAL = 1000 * 60 * 5;
|
|
|
|
@Injectable()
|
|
export class UsersService {
|
|
private logger = new Logger(UsersService.name);
|
|
private memoryCache = new MemoryCache<number, RedmineTypes.User>(
|
|
USER_MEMORY_CACHE_LIFETIME,
|
|
USER_MEMORY_CACHE_AUTOCLEAN_INTERVAL,
|
|
);
|
|
|
|
constructor(
|
|
private users: Users,
|
|
private redmineDataLoader: RedmineDataLoader,
|
|
private redmineUserCacheWriterService: RedmineUserCacheWriterService,
|
|
) {}
|
|
|
|
async getUser(userId: number): Promise<RedmineTypes.PublicUser> {
|
|
const userFromMemoryCache = this.getUserFromMemoryCache(userId);
|
|
if (userFromMemoryCache) {
|
|
return RedmineTypes.CreatePublicUserFromUser(userFromMemoryCache);
|
|
}
|
|
const userFromCache = await this.getUserFromCache(userId);
|
|
if (userFromCache) {
|
|
this.memoryCache.set(userId, userFromCache);
|
|
return RedmineTypes.CreatePublicUserFromUser(userFromCache);
|
|
}
|
|
let userFromRedmine = await this.getUserFromRedmine(userId);
|
|
if (userFromRedmine) {
|
|
userFromRedmine = await this.redmineUserCacheWriterService.saveUser(
|
|
userFromRedmine,
|
|
);
|
|
}
|
|
return RedmineTypes.CreatePublicUserFromUser(
|
|
this.memoryCache.set(
|
|
userId,
|
|
userFromRedmine || RedmineTypes.Unknown.user,
|
|
),
|
|
);
|
|
}
|
|
|
|
private async getUserFromRedmine(
|
|
userId: number,
|
|
): Promise<RedmineTypes.User | null> {
|
|
const user = await this.redmineDataLoader.loadUser(userId);
|
|
if (user) {
|
|
this.logger.debug(
|
|
`Get user from redmine with userId = ${userId}, login = ${user.login}`,
|
|
);
|
|
}
|
|
return user;
|
|
}
|
|
|
|
private async getUserFromCache(
|
|
userId: number,
|
|
): Promise<RedmineTypes.User | null> {
|
|
const usersDb = await this.users.getDatasource();
|
|
try {
|
|
const user = (await usersDb.get(String(userId))) as any;
|
|
this.logger.debug(
|
|
`Get user from couchdb with userId = ${userId}, login = ${user.login}`,
|
|
);
|
|
return user;
|
|
} catch (ex) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private getUserFromMemoryCache(userId: number): RedmineTypes.User | null {
|
|
const user = this.memoryCache.get(userId);
|
|
if (user) {
|
|
this.logger.debug(
|
|
`Get user from memory cache with userId = ${userId}, login = ${user.login}`,
|
|
);
|
|
}
|
|
return user;
|
|
}
|
|
}
|