Skip to content

Commit 5255c47

Browse files
committed
perf(webapp): short-circuit mollifier gate when globally disabled
evaluateGate ran on every trigger regardless of TRIGGER_MOLLIFIER_ENABLED. With the flag off (the default everywhere it hasn't been opted in), the gate still produced a `pass_through` decision after allocating a GateInputs object, spreading defaultGateDependencies inside evaluateGate, and incrementing the `mollifier.decisions{outcome=pass_through}` OTel counter. Cheap individually, but triggerTask is the hottest code path in the system — multiply by trigger rate and the unnecessary work compounds. Guard the gate call with a direct env.TRIGGER_MOLLIFIER_ENABLED check at the call site. When the flag is off, mollifierOutcome is null and the downstream `mollifierOutcome?.action === "mollify"` branch skips the buffer dual-write entirely — zero allocation, zero counter increment on the disabled path. When the flag is on, behaviour is unchanged. Lost-signal note: with mollifier off, we no longer count "pass_through" decisions in the OTel counter (the gate never runs). That's a non-issue — "pass_through count when feature is off" is just total trigger rate, which is already observable via the trigger handler's own spans/counters upstream. The gate counter remains the source of truth for the mollify/shadow/pass_through ratio when the feature is on, which is the load-bearing signal.
1 parent f2f4ba6 commit 5255c47

1 file changed

Lines changed: 19 additions & 8 deletions

File tree

apps/webapp/app/runEngine/services/triggerTask.server.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ import type {
4040
TriggerTaskRequest,
4141
TriggerTaskValidator,
4242
} from "../types";
43+
import { env } from "~/env.server";
4344
import {
4445
evaluateGate as defaultEvaluateGate,
46+
type GateOutcome,
4547
type MollifierEvaluateGate,
4648
} from "~/v3/mollifier/mollifierGate.server";
4749
import {
@@ -335,13 +337,22 @@ export class RunEngineTriggerTaskService {
335337
taskKind: taskKind ?? "STANDARD",
336338
};
337339

338-
const mollifierOutcome = await this.evaluateGate({
339-
envId: environment.id,
340-
orgId: environment.organizationId,
341-
taskId,
342-
orgFeatureFlags:
343-
(environment.organization.featureFlags as Record<string, unknown> | null) ?? null,
344-
});
340+
// Short-circuit before the gate when mollifier is globally off (the
341+
// default for every deployment that hasn't opted in). Avoids the
342+
// GateInputs allocation, the deps spread inside `evaluateGate`, and
343+
// the `mollifier.decisions{outcome=pass_through}` OTel increment on
344+
// every trigger — `triggerTask` is the highest-throughput code path
345+
// in the system. When the flag is on, behaviour is unchanged.
346+
const mollifierOutcome: GateOutcome | null =
347+
env.TRIGGER_MOLLIFIER_ENABLED === "1"
348+
? await this.evaluateGate({
349+
envId: environment.id,
350+
orgId: environment.organizationId,
351+
taskId,
352+
orgFeatureFlags:
353+
(environment.organization.featureFlags as Record<string, unknown> | null) ?? null,
354+
})
355+
: null;
345356

346357
try {
347358
return await this.traceEventConcern.traceRun(
@@ -363,7 +374,7 @@ export class RunEngineTriggerTaskService {
363374
// dequeue mechanism works. Phase 2 will replace engine.trigger
364375
// (below) with a synthesised 200 response and rely on the
365376
// drainer to perform the Postgres write via replay.
366-
if (mollifierOutcome.action === "mollify") {
377+
if (mollifierOutcome?.action === "mollify") {
367378
const buffer = this.getMollifierBuffer();
368379
if (buffer) {
369380
const canonicalPayload = buildBufferedTriggerPayload({

0 commit comments

Comments
 (0)