Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/webapp/app/v3/eventRepository/common.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function extractContextFromCarrier(carrier: Record<string, unknown>) {
}

export function getNowInNanoseconds(): bigint {
return BigInt(new Date().getTime() * 1_000_000);
return convertDateToNanoseconds(new Date());
}

export function getDateFromNanoseconds(nanoseconds: bigint): Date {
Expand All @@ -40,7 +40,7 @@ export function calculateDurationFromStart(
) {
const $endtime = typeof endTime === "string" ? new Date(endTime) : endTime;

const duration = Number(BigInt($endtime.getTime() * 1_000_000) - startTime);
const duration = Number(convertDateToNanoseconds($endtime) - startTime);

if (minimumDuration && duration < minimumDuration) {
return minimumDuration;
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/v3/eventRepository/index.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ async function recordRunEvent(
runId: foundRun.friendlyId,
...attributes,
},
startTime: BigInt((startTime?.getTime() ?? Date.now()) * 1_000_000),
startTime: BigInt(startTime?.getTime() ?? Date.now()) * BigInt(1_000_000),
...optionsRest,
});

Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/v3/runEngineHandlers.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ export function registerRunEngineEventBusHandlers() {
);

await eventRepository.recordEvent(retryMessage, {
startTime: BigInt(time.getTime() * 1000000),
startTime: BigInt(time.getTime()) * BigInt(1_000_000),
taskSlug: run.taskIdentifier,
environment,
attributes: {
Expand Down
41 changes: 41 additions & 0 deletions apps/webapp/test/eventRepositoryCommon.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import {
calculateDurationFromStart,
convertDateToNanoseconds,
getNowInNanoseconds,
} from "~/v3/eventRepository/common.server";
Comment on lines +1 to +6

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Conversion tests are not colocated

The new conversion tests live outside the event repository. The repository's testing guide requires new test files beside the source they exercise.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.


// 1700000000001 * 1e6 is not representable as a double (spacing is 256 at ~1.7e18),
// so Number multiplication before BigInt conversion rounds it to ...000999936.
const unsafeMs = 1_700_000_000_001;
const unsafeNs = 1_700_000_000_001_000_000n;

describe("eventRepository nanosecond conversions", () => {
afterEach(() => {
vi.useRealTimers();
});

it("convertDateToNanoseconds keeps exact precision beyond MAX_SAFE_INTEGER", () => {
expect(convertDateToNanoseconds(new Date(unsafeMs))).toBe(unsafeNs);
});

it("getNowInNanoseconds keeps exact precision beyond MAX_SAFE_INTEGER", () => {
vi.useFakeTimers();
vi.setSystemTime(unsafeMs);
Comment on lines +23 to +24

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Clock fakes in conversion test

The getNowInNanoseconds test replaces the clock with fake timers. The repository's testing rules prohibit fakes; use a real-clock assertion or a testable clock input.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.


expect(getNowInNanoseconds()).toBe(unsafeNs);
expect(getNowInNanoseconds() % 1_000_000n).toBe(0n);
});

it("calculateDurationFromStart is exact for sub-millisecond-sensitive end times", () => {
const startTime = convertDateToNanoseconds(new Date(unsafeMs - 1));

expect(calculateDurationFromStart(startTime, new Date(unsafeMs))).toBe(1_000_000);
});

it("calculateDurationFromStart applies the minimum duration", () => {
const startTime = convertDateToNanoseconds(new Date(unsafeMs - 1));

expect(calculateDurationFromStart(startTime, new Date(unsafeMs), 5_000_000)).toBe(5_000_000);
});
});