Skip to content

Commit

Permalink
feat: add custom spans
Browse files Browse the repository at this point in the history
  • Loading branch information
simonknittel committed Jan 26, 2025
1 parent 39eb85e commit bdf33e0
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 104 deletions.
70 changes: 47 additions & 23 deletions app/src/algolia/actions/updateIndices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 "..";
Expand Down Expand Up @@ -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",
Expand Down
53 changes: 33 additions & 20 deletions app/src/leaderboards/queries.ts
Original file line number Diff line number Diff line change
@@ -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";

Expand Down Expand Up @@ -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}`],
{
Expand Down
157 changes: 96 additions & 61 deletions app/src/roles/utils/getRoles.ts
Original file line number Diff line number Diff line change
@@ -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) => {
Expand All @@ -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();
}
});
});

0 comments on commit bdf33e0

Please sign in to comment.