diff --git a/.server-changes/disable-postgres-task-event-writes.md b/.server-changes/disable-postgres-task-event-writes.md new file mode 100644 index 00000000000..47eb9ef9fd1 --- /dev/null +++ b/.server-changes/disable-postgres-task-event-writes.md @@ -0,0 +1,6 @@ +--- +area: webapp +type: feature +--- + +Added `EVENT_REPOSITORY_POSTGRES_WRITES_DISABLED` to skip all PostgreSQL task-event writes for deployments that store task events in ClickHouse. Leave it off unless `EVENT_REPOSITORY_DEFAULT_STORE` is `clickhouse_v2`, otherwise task events are lost. diff --git a/apps/webapp/app/env.server.ts b/apps/webapp/app/env.server.ts index 6dc6ccee3f2..0e2b5ab78fe 100644 --- a/apps/webapp/app/env.server.ts +++ b/apps/webapp/app/env.server.ts @@ -1828,6 +1828,7 @@ const EnvironmentSchema = z .enum(["postgres", "clickhouse", "clickhouse_v2"]) .default("postgres"), EVENT_REPOSITORY_DEBUG_LOGS_DISABLED: BoolEnv.default(false), + EVENT_REPOSITORY_POSTGRES_WRITES_DISABLED: BoolEnv.default(false), EVENTS_CLICKHOUSE_MAX_TRACE_SUMMARY_VIEW_COUNT: z.coerce.number().int().default(25_000), EVENTS_CLICKHOUSE_MAX_TRACE_DETAILED_SUMMARY_VIEW_COUNT: z.coerce.number().int().default(5_000), EVENTS_CLICKHOUSE_MAX_LIVE_RELOADING_SETTING: z.coerce.number().int().default(2000), diff --git a/apps/webapp/app/v3/eventRepository/eventRepository.server.ts b/apps/webapp/app/v3/eventRepository/eventRepository.server.ts index 2de5ce8b25a..ea778fb5356 100644 --- a/apps/webapp/app/v3/eventRepository/eventRepository.server.ts +++ b/apps/webapp/app/v3/eventRepository/eventRepository.server.ts @@ -157,14 +157,23 @@ export class EventRepository implements IEventRepository { } private async insertImmediate(event: CreateEventInput) { + if (env.EVENT_REPOSITORY_POSTGRES_WRITES_DISABLED) { + return; + } await this.#flushBatch(nanoid(), [this.#createableEventToPrismaEvent(event)]); } insertMany(events: CreateEventInput[]) { + if (env.EVENT_REPOSITORY_POSTGRES_WRITES_DISABLED) { + return; + } this._flushScheduler.addToBatch(events.map(this.#createableEventToPrismaEvent)); } async insertManyImmediate(events: CreateEventInput[]) { + if (env.EVENT_REPOSITORY_POSTGRES_WRITES_DISABLED) { + return; + } await this.#flushBatchWithReturn(nanoid(), events.map(this.#createableEventToPrismaEvent)); } @@ -1018,7 +1027,7 @@ export class EventRepository implements IEventRepository { if (options.immediate) { await this.insertImmediate(event); } else { - this._flushScheduler.addToBatch([this.#createableEventToPrismaEvent(event)]); + this.insertMany([event]); } } @@ -1152,7 +1161,7 @@ export class EventRepository implements IEventRepository { if (options.immediate) { await this.insertImmediate(event); } else { - this._flushScheduler.addToBatch([this.#createableEventToPrismaEvent(event)]); + this.insertMany([event]); } return result; diff --git a/docs/self-hosting/env/webapp.mdx b/docs/self-hosting/env/webapp.mdx index d4e8b16ff39..1f629718b52 100644 --- a/docs/self-hosting/env/webapp.mdx +++ b/docs/self-hosting/env/webapp.mdx @@ -135,6 +135,7 @@ mode: "wide" | `SERVER_OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` | No | 8192 | OTel span attribute value length limit. | | **Task events** | | | | | `EVENT_REPOSITORY_DEFAULT_STORE` | No | postgres | Where to store task events. Set to `clickhouse_v2` to store in ClickHouse (recommended for production). | +| `EVENT_REPOSITORY_POSTGRES_WRITES_DISABLED` | No | 0 | Skip all PostgreSQL task-event writes (set to `1`). Only enable when `EVENT_REPOSITORY_DEFAULT_STORE` is `clickhouse_v2`, otherwise task events are lost. | | **Realtime** | | | | | `REALTIME_STREAM_VERSION` | No | v1 | Stream version exposed to tasks via the `TRIGGER_REALTIME_STREAM_VERSION` variable. Distinct from `REALTIME_STREAMS_DEFAULT_VERSION`. One of `v1`, `v2`. | | `REALTIME_STREAM_MAX_LENGTH` | No | 1000 | Realtime stream max length. |