diff --git a/app/src/algolia/actions/updateIndices.ts b/app/src/algolia/actions/updateIndices.ts index 6739cc99..1992fdb4 100644 --- a/app/src/algolia/actions/updateIndices.ts +++ b/app/src/algolia/actions/updateIndices.ts @@ -2,6 +2,8 @@ import { prisma } from "@/db"; import { log } from "@/logging"; +import { getTracer } from "@/tracing/utils/getTracer"; +import { SpanStatusCode } from "@opentelemetry/api"; import { unstable_rethrow } from "next/navigation"; import { serializeError } from "serialize-error"; import { getIndex } from ".."; @@ -34,31 +36,53 @@ export const updateIndices = async () => { ]); const index = getIndex(); - await index.clearObjects(); + await getTracer().startActiveSpan("clearAlgoliaObjects", async (span) => { + try { + } catch (error) { + await index.clearObjects(); + span.setStatus({ + code: SpanStatusCode.ERROR, + }); + throw error; + } finally { + span.end(); + } + }); - await index.saveObjects([ - ...organizations.map((organization) => ({ - objectID: organization.id, - spectrumId: organization.spectrumId, - type: "organization", - names: [organization.name], - })), + await getTracer().startActiveSpan("saveAlgoliaObjects", async (span) => { + try { + await index.saveObjects([ + ...organizations.map((organization) => ({ + objectID: organization.id, + spectrumId: organization.spectrumId, + type: "organization", + names: [organization.name], + })), - ...citizen.map((citizen) => ({ - objectID: citizen.id, - spectrumId: citizen.spectrumId, - type: "citizen", - handles: citizen.logs - .filter((log) => log.type === "handle") - .map((log) => log.content), - communityMonikers: citizen.logs - .filter((log) => log.type === "community-moniker") - .map((log) => log.content), - citizenIds: citizen.logs - .filter((log) => log.type === "citizen-id") - .map((log) => log.content), - })), - ]); + ...citizen.map((citizen) => ({ + objectID: citizen.id, + spectrumId: citizen.spectrumId, + type: "citizen", + handles: citizen.logs + .filter((log) => log.type === "handle") + .map((log) => log.content), + communityMonikers: citizen.logs + .filter((log) => log.type === "community-moniker") + .map((log) => log.content), + citizenIds: citizen.logs + .filter((log) => log.type === "citizen-id") + .map((log) => log.content), + })), + ]); + } catch (error) { + span.setStatus({ + code: SpanStatusCode.ERROR, + }); + throw error; + } finally { + span.end(); + } + }); return { success: "Successfully updated Algolia indices", diff --git a/app/src/leaderboards/queries.ts b/app/src/leaderboards/queries.ts index 3fdf2dd7..bb7e5e65 100644 --- a/app/src/leaderboards/queries.ts +++ b/app/src/leaderboards/queries.ts @@ -1,3 +1,5 @@ +import { getTracer } from "@/tracing/utils/getTracer"; +import { SpanStatusCode } from "@opentelemetry/api"; import { unstable_cache } from "next/cache"; import { z } from "zod"; @@ -35,27 +37,38 @@ const schema = z.object({ export const getLeaderboard = (mode: "SB", season: string) => { return unstable_cache( async (mode: "SB", season: string) => { - const response = await fetch( - "https://robertsspaceindustries.com/api/leaderboards/getLeaderboard", - { - method: "POST", - body: JSON.stringify({ - mode, - map: "MAP-ANY", - type: "Account", - season, - page: 1, - pagesize: "100", - }), - headers: { - "Content-Type": "application/json", - }, - }, - ); + return getTracer().startActiveSpan("getLeaderboard", async (span) => { + try { + const response = await fetch( + "https://robertsspaceindustries.com/api/leaderboards/getLeaderboard", + { + method: "POST", + body: JSON.stringify({ + mode, + map: "MAP-ANY", + type: "Account", + season, + page: 1, + pagesize: "100", + }), + headers: { + "Content-Type": "application/json", + }, + }, + ); - const json = (await response.json()) as unknown; - const result = schema.parse(json); - return result.data.resultset; + const json = (await response.json()) as unknown; + const result = schema.parse(json); + return result.data.resultset; + } catch (error) { + span.setStatus({ + code: SpanStatusCode.ERROR, + }); + throw error; + } finally { + span.end(); + } + }); }, [`mode=${mode}`, `season=${season}`], { diff --git a/app/src/roles/utils/getRoles.ts b/app/src/roles/utils/getRoles.ts index 31ca49b9..daa53b78 100644 --- a/app/src/roles/utils/getRoles.ts +++ b/app/src/roles/utils/getRoles.ts @@ -1,34 +1,47 @@ import { requireAuthentication } from "@/auth/server"; import { prisma } from "@/db"; +import { getTracer } from "@/tracing/utils/getTracer"; +import { SpanStatusCode } from "@opentelemetry/api"; import type { Entity } from "@prisma/client"; import { cache } from "react"; import { getRoles } from "../queries"; export const getVisibleRoles = cache(async () => { - const authentication = await requireAuthentication(); + return getTracer().startActiveSpan("getVisibleRoles", async (span) => { + try { + const authentication = await requireAuthentication(); - const allRoles = await getRoles(); - // TODO: Filter `inherits` as well - const visibleRoles = ( - await Promise.all( - allRoles.map(async (role) => { - return { - role, - include: await authentication.authorize("otherRole", "read", [ - { - key: "roleId", - value: role.id, - }, - ]), - }; - }), - ) - ) - .filter(({ include }) => include) - .map(({ role }) => role) - .sort((a, b) => a.name.localeCompare(b.name)); + const allRoles = await getRoles(); + // TODO: Filter `inherits` as well + const visibleRoles = ( + await Promise.all( + allRoles.map(async (role) => { + return { + role, + include: await authentication.authorize("otherRole", "read", [ + { + key: "roleId", + value: role.id, + }, + ]), + }; + }), + ) + ) + .filter(({ include }) => include) + .map(({ role }) => role) + .sort((a, b) => a.name.localeCompare(b.name)); - return visibleRoles; + return visibleRoles; + } catch (error) { + span.setStatus({ + code: SpanStatusCode.ERROR, + }); + throw error; + } finally { + span.end(); + } + }); }); export const getAssignedRoles = cache(async (entity: Entity) => { @@ -43,51 +56,73 @@ export const getAssignedRoles = cache(async (entity: Entity) => { }); export const getMyAssignedRoles = cache(async () => { - const authentication = await requireAuthentication(); + return getTracer().startActiveSpan("getMyAssignedRoles", async (span) => { + try { + const authentication = await requireAuthentication(); - const entity = await prisma.entity.findUnique({ - where: { - discordId: authentication.session.discordId, - }, - }); - if (!entity) throw new Error("Forbidden"); + const entity = await prisma.entity.findUnique({ + where: { + discordId: authentication.session.discordId, + }, + }); + if (!entity) throw new Error("Forbidden"); - return getAssignedRoles(entity); + return await getAssignedRoles(entity); + } catch (error) { + span.setStatus({ + code: SpanStatusCode.ERROR, + }); + throw error; + } finally { + span.end(); + } + }); }); export const getAssignableRoles = cache(async () => { - const [authentication, allRoles] = await Promise.all([ - requireAuthentication(), - getVisibleRoles(), - ]); + return getTracer().startActiveSpan("getAssignableRoles", async (span) => { + try { + const [authentication, allRoles] = await Promise.all([ + requireAuthentication(), + getVisibleRoles(), + ]); - const assignableRoles = ( - await Promise.all( - allRoles.map(async (role) => { - const include = - (await authentication.authorize("otherRole", "assign", [ - { - key: "roleId", - value: role.id, - }, - ])) || - (await authentication.authorize("otherRole", "dismiss", [ - { - key: "roleId", - value: role.id, - }, - ])); + const assignableRoles = ( + await Promise.all( + allRoles.map(async (role) => { + const include = + (await authentication.authorize("otherRole", "assign", [ + { + key: "roleId", + value: role.id, + }, + ])) || + (await authentication.authorize("otherRole", "dismiss", [ + { + key: "roleId", + value: role.id, + }, + ])); - return { - role, - include, - }; - }), - ) - ) - .filter(({ include }) => include) - .map(({ role }) => role) - .sort((a, b) => a.name.localeCompare(b.name)); + return { + role, + include, + }; + }), + ) + ) + .filter(({ include }) => include) + .map(({ role }) => role) + .sort((a, b) => a.name.localeCompare(b.name)); - return assignableRoles; + return assignableRoles; + } catch (error) { + span.setStatus({ + code: SpanStatusCode.ERROR, + }); + throw error; + } finally { + span.end(); + } + }); });