From 7ce2dcb9122e0630108f26dc05ec883d685651c5 Mon Sep 17 00:00:00 2001 From: Tony Holdstock-Brown Date: Mon, 16 Oct 2023 13:10:24 -0700 Subject: [PATCH 1/4] Add function run priority docs --- pages/docs/reference/functions/create.mdx | 38 ++++++ .../docs/reference/functions/run-priority.mdx | 112 ++++++++++++++++++ shared/Docs/Navigation.tsx | 4 + 3 files changed, 154 insertions(+) create mode 100644 pages/docs/reference/functions/run-priority.mdx diff --git a/pages/docs/reference/functions/create.mdx b/pages/docs/reference/functions/create.mdx index 776f77fea..ed2220c09 100644 --- a/pages/docs/reference/functions/create.mdx +++ b/pages/docs/reference/functions/create.mdx @@ -75,6 +75,26 @@ The `createFunction` method accepts a series of arguments to define your functio + + Options to configure function debounce ([reference](/docs/reference/functions/debounce)) + + + The time period of which to set the limit. The period begins when the first matching event is received. + How long to wait before invoking the function with the batch even if it's not full. + Current permitted values are from `1s` to `7d` (`168h`). + + + A unique key expression to apply the debounce to. The expression is evaluated for each triggering event. + + Expressions are defined using the [Common Expression Language (CEL)](https://github.com/google/cel-go) with the original event accessible using dot-notation. Examples: + + * Debounce per customer id: `'event.data.customer_id'` + * Debounce per account and email address: `'event.data.account_id + "-" + event.user.email'` + + + + + Configure how the function should consume batches of events ([reference](/docs/guides/batching)) @@ -108,6 +128,24 @@ The `createFunction` method accepts a series of arguments to define your functio + + + + Options to configure how to prioritize functions + + + + An expression which must return an integer between -600 and 600 (by default), with higher + return values resulting in a higher priority. Examples: + + * Return the priority within an event directly: `event.data.priority` (where + `event.data.priority` is an int within your account's range) + * Rate limit by a string field: `event.data.plan == 'enterprise' ? 180 : 0` + + + + + {/* TODO - Document fns arg */} diff --git a/pages/docs/reference/functions/run-priority.mdx b/pages/docs/reference/functions/run-priority.mdx new file mode 100644 index 000000000..98971ec95 --- /dev/null +++ b/pages/docs/reference/functions/run-priority.mdx @@ -0,0 +1,112 @@ +# Function run priority + +Defining a function's run priority allows you to **prioritize specific function runs above other runs within the same function**. For example: + +- Given you have a single function +- And you initialize two function runs at the same time, A and B +- Function run priority allows you to run run B ahead of A + +This is useful to prioritize specific function runs, such as ensuring paid user's functions run ahead of free users when scheduled at similar times. + +```ts +export default inngest.createFunction( + { + id: "synchronize-data", + priority: { + // Allow runs to have a dynamic "factor" between -600 and 600. This changes + // the order of jobs in the queue; returning `120` means that this new run should + // execute before any jobs enqueued in the last 120 seconds (as it has a higher priority). + // + // Example: + // + // If two jobs are enqueued at time 150 (t150) with the following factors: + // + // - Job X: t150, factor 0 (no expression or data) + // - Job Y: t150, factor 120 + // + // Then Job Y will run ahead of Job X. Job Y will also run before any jobs scheduled + // 120 seconds beforehand. Visually: + // + // Jobs: [A, B, C, ] + // Priority/Time: [10, 40, 130] + // + // Becomes: + // + // Jobs: [A, Y, B, C, X] + // Priority/Time: [10, 30, 40, 130, 150] + // + // Job Y's score becomes 30 (t150 - 120 = 30), going before any other work except job A. + // + // NOTE: returning a negative number delays the function run's jobs by the given value + // in seconds. + run: "event.data.account_type == 'enterprise' ? 120 : 0", + }, + }, + { event: "intercom/company.updated" }, + async ({ event, step }) => { + } +); +``` + +## How `priority.run` works + +**The queue** + +Within Inngest, each function's scheduled runs is a prioirity queue scored by the time that jobs +should run. When you create new function runs by sending events, a new job is inserted into the +queue with a score of the current time (as a millisecond epoch). + +**Expressions** + +Any time a new function run is scheduled, Inngest evaluates the `priority.run` expression given +the input event's data. By default, this returns 0. + +For example, the expression `"event.data.plan == 'enterprise' ? 300 : 0"` may return 300 or 0. If +an event's `data.plan` field equals `enterprise`, the expression returns `300`. + +**Prioritization** + +We take the returning number from the expression, and subtract this from the function run's epoch +time (as seconds). Returning `300` subtracts 300 seconds from the function run's epoch time, +pushing the new run ahead of any other functions in the last 300 seconds (5 minutes). + +If two function runs are scheduled at similar times, the functions with a higher priority run sooner +when at capacity within a single function's concurrency limits. + +**Fairness** + +The expression defined within `priority.run` has a max return value of 600 by default, though this +can be increased upon request. + +That is, we only skew a function run's priority by up to 600 seconds. This ensures that you can +never starve work older than 600 seconds; the longer a run exists in the queue without work, +the more likely it is to be worked on. + +Using this model, it's impossible to stave work on lower priority items and functions always exhibit +some level of fairness. + +## Configuration + + + + Options to configure how to prioritize functions + + + + An expression which must return an integer between -600 and 600 (by default), with higher + return values resulting in a higher priority. Examples: + + * Return the priority within an event directly: `event.data.priority` (where + `event.data.priority` is an int within your account's range) + * Rate limit by a string field: `event.data.plan == 'enterprise' ? 180 : 0` + + + + + + + Return values outside of your account's range (by default, -600 to 600) will automatically be clipped + to your max bounts. + + An invalid expression will evaluate to 0, as in "no priority". + diff --git a/shared/Docs/Navigation.tsx b/shared/Docs/Navigation.tsx index ee16b7788..d1e7cb083 100644 --- a/shared/Docs/Navigation.tsx +++ b/shared/Docs/Navigation.tsx @@ -353,6 +353,10 @@ const referenceNavigation = [ title: "Debounce", href: `${baseDir}/reference/functions/debounce`, }, + { + title: "Function run priority", + href: `${baseDir}/reference/functions/run-priority`, + }, // { // title: "Logging", // href: `${baseDir}/reference/functions/logging`, From 9eceba8313a7bf86bec59c75f1519caa8f1a719d Mon Sep 17 00:00:00 2001 From: Tony Holdstock-Brown Date: Mon, 16 Oct 2023 13:18:56 -0700 Subject: [PATCH 2/4] Typo --- pages/docs/reference/functions/run-priority.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/docs/reference/functions/run-priority.mdx b/pages/docs/reference/functions/run-priority.mdx index 98971ec95..92e0e7a43 100644 --- a/pages/docs/reference/functions/run-priority.mdx +++ b/pages/docs/reference/functions/run-priority.mdx @@ -52,7 +52,7 @@ export default inngest.createFunction( **The queue** -Within Inngest, each function's scheduled runs is a prioirity queue scored by the time that jobs +Within Inngest, each function's scheduled runs is a priority queue scored by the time that jobs should run. When you create new function runs by sending events, a new job is inserted into the queue with a score of the current time (as a millisecond epoch). From 3a2694c3889f888d8196f83eb35f48a52ffdb88b Mon Sep 17 00:00:00 2001 From: Tony Holdstock-Brown Date: Mon, 16 Oct 2023 13:19:50 -0700 Subject: [PATCH 3/4] Simplify --- pages/docs/reference/functions/run-priority.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/docs/reference/functions/run-priority.mdx b/pages/docs/reference/functions/run-priority.mdx index 92e0e7a43..76b4d1462 100644 --- a/pages/docs/reference/functions/run-priority.mdx +++ b/pages/docs/reference/functions/run-priority.mdx @@ -71,7 +71,7 @@ time (as seconds). Returning `300` subtracts 300 seconds from the function run' pushing the new run ahead of any other functions in the last 300 seconds (5 minutes). If two function runs are scheduled at similar times, the functions with a higher priority run sooner -when at capacity within a single function's concurrency limits. +when at capacity. **Fairness** From 18494e60b838d5d68b6ff140783f5c73cc24d4b1 Mon Sep 17 00:00:00 2001 From: Tony Holdstock-Brown Date: Mon, 16 Oct 2023 13:20:32 -0700 Subject: [PATCH 4/4] Typo --- pages/docs/reference/functions/run-priority.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/docs/reference/functions/run-priority.mdx b/pages/docs/reference/functions/run-priority.mdx index 76b4d1462..e0dc1d614 100644 --- a/pages/docs/reference/functions/run-priority.mdx +++ b/pages/docs/reference/functions/run-priority.mdx @@ -106,7 +106,7 @@ some level of fairness. Return values outside of your account's range (by default, -600 to 600) will automatically be clipped - to your max bounts. + to your max bounds. An invalid expression will evaluate to 0, as in "no priority".