Skip to content

Commit 4f1b148

Browse files
wip on service ping
1 parent 92cf88f commit 4f1b148

File tree

6 files changed

+66
-1
lines changed

6 files changed

+66
-1
lines changed

.env.development

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,5 @@ SOURCEBOT_TELEMETRY_DISABLED=true # Disables telemetry collection
7171
NODE_ENV=development
7272

7373
DEBUG_WRITE_CHAT_MESSAGES_TO_FILE=true
74+
75+
SOURCEBOT_LIGHTHOUSE_URL=http://localhost:3003

packages/shared/src/entitlements.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ export type Plan = keyof typeof planLabels;
3131
const entitlements = [
3232
"search-contexts",
3333
"anonymous-access",
34-
"multi-tenancy",
3534
"sso",
3635
"code-nav",
3736
"audit",

packages/shared/src/env.server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ const options = {
266266

267267
SOURCEBOT_ENCRYPTION_KEY: z.string(),
268268
SOURCEBOT_INSTALL_ID: z.string().default("unknown"),
269+
SOURCEBOT_LIGHTHOUSE_URL: z.string().url(),
269270

270271
FALLBACK_GITHUB_CLOUD_TOKEN: z.string().optional(),
271272
FALLBACK_GITLAB_CLOUD_TOKEN: z.string().optional(),

packages/web/src/initialize.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createGuestUser } from '@/lib/authUtils';
22
import { __unsafePrisma } from "@/prisma";
3+
import { startServicePing } from '@/servicePing';
34
import { OrgRole } from '@sourcebot/db';
45
import { createLogger, env, hasEntitlement, loadConfig } from "@sourcebot/shared";
56
import { SINGLE_TENANT_ORG_ID, SOURCEBOT_GUEST_USER_ID } from './lib/constants';
@@ -115,4 +116,5 @@ const init = async () => {
115116

116117
(async () => {
117118
await init();
119+
startServicePing();
118120
})();

packages/web/src/lib/utils.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,4 +589,28 @@ export const isHttpError = (error: unknown, status: number): boolean => {
589589
&& typeof error === 'object'
590590
&& 'status' in error
591591
&& error.status === status;
592+
}
593+
594+
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
595+
596+
export const fetchWithRetry = async (
597+
input: RequestInfo | URL,
598+
init?: RequestInit,
599+
{ retries = 3, backoffMs = 1000 }: { retries?: number; backoffMs?: number } = {},
600+
): Promise<Response> => {
601+
for (let attempt = 0; attempt <= retries; attempt++) {
602+
try {
603+
const response = await fetch(input, init);
604+
if (response.ok || attempt === retries) {
605+
return response;
606+
}
607+
} catch (error) {
608+
if (attempt === retries) {
609+
throw error;
610+
}
611+
}
612+
await sleep(backoffMs * Math.pow(2, attempt));
613+
}
614+
// Unreachable, but TypeScript needs it
615+
throw new Error('fetchWithRetry: exhausted retries');
592616
}

packages/web/src/servicePing.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { fetchWithRetry } from "@/lib/utils";
2+
import { createLogger, env, SOURCEBOT_VERSION } from "@sourcebot/shared";
3+
4+
const logger = createLogger('service-ping');
5+
6+
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
7+
8+
const sendPing = async () => {
9+
const payload = {
10+
installId: env.SOURCEBOT_INSTALL_ID,
11+
version: SOURCEBOT_VERSION,
12+
};
13+
14+
try {
15+
const response = await fetchWithRetry(`${env.SOURCEBOT_LIGHTHOUSE_URL}/ping`, {
16+
method: 'POST',
17+
headers: { 'Content-Type': 'application/json' },
18+
body: JSON.stringify(payload),
19+
});
20+
21+
if (!response.ok) {
22+
logger.error(`Service ping failed with status ${response.status}`);
23+
} else {
24+
logger.info(`Service ping sent successfully`);
25+
}
26+
} catch (error) {
27+
logger.error(`Service ping failed: ${error}`);
28+
}
29+
};
30+
31+
export const startServicePing = () => {
32+
// Fire immediately on startup
33+
sendPing();
34+
35+
// Then repeat daily
36+
setInterval(sendPing, ONE_DAY_MS);
37+
};

0 commit comments

Comments
 (0)