Skip to content
Merged
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
2 changes: 2 additions & 0 deletions kits/firestore-send-email/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
- fix: deploy `processQueue` with the extension's runtime settings: `concurrency: 1`, `cpu: "gcf_gen1"` (0.1666 vCPU at 256MiB) and `ingressSettings: "ALLOW_INTERNAL_ONLY"`. `setGlobalOptions` can't change these. Before, the kit took the 2nd gen defaults of concurrency `80`, 1 vCPU and `ALLOW_ALL`. A burst of mail with attachments landed on one 256MiB instance, which ran out of memory and dropped every event in flight on it: the documents were left in `PENDING` or `PROCESSING`, or with no `delivery` field, and were never retried or marked as failed, so the mail was never sent. Existing kit deployments switch on their next deploy.

- fix: an Eventarc publish failure no longer fails the function. A channel that was deleted or is unreachable answers `PERMISSION_DENIED`, and the publish was awaited before the work the function exists to do, so the mail was never sent. The publish failure is now logged as a warning and the invocation continues. Deploys also declare `eventarcpublishing.googleapis.com`, so the API is enabled on your project whether or not you use events.

- docs: the no-region fallback needs an explicit empty `DATABASE_REGION=` line in `.env`. Omitting the key entirely fails a non-interactive deploy, because the CLI resolves parameters before it reads their defaults. Corrects the note on the `DATABASE_REGION` mapping fix below; no behavior change.
Expand Down
5 changes: 5 additions & 0 deletions kits/firestore-send-email/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@ a `TypeError` about reading `attachments` into `delivery.error`. It now writes
- SendGrid is still selected by an `smtp.sendgrid.net` connection URI with the
API key in `SMTP_PASSWORD`, and Outlook hosts still get their explicit
transport configuration.
- The function still runs like the extension's: 0.1666 vCPU
(`cpu: "gcf_gen1"`), one event per instance (`concurrency: 1`) and
internal-only ingress, rather than the 2nd gen defaults of 1 vCPU,
concurrency `80` and `ALLOW_ALL`, so a burst of mail scales out across
instances instead of sharing one. `setGlobalOptions` can't change these.
- The function still runs with a 120 second timeout, and `TLS_OPTIONS`,
`DATABASE`, `USERS_COLLECTION` and `TEMPLATES_COLLECTION` behave as before.

Expand Down
9 changes: 9 additions & 0 deletions kits/firestore-send-email/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,15 @@ function ensureInitialized(): Promise<HandlerContext> {
export const processQueue = onDocumentWritten(
{
...(deploy.region ? { region: deploy.region } : {}),
// The extension ran this function at 0.1666 vCPU, one event per instance,
// with internal-only ingress. Left unset, the CLI deploys the 2nd gen
// defaults: 1 vCPU, concurrency 80 and `ALLOW_ALL`. At concurrency 80, a
// burst of mail with attachments lands on one 256MiB instance, which runs
// out of memory and drops every event in flight on it. The trigger has no
// retry policy, so that mail is never sent.
concurrency: 1,
cpu: "gcf_gen1",
ingressSettings: "ALLOW_INTERNAL_ONLY",
document: deploy.document,
database: deploy.database,
timeoutSeconds: 120,
Expand Down
9 changes: 9 additions & 0 deletions kits/firestore-send-email/tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,13 @@ describe("processQueue options", () => {
const document = options.document as { toCEL(): string };
expect(document.toCEL()).toContain("params.MAIL_COLLECTION");
});

// Concurrency 80 let a burst of mail with attachments land on one 256MiB
// instance, which ran out of memory and dropped it.
test("the function runs one event per gen1 CPU instance with internal-only ingress", async () => {
const options = await loadTriggerOptions();
expect(options.concurrency).toBe(1);
expect(options.cpu).toBe("gcf_gen1");
expect(options.ingressSettings).toBe("ALLOW_INTERNAL_ONLY");
});
});
Loading