diff --git a/pages/docs/examples/cleanup-after-function-cancellation.mdx b/pages/docs/examples/cleanup-after-function-cancellation.mdx new file mode 100644 index 000000000..2e6b7a6c9 --- /dev/null +++ b/pages/docs/examples/cleanup-after-function-cancellation.mdx @@ -0,0 +1,114 @@ +import { ResourceGrid, Resource } from 'src/shared/Docs/Resources'; + +import { RiBracesFill, RiErrorWarningFill } from "@remixicon/react"; + +export const description = "Create a function that executes after a function run has been cancelled via event, REST API, or bulk cancellation."; + +# Cleanup after function cancellation + +When function runs are cancelled, you may want to perform some sort of post-cancellation code. This example will use the [`inngest/function.cancelled`](/docs/reference/system-events/inngest-function-cancelled) system event. + +Whether your function run is cancelled via [`cancelOn` event](/docs/features/inngest-functions/cancellation/cancel-on-events), [REST API](/docs/guides/cancel-running-functions) or [bulk cancellation](/docs/platform/manage/bulk-cancellation), this method will work the same. + +## Quick snippet + +Here is an Inngest function and a corresponding function that will be run whenever the original function is cancelled. This uses the function trigger's `if` parameter to filter the `inngest/function.cancelled` event to only be triggered for the original function. + +```ts +const inngest = new Inngest({ id: "newsletter-app" }); + +// This is our "import" function that will get cancelled +export const importAllContacts = inngest.createFunction( + { + id: "import-all-contacts", + cancelOn: [{ event: "contacts/import.cancelled", if: "async.data.importId == event.data.importId" }] + }, + { event: "contacts/import.requested" }, + async ({ event, step }) => { + // This is a long running function + } +) + +// This function will be run only when the matching function_id has a run that is cancelled +export const cleanupCancelledImport = inngest.createFunction( + { + name: "Cleanup cancelled import", + id: "cleanup-cancelled-import" + }, + { + event: "inngest/function.cancelled", + // The function ID is a hyphenated slug of the App ID w/ the functions" id + if: "event.data.function_id == 'newsletter-app-import-all-contacts'" + }, + async ({ event, step, logger }) => { + // This code will execute after your function is cancelled + + // The event that triggered our original function run is passed nested in our event payload + const originalTriggeringEvent = event.data.event; + logger.info(`Import was cancelled: ${originalTriggeringEvent.data.importId}`) + } +); +``` + +An example cancellation event payload: + +```json +{ + "name": "inngest/function.cancelled", + "data": { + "error": { + "error": "function cancelled", + "message": "function cancelled", + "name": "Error" + }, + "event": { + "data": { + "importId": "bdce1b1b-6e3a-43e6-84c2-2deb559cdde6" + }, + "id": "01JDJK451Y9KFGE5TTM2FHDEDN", + "name": "contacts/import.requested", + "ts": 1732558407003, + "user": {} + }, + "events": [ + { + "data": { + "importId": "bdce1b1b-6e3a-43e6-84c2-2deb559cdde6" + }, + "id": "01JDJK451Y9KFGE5TTM2FHDEDN", + "name": "contacts/import.requested", + "ts": 1732558407003, + "user": {} + } + ], + "function_id": "newsletter-app-import-all-contacts", + "run_id": "01JDJKGTGDVV4DTXHY6XYB7BKK" + }, + "id": "01JDJKH1S5P2YER8PKXPZJ1YZJ", + "ts": 1732570023717 +} +``` + +## More context + +Check the resources below to learn more about building email sequences with Inngest. + + + + + + + + \ No newline at end of file diff --git a/pages/docs/examples/track-failures-in-datadog.mdx b/pages/docs/examples/track-failures-in-datadog.mdx index 583e1733e..07baeff8b 100644 --- a/pages/docs/examples/track-failures-in-datadog.mdx +++ b/pages/docs/examples/track-failures-in-datadog.mdx @@ -1,5 +1,4 @@ import { ResourceGrid, Resource } from 'src/shared/Docs/Resources'; -import { Example } from 'src/shared/Docs/Examples'; import { RiBracesFill, RiErrorWarningFill } from "@remixicon/react"; @@ -102,7 +101,7 @@ Check the resources below to learn more about building email sequences with Inng diff --git a/pages/docs/features/inngest-functions/cancellation.mdx b/pages/docs/features/inngest-functions/cancellation.mdx index ce92fa946..829ff8bb2 100644 --- a/pages/docs/features/inngest-functions/cancellation.mdx +++ b/pages/docs/features/inngest-functions/cancellation.mdx @@ -118,4 +118,10 @@ Let's now look at two different cancellations triggered from the Dashboard Bulk -All canceled Function runs can be replay by using the Platform's [Functions Replay UI](/docs/platform/replay). \ No newline at end of file +All canceled Function runs can be replay by using the Platform's [Functions Replay UI](/docs/platform/replay). + +## Handling cancelled functions + +Function runs that are cancelled may require additional work like database cleanup or purging of deletion of temporary resources. This can be done leveraging the [`inngest/function.cancelled`](/docs/reference/system-events/inngest-function-cancelled) system event. + +See [this complete example](/docs/examples/cleanup-after-function-cancellation) for how to use this event within your system to cleanup after a function run is cancelled. \ No newline at end of file diff --git a/pages/docs/features/inngest-functions/error-retries/failure-handlers.mdx b/pages/docs/features/inngest-functions/error-retries/failure-handlers.mdx index 737418860..9a4cda856 100644 --- a/pages/docs/features/inngest-functions/error-retries/failure-handlers.mdx +++ b/pages/docs/features/inngest-functions/error-retries/failure-handlers.mdx @@ -35,3 +35,6 @@ inngest.createFunction( ``` + + To handle cancelled function runs, checkout out [this example](/docs/examples/cleanup-after-function-cancellation) that uses the [`inngest/function.cancelled`](/docs/reference/system-events/inngest-function-cancelled) system event. + diff --git a/pages/docs/reference/system-events/inngest-function-cancelled.mdx b/pages/docs/reference/system-events/inngest-function-cancelled.mdx new file mode 100644 index 000000000..1309d1731 --- /dev/null +++ b/pages/docs/reference/system-events/inngest-function-cancelled.mdx @@ -0,0 +1,101 @@ +import { Callout, CodeGroup, Properties, Property, Row, Col, VersionBadge } from "src/shared/Docs/mdx"; + +# `inngest/function.cancelled` {{ className: "not-prose" }} + +The `inngest/function.cancelled` event is sent whenever any single function is cancelled in your [Inngest environment](/docs/platform/environments). The event will be sent if the event is cancelled via [`cancelOn` event](/docs/features/inngest-functions/cancellation/cancel-on-events), [REST API](/docs/guides/cancel-running-functions) or [bulk cancellation](/docs/platform/manage/bulk-cancellation). + +This event can be used to handle cleanup or similar for a single function or handle some sort of tracking function cancellations in some external system like Datadog. + + + You can write a function that uses the `"inngest/function.cancelled"` event with the optional `if` parameter to filter to specifically handle a single function by `function_id`. + + +## The event payload + + + + + + + The `inngest/` event prefix is reserved for system events in each environment. + + + The event payload data. + + + Data about the error payload as returned from the cancelled function. + + + The cancellation error, always `"function cancelled"` + + + The name of the error, defaulting to `"Error"`. + + + + + The cancelled function's original event payload. + + + The cancelled function's [`id`](/docs/reference/functions/create#configuration). + + + The cancelled function's [run ID](/docs/reference/functions/create#run-id). + + + + + The timestamp integer in milliseconds at which the cancellation occurred. + + + + + + +```json {{ title: "Example payload" }} +{ + "name": "inngest/function.cancelled", + "data": { + "error": { + "error": "function cancelled", + "message": "function cancelled", + "name": "Error" + }, + "event": { + "data": { + "content": "Yost LLC explicabo eos", + "transcript": "s3://product-ideas/carber-vac-release.txt", + "userId": "bdce1b1b-6e3a-43e6-84c2-2deb559cdde6" + }, + "id": "01JDJK451Y9KFGE5TTM2FHDEDN", + "name": "integrations/export.requested", + "ts": 1732558407003, + "user": {} + }, + "events": [ + { + "data": { + "content": "Yost LLC explicabo eos", + "transcript": "s3://product-ideas/carber-vac-release.txt", + "userId": "bdce1b1b-6e3a-43e6-84c2-2deb559cdde6" + }, + "id": "01JDJK451Y9KFGE5TTM2FHDEDN", + "name": "integrations/export.requested", + "ts": 1732558407003 + } + ], + "function_id": "demo-app-export", + "run_id": "01JDJKGTGDVV4DTXHY6XYB7BKK" + }, + "id": "01JDJKH1S5P2YER8PKXPZJ1YZJ", + "ts": 1732570023717 +} +``` + + + + + +## Related resources + +* [Example: Cleanup after function cancellation](/docs/examples/cleanup-after-function-cancellation) \ No newline at end of file diff --git a/shared/Docs/navigationStructure.ts b/shared/Docs/navigationStructure.ts index 096612183..57ed568e5 100644 --- a/shared/Docs/navigationStructure.ts +++ b/shared/Docs/navigationStructure.ts @@ -339,10 +339,15 @@ const sectionReference: NavGroup[] = [ title: "System events", links: [ { - title: "inngest/function.failed", + title: "function.failed", href: "/docs/reference/system-events/inngest-function-failed", className: "font-mono", }, + { + title: "function.cancelled", + href: "/docs/reference/system-events/inngest-function-cancelled", + className: "font-mono", + }, ], }, ]; @@ -886,6 +891,10 @@ const sectionExamples: NavGroup[] = [ title: "Track all function failures in Datadog", href: `/docs/examples/track-failures-in-datadog`, }, + { + title: "Cleanup after function cancellation", + href: `/docs/examples/cleanup-after-function-cancellation`, + }, ], }, ];