|
| 1 | +import { join } from 'node:path'; |
| 2 | +import { expect, it, vi } from 'vitest'; |
| 3 | +import { createRunner } from '../../../runner'; |
| 4 | + |
| 5 | +interface Invocation { |
| 6 | + trigger: string; |
| 7 | + durationMs: number; |
| 8 | +} |
| 9 | + |
| 10 | +// Regression test for https://github.com/getsentry/sentry-javascript/issues/25489 |
| 11 | +// workerd keeps a Durable Object invocation open until its pending timers fire, so an SDK timer |
| 12 | +// that is still pending when the method returns makes the invocation longer, and billed. |
| 13 | +it('does not keep Durable Object invocations open after the method returns', async ({ signal }) => { |
| 14 | + // The tail worker must run in the same `wrangler dev` process to receive the tail events. |
| 15 | + const runner = createRunner(__dirname) |
| 16 | + .withWranglerArgs('--config', join(__dirname, 'wrangler-tail.jsonc')) |
| 17 | + .start(signal); |
| 18 | + |
| 19 | + await runner.makeRequest('get', '/fetch'); |
| 20 | + await runner.makeRequest('get', '/rpc'); |
| 21 | + await runner.makeRequest('get', '/alarm'); |
| 22 | + |
| 23 | + const { fetchInvocation, rpcInvocation, alarmInvocation } = await vi.waitFor( |
| 24 | + async () => { |
| 25 | + const invocations = (await runner.makeRequest<Invocation[]>('get', '/invocations')) ?? []; |
| 26 | + const result = { |
| 27 | + fetchInvocation: invocations.find(invocation => invocation.trigger === 'fetch'), |
| 28 | + rpcInvocation: invocations.find(invocation => invocation.trigger === 'ping'), |
| 29 | + alarmInvocation: invocations.find(invocation => invocation.trigger === 'alarm'), |
| 30 | + }; |
| 31 | + |
| 32 | + expect(result.fetchInvocation).toBeDefined(); |
| 33 | + expect(result.rpcInvocation).toBeDefined(); |
| 34 | + expect(result.alarmInvocation).toBeDefined(); |
| 35 | + |
| 36 | + return result; |
| 37 | + }, |
| 38 | + { timeout: 10_000, interval: 100 }, |
| 39 | + ); |
| 40 | + |
| 41 | + // An invocation takes a few ms locally. The limit leaves room for slow CI machines and still |
| 42 | + // fails for a 500 ms timer. |
| 43 | + expect(fetchInvocation?.durationMs).toBeLessThan(250); |
| 44 | + expect(rpcInvocation?.durationMs).toBeLessThan(250); |
| 45 | + expect(alarmInvocation?.durationMs).toBeLessThan(250); |
| 46 | +}); |
0 commit comments