Skip to content

Commit

Permalink
feature: add tracing to achievement system (#935)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhenkel92 authored Dec 19, 2023
1 parent c42ff66 commit 6bfd232
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 26 deletions.
6 changes: 4 additions & 2 deletions common/achievement/create.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Prisma } from '@prisma/client';
import { Achievement_template, JsonFilter, achievement_template_for_enum } from '../../graphql/generated';
import { Achievement_template, achievement_template_for_enum } from '../../graphql/generated';
import { ActionID, SpecificNotificationContext } from '../notification/actions';
import { prisma } from '../prisma';
import { TemplateSelectEnum, getAchievementTemplates } from './template';
import tracer from '../logger/tracing';

async function findUserAchievement<ID extends ActionID>(templateId: number, userId: string, context: SpecificNotificationContext<ID>) {
const keys = context ? Object.keys(context) : [];
Expand Down Expand Up @@ -36,7 +37,8 @@ async function getOrCreateUserAchievement<ID extends ActionID>(template: Achieve
return existingUserAchievement;
}

async function createAchievement<ID extends ActionID>(currentTemplate: Achievement_template, userId: string, context: SpecificNotificationContext<ID>) {
const createAchievement = tracer.wrap('achievement.createAchievement', _createAchievement);
async function _createAchievement<ID extends ActionID>(currentTemplate: Achievement_template, userId: string, context: SpecificNotificationContext<ID>) {
const templatesByGroup = await getAchievementTemplates(TemplateSelectEnum.BY_GROUP);
const keys = Object.keys(context);
const userAchievementsByGroup = await prisma.user_achievement.findMany({
Expand Down
6 changes: 5 additions & 1 deletion common/achievement/evaluate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ import swan from '@onlabsorg/swan-js';
import { bucketCreatorDefs } from './bucket';
import { getLogger } from '../logger/logger';
import { getBucketContext } from './util';
import tracer from '../logger/tracing';

const logger = getLogger('Achievement');

export async function evaluateAchievement(
export const evaluateAchievement = tracer.wrap('achievement.evaluateAchievement', _evaluateAchievement);

async function _evaluateAchievement(
condition: string,
dataAggregation: ConditionDataAggregations,
metrics: string[],
Expand Down
39 changes: 24 additions & 15 deletions common/achievement/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ import { evaluateAchievement } from './evaluate';
import { AchievementToCheck, ActionEvent, ConditionDataAggregations, UserAchievementContext, UserAchievementTemplate } from './types';
import { createAchievement, getOrCreateUserAchievement } from './create';
import { actionTakenAt } from '../notification';

Check warning on line 10 in common/achievement/index.ts

View workflow job for this annotation

GitHub Actions / lint

Dependency cycle detected
import tracer from '../logger/tracing';

const logger = getLogger('Achievement');

export async function rewardActionTaken<ID extends ActionID>(user: User, actionId: ID, context: SpecificNotificationContext<ID>) {
export const rewardActionTaken = tracer.wrap('achievement.rewardActionTaken', _rewardActionTaken);
async function _rewardActionTaken<ID extends ActionID>(user: User, actionId: ID, context: SpecificNotificationContext<ID>) {
if (!isGamificationFeatureActive()) {
return;
}
const templatesForAction = await getTemplatesByAction(actionId);
const templatesForAction = await tracer.trace('achievement.getTemplatesByAction', () => getTemplatesByAction(actionId));

if (templatesForAction.length === 0) {
logger.debug(`No achievement found for action '${actionId}'`);
Expand All @@ -30,20 +32,27 @@ export async function rewardActionTaken<ID extends ActionID>(user: User, actionI
user: user,
context,
};
await trackEvent(actionEvent);

for (const [, group] of templatesByGroups) {
let achievementToCheck: AchievementToCheck;
for (const template of group) {
const userAchievement = await getOrCreateUserAchievement(template, user.userID, context);
if (userAchievement.achievedAt === null || userAchievement.recordValue) {
achievementToCheck = userAchievement;
break;
await tracer.trace('achievement.trackEvent', () => trackEvent(actionEvent));

for (const [groupName, group] of templatesByGroups) {
await tracer.trace('achievement.evaluateAchievementGroups', async (span) => {
span.setTag('achievement.group', groupName);
let achievementToCheck: AchievementToCheck;
for (const template of group) {
const userAchievement = await tracer.trace('achievement.getOrCreateUserAchievement', () =>
getOrCreateUserAchievement(template, user.userID, context)
);
if (userAchievement.achievedAt === null || userAchievement.recordValue) {
achievementToCheck = userAchievement;
break;
}
}
}
if (achievementToCheck) {
await checkUserAchievement(achievementToCheck as UserAchievementTemplate, actionEvent);
}
span.setTag('achievement.foundToCheck', !!achievementToCheck);
if (achievementToCheck) {
span.setTag('achievement.id', achievementToCheck.id);
await tracer.trace('achievement.checkUserAchievement', () => checkUserAchievement(achievementToCheck as UserAchievementTemplate, actionEvent));
}
});
}
}

Expand Down
20 changes: 12 additions & 8 deletions common/notification/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Channels } from '../../graphql/types/preferences';
import { ALL_PREFERENCES } from './defaultPreferences';
import assert from 'assert';
import { Prisma } from '@prisma/client';
import { addTagsToActiveSpan } from '../logger/tracing';
import tracer, { addTagsToActiveSpan } from '../logger/tracing';
import * as Achievement from '../../common/achievement';

Check warning on line 18 in common/notification/index.ts

View workflow job for this annotation

GitHub Actions / lint

Dependency cycle detected

const logger = getLogger('Notification');
Expand Down Expand Up @@ -397,14 +397,17 @@ export async function actionTaken<ID extends ActionID>(
attachments?: AttachmentGroup,
noDuplicates = false
) {
if (!user.active) {
logger.debug(`No action '${actionId}' taken for User(${user.userID}) as the account is deactivated`);
return;
}
return await tracer.trace('notification.actionTaken', async (span) => {
span.setTag('actionId', actionId);

await Achievement.rewardActionTaken(user, actionId, notificationContext);
if (!user.active) {
logger.debug(`No action '${actionId}' taken for User(${user.userID}) as the account is deactivated`);
return;
}

return await actionTakenAt(new Date(), user, actionId, notificationContext, false, noDuplicates, attachments);
await Achievement.rewardActionTaken(user, actionId, notificationContext);
return await actionTakenAt(new Date(), user, actionId, notificationContext, false, noDuplicates, attachments);
});
}

/* actionTakenAt is the mighty variant of actionTaken:
Expand Down Expand Up @@ -443,7 +446,8 @@ If 'noDuplicates' is set, a Notification will be ignored if a Notification alrea
Otherwise a Notification will just be sent multiple times.
*/

export async function actionTakenAt<ID extends ActionID>(
export const actionTakenAt = tracer.wrap('notification.actionTakenAt', _actionTakenAt);
export async function _actionTakenAt<ID extends ActionID>(
at: Date,
user: User,
actionId: ID,
Expand Down

0 comments on commit 6bfd232

Please sign in to comment.