message: Cache user features
diff: @@ -27,9 +27,12 @@ import Bluebird from "bluebird";
  import { StringCrypto } from "../StringCrypto";
  import { toIrcLowerCase } from "../../irc/formatting";
  import { NeDBDataStore } from "../NedbDataStore";
  +import QuickLRU from "quick-lru";
  const log = getLogger("PgDatastore");
  +const FEATURE_CACHE_SIZE = 512;
  +
  export class PgDataStore implements DataStore {
  private serverMappings: {[domain: string]: IrcServer} = {};
  @@ -37,6 +40,9 @@ export class PgDataStore implements DataStore {
  private pgPool: Pool;
  private hasEnded = false;
  private cryptoStore?: StringCrypto;
  + private userFeatureCache = new QuickLRU<string, UserFeatures>({
  + maxSize: FEATURE_CACHE_SIZE,
  + });
  constructor(private bridgeDomain: string, connectionString: string, pkeyPath?: string, min = 1, max = 4) {
  this.pgPool = new Pool({
  @@ -465,14 +471,14 @@ export class PgDataStore implements DataStore {
  }
  public async getUserFeatures(userId: string): Promise<UserFeatures> {
  - const pgRes = (
  - await this.pgPool.query("SELECT features FROM user_features WHERE user_id = $1",
  - [userId])
  - );
  - if (pgRes.rowCount === 0) {
  - return {};
  - }
  - return pgRes.rows[0].features || {};
  + const existing = this.userFeatureCache.get(userId);
  + if (existing) {
  + return existing;
  + }
  + const pgRes = await this.pgPool.query("SELECT features FROM user_features WHERE user_id = $1", [userId]);
  + const features = (pgRes.rows[0] || {});
  + this.userFeatureCache.set(userId, features);
  + return features;
  }
  public async storeUserFeatures(userId: string, features: UserFeatures): Promise<void> {
  