chore(release): 0.4.0
[risinglegends.git] / src / server / events.ts
1 import { db } from './lib/db';
2 import { version } from '../../package.json';
3 import { CreatedEvent, Event, EventName } from '../shared/event';
4 import { isEqual } from 'lodash';
5 import { logger } from './lib/logger';
6 import { EVENT_FLUSH_INTERVAL, EVENT_SECOND_BUCKET } from '../shared/constants';
7 import { clickhouse } from './lib/clickhouse';
8
9 const eventBuffer: CreatedEvent[] = [];
10 const maxToAdd = 10;
11
12 export async function flushBuffer() {
13   const events = eventBuffer.splice(0, maxToAdd);
14   if(events.length) {
15     await addEvents(events);
16     logger.log(`Flushed ${events.length} events`);
17   }
18   setTimeout(flushBuffer, EVENT_FLUSH_INTERVAL);
19 }
20
21 function bucketTime(date: Date): Date {
22   const d = new Date();
23   d.setFullYear(date.getFullYear());
24   d.setMonth(date.getMonth());
25   d.setDate(date.getDate());
26   d.setHours(date.getHours());
27   d.setMinutes(date.getMinutes());
28   d.setMilliseconds(0);
29
30   const s = date.getSeconds();
31
32   // round down to closest 5 second interval
33   d.setSeconds(s - (s%EVENT_SECOND_BUCKET));
34   return d;
35 }
36
37
38 export async function addEvent(event_name: EventName, player_id: string, props?: any, created?: Date) {
39   eventBuffer.push({
40     event_name,
41     player_id,
42     app_version: version,
43     props: props,
44     created
45   });
46 }
47
48 export async function addEvents(events: CreatedEvent[]) {
49   return db('events').insert(events);
50 }
51
52 export async function getEventHistory(player_id: string, event_name: EventName) {
53   return db.select('*').from<Event<any>>('events').where({
54     player_id,
55     event_name
56   });
57 }
58
59 export async function getEventHistoryToday(player_id: string, event_name: EventName) {
60   return db.select('*').from<Event<any>>('events').where({
61     player_id,
62     event_name
63   }).andWhere('created', '>=', db.raw('current_date::timestamp'));
64
65 }
66
67 export async function hasNeverHappenedBefeore(name: EventName, player_id: string, props?: any): Promise<boolean> {
68   return hasHappendXTimes(0, name, player_id, props);
69 }
70
71 export async function hasHappendXTimes(times: number, event_name: EventName, player_id: string, props?: any): Promise<boolean> {
72   const res: Event<any>[] = await getEventHistory(player_id, event_name);
73
74   if(props) {
75     return res.filter(row => isEqual(row.props, props)).length === times;
76   }
77   return res.length === times;
78 }