UNPKG

inngest

Version:

Official SDK for Inngest.com. Inngest is the reliability layer for modern applications. Inngest combines durable execution, events, and queues into a zero-infra platform with built-in observability.

93 lines (91 loc) 3.34 kB
const require_consts = require('../../helpers/consts.cjs'); const require_connect = require('../../proto/src/components/connect/protobuf/connect.cjs'); const require_util = require('./util.cjs'); //#region src/components/connect/buffer.ts var MessageBuffer = class { buffered = {}; pending = {}; getApiBaseUrl; logger; envName; constructor({ envName, getApiBaseUrl, logger }) { this.envName = envName; this.getApiBaseUrl = getApiBaseUrl; this.logger = logger; } append(requestId, responseBytes) { this.buffered[requestId] = responseBytes; delete this.pending[requestId]; } addPending(requestId, responseBytes, deadline) { this.pending[requestId] = responseBytes; setTimeout(() => { if (this.pending[requestId]) { this.logger.warn({ requestId }, "Message not acknowledged in time"); this.append(requestId, this.pending[requestId]); } }, deadline); } acknowledgePending(requestId) { delete this.pending[requestId]; } async sendFlushRequest(hashedSigningKey, responseBytes) { const headers = { "Content-Type": "application/protobuf", ...hashedSigningKey ? { Authorization: `Bearer ${hashedSigningKey}` } : {} }; if (this.envName) headers[require_consts.headerKeys.Environment] = this.envName; if (!isUnsharedArrayBuffer(responseBytes)) throw new Error("Unreachable: response bytes are not an ArrayBuffer"); const resp = await fetch(new URL("/v0/connect/flush", await this.getApiBaseUrl()), { method: "POST", body: responseBytes, headers }); if (!resp.ok) { this.logger.error({ body: await resp.text(), status: resp.status }, "Failed to flush messages"); throw new Error("Failed to flush messages"); } return require_connect.FlushResponse.decode(new Uint8Array(await resp.arrayBuffer())); } async flush(hashedSigningKey) { if (Object.keys(this.buffered).length === 0) return; this.logger.info({ count: Object.keys(this.buffered).length }, "Flushing messages"); const maxAttempts = 5; for (let attempt = 0; attempt < maxAttempts; attempt++) { for (const [requestId, v] of Object.entries(this.buffered)) try { await this.sendFlushRequest(hashedSigningKey, v); delete this.buffered[requestId]; } catch (err) { this.logger.warn({ err, requestId }, "Failed to flush message"); break; } if (Object.keys(this.buffered).length === 0) return; await new Promise((resolve) => setTimeout(resolve, require_util.expBackoff(attempt))); } this.logger.error({ maxAttempts }, "Failed to flush messages after max attempts"); } }; function isUnsharedArrayBuffer(value) { if (typeof SharedArrayBuffer === "undefined") return true; return value.buffer instanceof ArrayBuffer; } /** * Throws an error if the value is not an unshared ArrayBuffer. This should be * safe because we shouldn't be using `SharedArrayBuffer` at runtime, but our * protobuf types have `Uint8Array` as the return type (no generic), which * effectively defaults to a union of `ArrayBuffer` and `SharedArrayBuffer`. */ function ensureUnsharedArrayBuffer(value) { if (!isUnsharedArrayBuffer(value)) throw new Error("Unreachable: response bytes are not an ArrayBuffer"); return value; } //#endregion exports.MessageBuffer = MessageBuffer; exports.ensureUnsharedArrayBuffer = ensureUnsharedArrayBuffer; //# sourceMappingURL=buffer.cjs.map