From 60f87621b7e397270d90c8d912a7fbe7c91292e3 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 6 Feb 2025 09:44:38 +0000 Subject: [PATCH] Deploy website - based on 6a086353287ed1a8f067c439ef71e458b017aa6d --- 404.html | 4 ++-- assets/js/{8fea3195.1ad8b74d.js => 8fea3195.fe9cea2e.js} | 2 +- .../{runtime~main.6ab1384f.js => runtime~main.2acff39f.js} | 2 +- docs.html | 4 ++-- docs/admin-functions.html | 4 ++-- docs/cli.html | 4 ++-- docs/cli/run.html | 4 ++-- docs/config.html | 4 ++-- docs/connection-string.html | 4 ++-- docs/contributing.html | 4 ++-- docs/cron.html | 4 ++-- docs/docker.html | 4 ++-- docs/error-handling.html | 4 ++-- docs/exponential-backoff.html | 4 ++-- docs/faq.html | 4 ++-- docs/forbidden-flags.html | 4 ++-- docs/glossary.html | 4 ++-- docs/installation.html | 4 ++-- docs/job-key.html | 4 ++-- docs/jobs-view.html | 4 ++-- docs/library.html | 4 ++-- docs/library/add-job.html | 4 ++-- docs/library/add-jobs.html | 4 ++-- docs/library/logger.html | 4 ++-- docs/library/queue.html | 7 ++++--- docs/library/run.html | 4 ++-- docs/performance.html | 4 ++-- docs/pro.html | 4 ++-- docs/pro/config.html | 4 ++-- docs/pro/migration.html | 4 ++-- docs/pro/recovery.html | 4 ++-- docs/project-status.html | 4 ++-- docs/requirements.html | 4 ++-- docs/scaling.html | 4 ++-- docs/schema.html | 4 ++-- docs/sql-add-job.html | 4 ++-- docs/support.html | 4 ++-- docs/tasks.html | 4 ++-- docs/techniques.html | 4 ++-- docs/typescript.html | 4 ++-- docs/uninstall.html | 4 ++-- docs/worker-events.html | 4 ++-- errors/peh.html | 4 ++-- index.html | 4 ++-- news.html | 4 ++-- news/2023-12-11-016-release.html | 4 ++-- news/archive.html | 4 ++-- news/tags.html | 4 ++-- news/tags/releases.html | 4 ++-- pricing.html | 4 ++-- releases.html | 4 ++-- search.html | 4 ++-- sponsors.html | 4 ++-- 53 files changed, 106 insertions(+), 105 deletions(-) rename assets/js/{8fea3195.1ad8b74d.js => 8fea3195.fe9cea2e.js} (54%) rename assets/js/{runtime~main.6ab1384f.js => runtime~main.2acff39f.js} (72%) diff --git a/404.html b/404.html index adf62448..8104d6c8 100644 --- a/404.html +++ b/404.html @@ -13,13 +13,13 @@ - +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

Three ants crawling atop the footer
- + \ No newline at end of file diff --git a/assets/js/8fea3195.1ad8b74d.js b/assets/js/8fea3195.fe9cea2e.js similarity index 54% rename from assets/js/8fea3195.1ad8b74d.js rename to assets/js/8fea3195.fe9cea2e.js index 8cb9c133..e3e78e8f 100644 --- a/assets/js/8fea3195.1ad8b74d.js +++ b/assets/js/8fea3195.fe9cea2e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkgraphile_worker=self.webpackChunkgraphile_worker||[]).push([[6961],{9916:(e,n,r)=>{r.d(n,{xA:()=>u,yg:()=>g});var t=r(3696);function a(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function o(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n=0||(a[r]=e[r]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=t.createContext({}),d=function(e){var n=t.useContext(s),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},u=function(e){var n=d(e.components);return t.createElement(s.Provider,{value:n},e.children)},p="mdxType",c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},y=t.forwardRef((function(e,n){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=d(r),y=a,g=p["".concat(s,".").concat(y)]||p[y]||c[y]||o;return r?t.createElement(g,i(i({ref:n},u),{},{components:r})):t.createElement(g,i({ref:n},u))}));function g(e,n){var r=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=y;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l[p]="string"==typeof e?e:a,i[1]=l;for(var d=2;d{r.r(n),r.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>d});var t=r(8102),a=(r(3696),r(9916));const o={title:"Library: queueing jobs",sidebar_position:65,sidebar_label:"Queueing jobs"},i=void 0,l={unversionedId:"library/queue",id:"library/queue",title:"Library: queueing jobs",description:"You can also use the graphile-worker library to queue jobs using one of the",source:"@site/docs/library/queue.md",sourceDirName:"library",slug:"/library/queue",permalink:"/docs/library/queue",draft:!1,editUrl:"https://github.com/graphile/worker/tree/main/website/docs/library/queue.md",tags:[],version:"current",sidebarPosition:65,frontMatter:{title:"Library: queueing jobs",sidebar_position:65,sidebar_label:"Queueing jobs"},sidebar:"tutorialSidebar",previous:{title:"Running jobs",permalink:"/docs/library/run"},next:{title:"addJob()",permalink:"/docs/library/add-job"}},s={},d=[{value:"makeWorkerUtils()",id:"makeworkerutils",level:2},{value:"WorkerUtilsOptions",id:"workerutilsoptions",level:2},{value:"WorkerUtils",id:"workerutils",level:2},{value:"addJobAdhoc()",id:"addjobadhoc",level:2}],u={toc:d},p="wrapper";function c(e){let{components:n,...r}=e;return(0,a.yg)(p,(0,t.A)({},u,r,{components:n,mdxType:"MDXLayout"}),(0,a.yg)("p",null,"You can also use the ",(0,a.yg)("inlineCode",{parentName:"p"},"graphile-worker")," library to queue jobs using one of the\nfollowing APIs."),(0,a.yg)("p",null,"NOTE: although running the worker will automatically install its schema, the\nsame is not true for queuing jobs. You must ensure that the worker database\nschema is installed before you attempt to enqueue a job; you can install the\ndatabase schema into your database with the following command:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},'yarn graphile-worker -c "postgres:///my_db" --schema-only\n')),(0,a.yg)("p",null,"Alternatively you can use the ",(0,a.yg)("inlineCode",{parentName:"p"},"WorkerUtils")," migrate method:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"await workerUtils.migrate();\n")),(0,a.yg)("h2",{id:"makeworkerutils"},(0,a.yg)("inlineCode",{parentName:"h2"},"makeWorkerUtils()")),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-ts"},"function makeWorkerUtils(options: WorkerUtilsOptions): Promise;\n")),(0,a.yg)("p",null,"Useful for adding jobs from within JavaScript in an efficient way."),(0,a.yg)("p",null,"Runnable example:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-js"},'const { makeWorkerUtils } = require("graphile-worker");\n\nasync function main() {\n const workerUtils = await makeWorkerUtils({\n connectionString: "postgres:///my_db",\n });\n try {\n await workerUtils.migrate();\n\n await workerUtils.addJob(\n // Task identifier\n "calculate-life-meaning",\n\n // Payload\n { value: 42 },\n\n // Optionally, add further task spec details here\n );\n\n // await workerUtils.addJob(...);\n // await workerUtils.addJob(...);\n // await workerUtils.addJob(...);\n } finally {\n await workerUtils.release();\n }\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n')),(0,a.yg)("p",null,"We recommend building one instance of ",(0,a.yg)("inlineCode",{parentName:"p"},"WorkerUtils")," and sharing it as a\nsingleton throughout your code."),(0,a.yg)("h2",{id:"workerutilsoptions"},(0,a.yg)("inlineCode",{parentName:"h2"},"WorkerUtilsOptions")),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},"exactly one of these keys must be present to determine how to connect to the\ndatabase:",(0,a.yg)("ul",{parentName:"li"},(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"connectionString"),": A PostgreSQL\n",(0,a.yg)("a",{parentName:"li",href:"/docs/connection-string"},"connection string")," to the database containing the\njob queue, or"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"pgPool"),": A ",(0,a.yg)("inlineCode",{parentName:"li"},"pg.Pool")," instance to use"))),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"schema")," can be used to change the default ",(0,a.yg)("inlineCode",{parentName:"li"},"graphile_worker")," schema to\nsomething else (equivalent to ",(0,a.yg)("inlineCode",{parentName:"li"},"--schema")," on the CLI)")),(0,a.yg)("h2",{id:"workerutils"},(0,a.yg)("inlineCode",{parentName:"h2"},"WorkerUtils")),(0,a.yg)("p",null,"A ",(0,a.yg)("inlineCode",{parentName:"p"},"WorkerUtils")," instance has the following methods:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"addJob(name: string, payload: JSON, spec: TaskSpec)")," ","\u2014"," a method you can\ncall to enqueue a job, see ",(0,a.yg)("a",{parentName:"li",href:"/docs/library/add-job"},"addJob"),"."),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"migrate()")," ","\u2014"," a method you can call to update the graphile-worker\ndatabase schema; returns a promise."),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"release()")," ","\u2014"," call this to release the ",(0,a.yg)("inlineCode",{parentName:"li"},"WorkerUtils")," instance. It","'","s\ntypically best to use ",(0,a.yg)("inlineCode",{parentName:"li"},"WorkerUtils")," as a singleton, so you often won","'","t\nneed this, but it","'","s useful for tests or processes where you want Node to\nexit cleanly when it","'","s done.")),(0,a.yg)("h2",{id:"addjobadhoc"},(0,a.yg)("inlineCode",{parentName:"h2"},"addJobAdhoc()")),(0,a.yg)("admonition",{type:"info"},(0,a.yg)("p",{parentName:"admonition"},"This was called ",(0,a.yg)("inlineCode",{parentName:"p"},"quickAddJob()")," in Graphile Worker up until v0.16.x, but was\nrenamed to ",(0,a.yg)("inlineCode",{parentName:"p"},"addJobAdHoc()")," in v0.17.")),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-ts"},"function addJobAdhoc(options: WorkerUtilsOptions, ...addJobArgs): Promise;\n")),(0,a.yg)("p",null,"If you want to quickly add a job and you don","'","t mind the cost of opening a\nDB connection pool and then cleaning it up right away ",(0,a.yg)("em",{parentName:"p"},"for every job added"),",\nthere","'","s the ",(0,a.yg)("inlineCode",{parentName:"p"},"addJobAdhoc")," convenience function. It takes the same options\nas ",(0,a.yg)("inlineCode",{parentName:"p"},"makeWorkerUtils")," as the first argument; the remaining arguments are for\n",(0,a.yg)("a",{parentName:"p",href:"/docs/library/add-job"},(0,a.yg)("inlineCode",{parentName:"a"},"addJob")),"."),(0,a.yg)("admonition",{type:"tip"},(0,a.yg)("p",{parentName:"admonition"},"You are recommended to use ",(0,a.yg)("inlineCode",{parentName:"p"},"makeWorkerUtils")," instead where possible, but in\none-off scripts this convenience method may be enough.")),(0,a.yg)("p",null,"Runnable example:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-js"},'const { addJobAdhoc } = require("graphile-worker");\n\nasync function main() {\n await addJobAdhoc(\n // makeWorkerUtils options\n { connectionString: "postgres:///my_db" },\n\n // Task identifier\n "calculate-life-meaning",\n\n // Payload\n { value: 42 },\n\n // Optionally, add further task spec details here\n );\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkgraphile_worker=self.webpackChunkgraphile_worker||[]).push([[6961],{9916:(e,n,r)=>{r.d(n,{xA:()=>p,yg:()=>m});var t=r(3696);function a(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function o(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n=0||(a[r]=e[r]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=t.createContext({}),d=function(e){var n=t.useContext(s),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},p=function(e){var n=d(e.components);return t.createElement(s.Provider,{value:n},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},g=t.forwardRef((function(e,n){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=d(r),g=a,m=u["".concat(s,".").concat(g)]||u[g]||c[g]||o;return r?t.createElement(m,i(i({ref:n},p),{},{components:r})):t.createElement(m,i({ref:n},p))}));function m(e,n){var r=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=g;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l[u]="string"==typeof e?e:a,i[1]=l;for(var d=2;d{r.r(n),r.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>d});var t=r(8102),a=(r(3696),r(9916));const o={title:"Library: queueing jobs",sidebar_position:65,sidebar_label:"Queueing jobs"},i=void 0,l={unversionedId:"library/queue",id:"library/queue",title:"Library: queueing jobs",description:"You can also use the graphile-worker library to queue jobs using one of the",source:"@site/docs/library/queue.md",sourceDirName:"library",slug:"/library/queue",permalink:"/docs/library/queue",draft:!1,editUrl:"https://github.com/graphile/worker/tree/main/website/docs/library/queue.md",tags:[],version:"current",sidebarPosition:65,frontMatter:{title:"Library: queueing jobs",sidebar_position:65,sidebar_label:"Queueing jobs"},sidebar:"tutorialSidebar",previous:{title:"Running jobs",permalink:"/docs/library/run"},next:{title:"addJob()",permalink:"/docs/library/add-job"}},s={},d=[{value:"makeWorkerUtils()",id:"makeworkerutils",level:2},{value:"WorkerUtilsOptions",id:"workerutilsoptions",level:2},{value:"WorkerUtils",id:"workerutils",level:2},{value:"addJobAdhoc()",id:"addjobadhoc",level:2}],p={toc:d},u="wrapper";function c(e){let{components:n,...r}=e;return(0,a.yg)(u,(0,t.A)({},p,r,{components:n,mdxType:"MDXLayout"}),(0,a.yg)("p",null,"You can also use the ",(0,a.yg)("inlineCode",{parentName:"p"},"graphile-worker")," library to queue jobs using one of the\nfollowing APIs."),(0,a.yg)("p",null,"NOTE: although running the worker will automatically install its schema, the\nsame is not true for queuing jobs. You must ensure that the worker database\nschema is installed before you attempt to enqueue a job; you can install the\ndatabase schema into your database with the following command:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},'yarn graphile-worker -c "postgres:///my_db" --schema-only\n')),(0,a.yg)("p",null,"Alternatively you can use the ",(0,a.yg)("inlineCode",{parentName:"p"},"WorkerUtils")," migrate method:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"await workerUtils.migrate();\n")),(0,a.yg)("h2",{id:"makeworkerutils"},(0,a.yg)("inlineCode",{parentName:"h2"},"makeWorkerUtils()")),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-ts"},"function makeWorkerUtils(options: WorkerUtilsOptions): Promise;\n")),(0,a.yg)("p",null,"Useful for adding jobs from within JavaScript in an efficient way."),(0,a.yg)("p",null,"Runnable example:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-js"},'const { makeWorkerUtils } = require("graphile-worker");\n\nasync function main() {\n const workerUtils = await makeWorkerUtils({\n connectionString: "postgres:///my_db",\n });\n try {\n await workerUtils.migrate();\n\n await workerUtils.addJob(\n // Task identifier\n "calculate-life-meaning",\n\n // Payload\n { value: 42 },\n\n // Optionally, add further task spec details here\n );\n\n // await workerUtils.addJob(...);\n // await workerUtils.addJob(...);\n // await workerUtils.addJob(...);\n } finally {\n await workerUtils.release();\n }\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n')),(0,a.yg)("p",null,"We recommend building one instance of ",(0,a.yg)("inlineCode",{parentName:"p"},"WorkerUtils")," and sharing it as a\nsingleton throughout your code."),(0,a.yg)("h2",{id:"workerutilsoptions"},(0,a.yg)("inlineCode",{parentName:"h2"},"WorkerUtilsOptions")),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},"exactly one of these keys must be present to determine how to connect to the\ndatabase:",(0,a.yg)("ul",{parentName:"li"},(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"connectionString"),": A PostgreSQL\n",(0,a.yg)("a",{parentName:"li",href:"/docs/connection-string"},"connection string")," to the database containing the\njob queue, or"),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"pgPool"),": A ",(0,a.yg)("inlineCode",{parentName:"li"},"pg.Pool")," instance to use"))),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"schema")," can be used to change the default ",(0,a.yg)("inlineCode",{parentName:"li"},"graphile_worker")," schema to\nsomething else (equivalent to ",(0,a.yg)("inlineCode",{parentName:"li"},"--schema")," on the CLI)")),(0,a.yg)("admonition",{type:"warning"},(0,a.yg)("mdxAdmonitionTitle",{parentName:"admonition"},"If you use ",(0,a.yg)("inlineCode",{parentName:"mdxAdmonitionTitle"},"pgPool"),", ensure it has error handlers!"),(0,a.yg)("p",{parentName:"admonition"},"If your ",(0,a.yg)("inlineCode",{parentName:"p"},"pgPool")," doesn't have error handlers then connection issues with the\ndatabase may cause your Worker process to exit prematurely."),(0,a.yg)("pre",{parentName:"admonition"},(0,a.yg)("code",{parentName:"pre",className:"language-ts"},'import { Pool } from "pg";\nconst pool = new Pool({\n /* ... */\n});\n\n/* highlight-start */\n// No action necessary\nfunction handleError() {}\npool.on("error", handleError);\npool.on("connect", (client) => void client.on("error", handleError));\n/* highlight-end */\n'))),(0,a.yg)("h2",{id:"workerutils"},(0,a.yg)("inlineCode",{parentName:"h2"},"WorkerUtils")),(0,a.yg)("p",null,"A ",(0,a.yg)("inlineCode",{parentName:"p"},"WorkerUtils")," instance has the following methods:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"addJob(name: string, payload: JSON, spec: TaskSpec)")," ","\u2014"," a method you can\ncall to enqueue a job, see ",(0,a.yg)("a",{parentName:"li",href:"/docs/library/add-job"},"addJob"),"."),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"migrate()")," ","\u2014"," a method you can call to update the graphile-worker\ndatabase schema; returns a promise."),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"release()")," ","\u2014"," call this to release the ",(0,a.yg)("inlineCode",{parentName:"li"},"WorkerUtils")," instance. It","'","s\ntypically best to use ",(0,a.yg)("inlineCode",{parentName:"li"},"WorkerUtils")," as a singleton, so you often won","'","t\nneed this, but it","'","s useful for tests or processes where you want Node to\nexit cleanly when it","'","s done.")),(0,a.yg)("h2",{id:"addjobadhoc"},(0,a.yg)("inlineCode",{parentName:"h2"},"addJobAdhoc()")),(0,a.yg)("admonition",{type:"info"},(0,a.yg)("p",{parentName:"admonition"},"This was called ",(0,a.yg)("inlineCode",{parentName:"p"},"quickAddJob()")," in Graphile Worker up until v0.16.x, but was\nrenamed to ",(0,a.yg)("inlineCode",{parentName:"p"},"addJobAdHoc()")," in v0.17.")),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-ts"},"function addJobAdhoc(options: WorkerUtilsOptions, ...addJobArgs): Promise;\n")),(0,a.yg)("p",null,"If you want to quickly add a job and you don","'","t mind the cost of opening a\nDB connection pool and then cleaning it up right away ",(0,a.yg)("em",{parentName:"p"},"for every job added"),",\nthere","'","s the ",(0,a.yg)("inlineCode",{parentName:"p"},"addJobAdhoc")," convenience function. It takes the same options\nas ",(0,a.yg)("inlineCode",{parentName:"p"},"makeWorkerUtils")," as the first argument; the remaining arguments are for\n",(0,a.yg)("a",{parentName:"p",href:"/docs/library/add-job"},(0,a.yg)("inlineCode",{parentName:"a"},"addJob")),"."),(0,a.yg)("admonition",{type:"tip"},(0,a.yg)("p",{parentName:"admonition"},"You are recommended to use ",(0,a.yg)("inlineCode",{parentName:"p"},"makeWorkerUtils")," instead where possible, but in\none-off scripts this convenience method may be enough.")),(0,a.yg)("p",null,"Runnable example:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-js"},'const { addJobAdhoc } = require("graphile-worker");\n\nasync function main() {\n await addJobAdhoc(\n // makeWorkerUtils options\n { connectionString: "postgres:///my_db" },\n\n // Task identifier\n "calculate-life-meaning",\n\n // Payload\n { value: 42 },\n\n // Optionally, add further task spec details here\n );\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.6ab1384f.js b/assets/js/runtime~main.2acff39f.js similarity index 72% rename from assets/js/runtime~main.6ab1384f.js rename to assets/js/runtime~main.2acff39f.js index e7def994..a7eb3076 100644 --- a/assets/js/runtime~main.6ab1384f.js +++ b/assets/js/runtime~main.2acff39f.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,b,c,d,r={},t={};function f(e){var a=t[e];if(void 0!==a)return a.exports;var b=t[e]={id:e,loaded:!1,exports:{}};return r[e].call(b.exports,b,b.exports,f),b.loaded=!0,b.exports}f.m=r,f.c=t,e=[],f.O=(a,b,c,d)=>{if(!b){var r=1/0;for(i=0;i=d)&&Object.keys(f.O).every((e=>f.O[e](b[o])))?b.splice(o--,1):(t=!1,d0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[b,c,d]},f.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return f.d(a,{a:a}),a},b=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,f.t=function(e,c){if(1&c&&(e=this(e)),8&c)return e;if("object"==typeof e&&e){if(4&c&&e.__esModule)return e;if(16&c&&"function"==typeof e.then)return e}var d=Object.create(null);f.r(d);var r={};a=a||[null,b({}),b([]),b(b)];for(var t=2&c&&e;"object"==typeof t&&!~a.indexOf(t);t=b(t))Object.getOwnPropertyNames(t).forEach((a=>r[a]=()=>e[a]));return r.default=()=>e,f.d(d,r),d},f.d=(e,a)=>{for(var b in a)f.o(a,b)&&!f.o(e,b)&&Object.defineProperty(e,b,{enumerable:!0,get:a[b]})},f.f={},f.e=e=>Promise.all(Object.keys(f.f).reduce(((a,b)=>(f.f[b](e,a),a)),[])),f.u=e=>"assets/js/"+({696:"aa336e66",715:"dbb55107",730:"36fb0842",968:"04d1181f",979:"86d1797f",1278:"6a2efc62",1377:"9f33cc29",1416:"d9e16301",1459:"4d54d076",1633:"64a7a4a8",1755:"b9fe55b0",1827:"60e883a5",1856:"77e86a01",1975:"2cea4aaa",2138:"1a4e3797",2404:"b7ae13b2",2560:"0df6bfdc",2612:"99c8a2bc",2626:"3e8b85aa",2634:"c4f5d8e4",2635:"548347c6",2644:"bf89c9e9",2711:"9e4087bc",2830:"71849617",2926:"6b6dabe5",3249:"ccc49370",3624:"edefc60b",3880:"6afb3535",4421:"478990e4",4813:"6875c492",4877:"57b29698",4900:"f8d72259",5139:"8644cb3d",5215:"709fdcb1",5742:"c377a04b",5950:"9225b3a9",6061:"1f391b9e",6087:"47a5dbed",6103:"1be6b01a",6802:"5ed3387d",6803:"3b8c55ea",6879:"e8ca61e3",6961:"8fea3195",6963:"a2b339b6",7051:"e747ec83",7452:"08bd72b4",7643:"a6aa9e1f",7667:"81482700",7995:"4912050a",8042:"5cab3a8d",8070:"0480b142",8198:"be94c875",8209:"01a85c17",8269:"0874a7d3",8349:"7fef215d",8401:"17896441",8412:"00a09c75",8449:"32a77d0d",8458:"93234bd6",8581:"935f2afb",8714:"1be78505",8829:"605ee76d",9174:"913a5992",9391:"3a920b14",9504:"e383ab1f",9976:"7760e989"}[e]||e)+"."+{696:"bcf8138c",715:"a25ead7a",730:"f98aa84f",968:"6f78d418",979:"68838d05",1278:"7bee4576",1377:"66871fe9",1416:"fb7d33d5",1459:"e3b38fed",1633:"0c7930b2",1755:"0075b706",1827:"c6f83d4e",1840:"4043649c",1856:"68da7da4",1975:"57f90927",2138:"2c4eaae3",2404:"e9e9924c",2560:"6ff23cdf",2612:"a1fb85c5",2626:"f909d1c0",2634:"b97ebbac",2635:"64e08e5c",2644:"7c77a941",2711:"4753d0f7",2830:"ccc5ccc2",2926:"6a377d10",3059:"7b612210",3249:"c32f64b0",3624:"5bb8ac42",3880:"99971cff",4384:"44626fef",4421:"a840539c",4813:"a4c045be",4877:"0911f86f",4900:"bc6de2e1",5139:"1b64ca13",5215:"320a3444",5742:"9909d420",5882:"5e20e438",5950:"986abb4c",6061:"a0d8fed6",6087:"7370376a",6103:"59aac459",6802:"7a9a8f76",6803:"2a55e6e2",6879:"98e13299",6961:"1ad8b74d",6963:"8054ca37",7051:"0865ee8c",7452:"cf5924b4",7643:"56538353",7667:"5b7b51af",7995:"00855d19",8042:"35942a8e",8070:"7bda4ba0",8198:"509f77ab",8209:"5af7ecc7",8269:"329b5f6d",8349:"b7827d86",8401:"3308733a",8412:"b2b49fbc",8449:"3dd739ee",8458:"bea62163",8581:"0b659b2b",8714:"b3991eaf",8829:"aa0eff55",8973:"d3b528f9",9074:"97917598",9174:"0e8b4caf",9391:"d0ff6568",9504:"070ea7a2",9976:"4ae527e9"}[e]+".js",f.miniCssF=e=>{},f.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),f.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),c={},d="graphile-worker:",f.l=(e,a,b,r)=>{if(c[e])c[e].push(a);else{var t,o;if(void 0!==b)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var d=c[e];if(delete c[e],t.parentNode&&t.parentNode.removeChild(t),d&&d.forEach((e=>e(b))),a)return a(b)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=u.bind(null,t.onerror),t.onload=u.bind(null,t.onload),o&&document.head.appendChild(t)}},f.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.p="/",f.gca=function(e){return e={17896441:"8401",71849617:"2830",81482700:"7667",aa336e66:"696",dbb55107:"715","36fb0842":"730","04d1181f":"968","86d1797f":"979","6a2efc62":"1278","9f33cc29":"1377",d9e16301:"1416","4d54d076":"1459","64a7a4a8":"1633",b9fe55b0:"1755","60e883a5":"1827","77e86a01":"1856","2cea4aaa":"1975","1a4e3797":"2138",b7ae13b2:"2404","0df6bfdc":"2560","99c8a2bc":"2612","3e8b85aa":"2626",c4f5d8e4:"2634","548347c6":"2635",bf89c9e9:"2644","9e4087bc":"2711","6b6dabe5":"2926",ccc49370:"3249",edefc60b:"3624","6afb3535":"3880","478990e4":"4421","6875c492":"4813","57b29698":"4877",f8d72259:"4900","8644cb3d":"5139","709fdcb1":"5215",c377a04b:"5742","9225b3a9":"5950","1f391b9e":"6061","47a5dbed":"6087","1be6b01a":"6103","5ed3387d":"6802","3b8c55ea":"6803",e8ca61e3:"6879","8fea3195":"6961",a2b339b6:"6963",e747ec83:"7051","08bd72b4":"7452",a6aa9e1f:"7643","4912050a":"7995","5cab3a8d":"8042","0480b142":"8070",be94c875:"8198","01a85c17":"8209","0874a7d3":"8269","7fef215d":"8349","00a09c75":"8412","32a77d0d":"8449","93234bd6":"8458","935f2afb":"8581","1be78505":"8714","605ee76d":"8829","913a5992":"9174","3a920b14":"9391",e383ab1f:"9504","7760e989":"9976"}[e]||e,f.p+f.u(e)},(()=>{var e={5354:0,1869:0};f.f.j=(a,b)=>{var c=f.o(e,a)?e[a]:void 0;if(0!==c)if(c)b.push(c[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var d=new Promise(((b,d)=>c=e[a]=[b,d]));b.push(c[2]=d);var r=f.p+f.u(a),t=new Error;f.l(r,(b=>{if(f.o(e,a)&&(0!==(c=e[a])&&(e[a]=void 0),c)){var d=b&&("load"===b.type?"missing":b.type),r=b&&b.target&&b.target.src;t.message="Loading chunk "+a+" failed.\n("+d+": "+r+")",t.name="ChunkLoadError",t.type=d,t.request=r,c[1](t)}}),"chunk-"+a,a)}},f.O.j=a=>0===e[a];var a=(a,b)=>{var c,d,r=b[0],t=b[1],o=b[2],n=0;if(r.some((a=>0!==e[a]))){for(c in t)f.o(t,c)&&(f.m[c]=t[c]);if(o)var i=o(f)}for(a&&a(b);n{"use strict";var e,a,b,d,c,r={},t={};function f(e){var a=t[e];if(void 0!==a)return a.exports;var b=t[e]={id:e,loaded:!1,exports:{}};return r[e].call(b.exports,b,b.exports,f),b.loaded=!0,b.exports}f.m=r,f.c=t,e=[],f.O=(a,b,d,c)=>{if(!b){var r=1/0;for(i=0;i=c)&&Object.keys(f.O).every((e=>f.O[e](b[o])))?b.splice(o--,1):(t=!1,c0&&e[i-1][2]>c;i--)e[i]=e[i-1];e[i]=[b,d,c]},f.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return f.d(a,{a:a}),a},b=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,f.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var c=Object.create(null);f.r(c);var r={};a=a||[null,b({}),b([]),b(b)];for(var t=2&d&&e;"object"==typeof t&&!~a.indexOf(t);t=b(t))Object.getOwnPropertyNames(t).forEach((a=>r[a]=()=>e[a]));return r.default=()=>e,f.d(c,r),c},f.d=(e,a)=>{for(var b in a)f.o(a,b)&&!f.o(e,b)&&Object.defineProperty(e,b,{enumerable:!0,get:a[b]})},f.f={},f.e=e=>Promise.all(Object.keys(f.f).reduce(((a,b)=>(f.f[b](e,a),a)),[])),f.u=e=>"assets/js/"+({696:"aa336e66",715:"dbb55107",730:"36fb0842",968:"04d1181f",979:"86d1797f",1278:"6a2efc62",1377:"9f33cc29",1416:"d9e16301",1459:"4d54d076",1633:"64a7a4a8",1755:"b9fe55b0",1827:"60e883a5",1856:"77e86a01",1975:"2cea4aaa",2138:"1a4e3797",2404:"b7ae13b2",2560:"0df6bfdc",2612:"99c8a2bc",2626:"3e8b85aa",2634:"c4f5d8e4",2635:"548347c6",2644:"bf89c9e9",2711:"9e4087bc",2830:"71849617",2926:"6b6dabe5",3249:"ccc49370",3624:"edefc60b",3880:"6afb3535",4421:"478990e4",4813:"6875c492",4877:"57b29698",4900:"f8d72259",5139:"8644cb3d",5215:"709fdcb1",5742:"c377a04b",5950:"9225b3a9",6061:"1f391b9e",6087:"47a5dbed",6103:"1be6b01a",6802:"5ed3387d",6803:"3b8c55ea",6879:"e8ca61e3",6961:"8fea3195",6963:"a2b339b6",7051:"e747ec83",7452:"08bd72b4",7643:"a6aa9e1f",7667:"81482700",7995:"4912050a",8042:"5cab3a8d",8070:"0480b142",8198:"be94c875",8209:"01a85c17",8269:"0874a7d3",8349:"7fef215d",8401:"17896441",8412:"00a09c75",8449:"32a77d0d",8458:"93234bd6",8581:"935f2afb",8714:"1be78505",8829:"605ee76d",9174:"913a5992",9391:"3a920b14",9504:"e383ab1f",9976:"7760e989"}[e]||e)+"."+{696:"bcf8138c",715:"a25ead7a",730:"f98aa84f",968:"6f78d418",979:"68838d05",1278:"7bee4576",1377:"66871fe9",1416:"fb7d33d5",1459:"e3b38fed",1633:"0c7930b2",1755:"0075b706",1827:"c6f83d4e",1840:"4043649c",1856:"68da7da4",1975:"57f90927",2138:"2c4eaae3",2404:"e9e9924c",2560:"6ff23cdf",2612:"a1fb85c5",2626:"f909d1c0",2634:"b97ebbac",2635:"64e08e5c",2644:"7c77a941",2711:"4753d0f7",2830:"ccc5ccc2",2926:"6a377d10",3059:"7b612210",3249:"c32f64b0",3624:"5bb8ac42",3880:"99971cff",4384:"44626fef",4421:"a840539c",4813:"a4c045be",4877:"0911f86f",4900:"bc6de2e1",5139:"1b64ca13",5215:"320a3444",5742:"9909d420",5882:"5e20e438",5950:"986abb4c",6061:"a0d8fed6",6087:"7370376a",6103:"59aac459",6802:"7a9a8f76",6803:"2a55e6e2",6879:"98e13299",6961:"fe9cea2e",6963:"8054ca37",7051:"0865ee8c",7452:"cf5924b4",7643:"56538353",7667:"5b7b51af",7995:"00855d19",8042:"35942a8e",8070:"7bda4ba0",8198:"509f77ab",8209:"5af7ecc7",8269:"329b5f6d",8349:"b7827d86",8401:"3308733a",8412:"b2b49fbc",8449:"3dd739ee",8458:"bea62163",8581:"0b659b2b",8714:"b3991eaf",8829:"aa0eff55",8973:"d3b528f9",9074:"97917598",9174:"0e8b4caf",9391:"d0ff6568",9504:"070ea7a2",9976:"4ae527e9"}[e]+".js",f.miniCssF=e=>{},f.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),f.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),d={},c="graphile-worker:",f.l=(e,a,b,r)=>{if(d[e])d[e].push(a);else{var t,o;if(void 0!==b)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var c=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),c&&c.forEach((e=>e(b))),a)return a(b)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=u.bind(null,t.onerror),t.onload=u.bind(null,t.onload),o&&document.head.appendChild(t)}},f.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.p="/",f.gca=function(e){return e={17896441:"8401",71849617:"2830",81482700:"7667",aa336e66:"696",dbb55107:"715","36fb0842":"730","04d1181f":"968","86d1797f":"979","6a2efc62":"1278","9f33cc29":"1377",d9e16301:"1416","4d54d076":"1459","64a7a4a8":"1633",b9fe55b0:"1755","60e883a5":"1827","77e86a01":"1856","2cea4aaa":"1975","1a4e3797":"2138",b7ae13b2:"2404","0df6bfdc":"2560","99c8a2bc":"2612","3e8b85aa":"2626",c4f5d8e4:"2634","548347c6":"2635",bf89c9e9:"2644","9e4087bc":"2711","6b6dabe5":"2926",ccc49370:"3249",edefc60b:"3624","6afb3535":"3880","478990e4":"4421","6875c492":"4813","57b29698":"4877",f8d72259:"4900","8644cb3d":"5139","709fdcb1":"5215",c377a04b:"5742","9225b3a9":"5950","1f391b9e":"6061","47a5dbed":"6087","1be6b01a":"6103","5ed3387d":"6802","3b8c55ea":"6803",e8ca61e3:"6879","8fea3195":"6961",a2b339b6:"6963",e747ec83:"7051","08bd72b4":"7452",a6aa9e1f:"7643","4912050a":"7995","5cab3a8d":"8042","0480b142":"8070",be94c875:"8198","01a85c17":"8209","0874a7d3":"8269","7fef215d":"8349","00a09c75":"8412","32a77d0d":"8449","93234bd6":"8458","935f2afb":"8581","1be78505":"8714","605ee76d":"8829","913a5992":"9174","3a920b14":"9391",e383ab1f:"9504","7760e989":"9976"}[e]||e,f.p+f.u(e)},(()=>{var e={5354:0,1869:0};f.f.j=(a,b)=>{var d=f.o(e,a)?e[a]:void 0;if(0!==d)if(d)b.push(d[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var c=new Promise(((b,c)=>d=e[a]=[b,c]));b.push(d[2]=c);var r=f.p+f.u(a),t=new Error;f.l(r,(b=>{if(f.o(e,a)&&(0!==(d=e[a])&&(e[a]=void 0),d)){var c=b&&("load"===b.type?"missing":b.type),r=b&&b.target&&b.target.src;t.message="Loading chunk "+a+" failed.\n("+c+": "+r+")",t.name="ChunkLoadError",t.type=c,t.request=r,d[1](t)}}),"chunk-"+a,a)}},f.O.j=a=>0===e[a];var a=(a,b)=>{var d,c,r=b[0],t=b[1],o=b[2],n=0;if(r.some((a=>0!==e[a]))){for(d in t)f.o(t,d)&&(f.m[d]=t[d]);if(o)var i=o(f)}for(a&&a(b);n - + @@ -48,7 +48,7 @@ graphile-worker-rate-limiter)
  • Open source; liberal MIT license
  • Executes tasks written in Node.js (these can call out to any other language or networked service)
  • Modern JS with 100% async/await API (no callbacks)
  • Written natively in TypeScript
  • If you're running really lean, you can run Graphile Worker in the same Node process as your server to keep costs and devops complexity down.
  • Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/admin-functions.html b/docs/admin-functions.html index c4b77b24..3b604ebc 100644 --- a/docs/admin-functions.html +++ b/docs/admin-functions.html @@ -13,7 +13,7 @@ - + @@ -61,7 +61,7 @@ reaching max_attempts. Will delete this data, but is otherwise safe.

    tip

    You should write your tasks such that no job will ever permafail; for example after 20 attempts you might have the job do some cleanup and then exit successfuly.

    Example

    In the CLI:

    CLI
    graphile-worker --cleanup DELETE_PERMAFAILED_JOBS,GC_TASK_IDENTIFIERS,GC_JOB_QUEUES

    Or in the library using WorkerUtils:

    JS API
    await workerUtils.cleanup({
    tasks: ["DELETE_PERMAFAILED_JOBS", "GC_TASK_IDENTIFIERS", "GC_JOB_QUEUES"],
    });
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/cli.html b/docs/cli.html index d7f5616a..792a380d 100644 --- a/docs/cli.html +++ b/docs/cli.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ The names of these files will be the task identifiers, e.g. hello below:

    tasks/hello.js
    module.exports = async (payload, helpers) => {
    const { name } = payload;
    helpers.logger.info(`Hello, ${name}`);
    };

    Run the worker

    (Make sure you're in the folder that contains the tasks/ folder.)

    Run Graphile Worker passing in your database connection string:

    npx graphile-worker -c "postgres:///my_db"
    # or, if you have a remote database, something like:
    # npx graphile-worker -c "postgres://user:pass@host:port/db?ssl=true"
    # or, if you prefer envvars
    # DATABASE_URL="..." npx graphile-worker
    note

    npx runs the local copy of an npm module if it is installed, when you're ready, switch to using the package.json "scripts" entry instead.

    Add a job via SQL

    Connect to your database and run the following SQL:

    SELECT graphile_worker.add_job('hello', json_build_object('name', 'Bobby Tables'));

    Success!

    You should see the worker output Hello, Bobby Tables. Gosh, that was fast!

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/cli/run.html b/docs/cli/run.html index 33c9f3bf..e40c7cdb 100644 --- a/docs/cli/run.html +++ b/docs/cli/run.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ different role, one solution is to explicitly change the owner of the graphile_worker.* tables to be the same role as is used at runtime.

    CLI options

    The following CLI options are available (graphile-worker --help):

    Options:
    --help Show help [boolean]
    --version Show version number [boolean]
    -c, --connection Database connection string, defaults to the
    'DATABASE_URL' envvar [string]
    -s, --schema The database schema in which Graphile Worker is
    (to be) located [string]
    --schema-only Just install (or update) the database schema,
    then exit [boolean] [default: false]
    --once Run until there are no runnable jobs left, then
    exit [boolean] [default: false]
    --crontab override path to crontab file [string]
    -j, --jobs number of jobs to run concurrently [number]
    -m, --max-pool-size maximum size of the PostgreSQL pool [number]
    --poll-interval how long to wait between polling for jobs in
    milliseconds (for jobs scheduled in the
    future/retries) [number]
    --no-prepared-statements set this flag if you want to disable prepared
    statements, e.g. for compatibility with some
    external PostgreSQL pools [boolean]
    -C, --config The path to the config file [string]
    --cleanup Clean the database, then exit. Accepts a
    comma-separated list of cleanup tasks:
    GC_TASK_IDENTIFIERS, GC_JOB_QUEUES,
    DELETE_PERMAFAILED_JOBS [string]

    Connection string

    A PostgreSQL connection string looks like this:

    postgres://[user]:[pass]@[host]:[port]/[databaseName]?[parameter]=[value]

    Where each of the [...] placeholders are optional. Here are some examples:

    • postgres:///my_db connect to database my_db on the default host (localhost) and default port (5432)
    • postgres://127.0.0.1/my_db
    • postgres://127.0.0.1:5432/my_db
    • postgres://postgres:postgres@127.0.0.1:5432/my_db
    • postgres://postgres:postgres@127.0.0.1:5432/my_db?ssl=1
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/config.html b/docs/config.html index ca6e478a..a399df62 100644 --- a/docs/config.html +++ b/docs/config.html @@ -13,7 +13,7 @@ - + @@ -74,7 +74,7 @@ Worker Preset will use environment variables if they are set. Values in your custom preset or CLI flags will take precedence over environment variables.

    {
    connectionString: process.env.DATABASE_URL,
    schema: process.env.GRAPHILE_WORKER_SCHEMA
    }
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/connection-string.html b/docs/connection-string.html index 0391b771..b4fcafb8 100644 --- a/docs/connection-string.html +++ b/docs/connection-string.html @@ -13,7 +13,7 @@ - + @@ -69,7 +69,7 @@ pg-connection-string package to perform parsing of the connection string depending on which version of pg is in use.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/contributing.html b/docs/contributing.html index db599aff..83e3f214 100644 --- a/docs/contributing.html +++ b/docs/contributing.html @@ -13,7 +13,7 @@ - + @@ -67,7 +67,7 @@ See the Website README for more info on the website.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/cron.html b/docs/cron.html index 48c8610f..b2f1d561 100644 --- a/docs/cron.html +++ b/docs/cron.html @@ -13,7 +13,7 @@ - + @@ -105,7 +105,7 @@ if you want to schedule the same task multiple times, perhaps on different time patterns or with different payloads or other options (since every cron item must have a unique identifier).
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/docker.html b/docs/docker.html index 273c082f..f416debc 100644 --- a/docs/docker.html +++ b/docs/docker.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ supported command line options you can run:

    docker run --init --rm -it graphile/worker --help

    Adding tasks to execute is done by mounting the tasks directory as a volume into the /worker directory.

    The following example has a tasks directory in the current directory on the Docker host. The PostgreSQL server is also running on the same host.

    docker run \
    --init \
    --rm -it \
    --network=host \
    -v "$PWD/tasks":/worker/tasks \
    graphile/worker \
    -c "postgres://postgres:postgres@localhost:5432/postgres"
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/error-handling.html b/docs/error-handling.html index 64772e3d..20cbdaeb 100644 --- a/docs/error-handling.html +++ b/docs/error-handling.html @@ -13,7 +13,7 @@ - + @@ -42,7 +42,7 @@ version includes new migrations, then a NOTIFY event will be issued. Graphile Worker 0.16+ will LISTEN for this event, and will shut down if it is received.

    Error codes

    • GWBKM - Invalid job_key_mode value, expected 'replace', 'preserve_run_at' or 'unsafe_dedupe'.
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/exponential-backoff.html b/docs/exponential-backoff.html index e0df2df8..c1e7131e 100644 --- a/docs/exponential-backoff.html +++ b/docs/exponential-backoff.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ it fails). This seems to handle temporary issues well, after ~4 hours attempts will be made every ~6 hours until the maximum number of attempts is achieved. The specific delays can be seen below:

    select
    attempt,
    exp(least(10, attempt)) * interval '1 second' as delay,
    sum(exp(least(10, attempt)) * interval '1 second') over (order by attempt asc) total_delay
    from generate_series(1, 24) as attempt;

    attempt | delay | total_delay
    ---------+-----------------+-----------------
    1 | 00:00:02.718282 | 00:00:02.718282
    2 | 00:00:07.389056 | 00:00:10.107338
    3 | 00:00:20.085537 | 00:00:30.192875
    4 | 00:00:54.598150 | 00:01:24.791025
    5 | 00:02:28.413159 | 00:03:53.204184
    6 | 00:06:43.428793 | 00:10:36.632977
    7 | 00:18:16.633158 | 00:28:53.266135
    8 | 00:49:40.957987 | 01:18:34.224122
    9 | 02:15:03.083928 | 03:33:37.308050
    10 | 06:07:06.465795 | 09:40:43.773845
    11 | 06:07:06.465795 | 15:47:50.239640
    12 | 06:07:06.465795 | 21:54:56.705435
    13 | 06:07:06.465795 | 28:02:03.171230
    14 | 06:07:06.465795 | 34:09:09.637025
    15 | 06:07:06.465795 | 40:16:16.102820
    16 | 06:07:06.465795 | 46:23:22.568615
    17 | 06:07:06.465795 | 52:30:29.034410
    18 | 06:07:06.465795 | 58:37:35.500205
    19 | 06:07:06.465795 | 64:44:41.966000
    20 | 06:07:06.465795 | 70:51:48.431795
    21 | 06:07:06.465795 | 76:58:54.897590
    22 | 06:07:06.465795 | 83:06:01.363385
    23 | 06:07:06.465795 | 89:13:07.829180
    24 | 06:07:06.465795 | 95:20:14.294975
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/faq.html b/docs/faq.html index 35911dbe..10c1b4d8 100644 --- a/docs/faq.html +++ b/docs/faq.html @@ -13,7 +13,7 @@ - + @@ -38,7 +38,7 @@ idle worker to ask for jobs. If there is no idle worker then it'll drop the event knowing that when one of the workers finishes they'll ask for the next job anyway.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/forbidden-flags.html b/docs/forbidden-flags.html index 8e972b5a..82446aa6 100644 --- a/docs/forbidden-flags.html +++ b/docs/forbidden-flags.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ graphile-worker-rate-limiter project and the discussion on issue #118.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/glossary.html b/docs/glossary.html index 67003ed0..01517535 100644 --- a/docs/glossary.html +++ b/docs/glossary.html @@ -13,7 +13,7 @@ - + @@ -40,7 +40,7 @@ or similar signal, or via the runner.stop() API.

    Forceful shutdown

    When a WorkerPool stops accepting new jobs and explicitly unlocks all in progress tasks. The process should exit as soon as the in progress tasks have been unlocked, to ensure that they do not continue to be processed.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/installation.html b/docs/installation.html index a67d673b..b20b435e 100644 --- a/docs/installation.html +++ b/docs/installation.html @@ -13,13 +13,13 @@ - + - + \ No newline at end of file diff --git a/docs/job-key.html b/docs/job-key.html index fe7bb12c..e28a251e 100644 --- a/docs/job-key.html +++ b/docs/job-key.html @@ -13,7 +13,7 @@ - + @@ -47,7 +47,7 @@ job_key_mode = 'unsafe_dedupe'), meaning both will run. (The old job will be prevented from running again, and will have the job_key removed from it.)

    Calling remove_job for a locked (i.e. running) job will not actually remove it, but will prevent it from running again on failure.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/jobs-view.html b/docs/jobs-view.html index bfa2e89d..e987aeeb 100644 --- a/docs/jobs-view.html +++ b/docs/jobs-view.html @@ -13,7 +13,7 @@ - + @@ -40,7 +40,7 @@ instead. If you need it for debugging then you can read it from the private tables, just be careful, and don't write scripts to do it for you since it might change in a patch release.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/library.html b/docs/library.html index b606b295..9d1a4d3a 100644 --- a/docs/library.html +++ b/docs/library.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ not the recommended to use it in your main application due to inefficiency. It's fine for one-off scripts like this, but in your main application you should use WorkerUtils' addJob method..

    Success!

    Running these two examples should output something like:

    [core] INFO: Worker connected and looking for jobs... (task names: 'hello')
    [job(worker-7327280603017288: hello{1})] INFO: Hello, Bobby Tables
    [worker(worker-7327280603017288)] INFO: Completed task 1 (hello) with success (0.16ms)
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/library/add-job.html b/docs/library/add-job.html index f1ddbcce..9d84601f 100644 --- a/docs/library/add-job.html +++ b/docs/library/add-job.html @@ -13,7 +13,7 @@ - + @@ -50,7 +50,7 @@ received a DM. Over the next 2 minutes if any other DMs are received, these can be appended to the job payload such that when the job executes it can inform the user of all of these DMs, not just the latest one.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/library/add-jobs.html b/docs/library/add-jobs.html index 87381d9e..4f3f56eb 100644 --- a/docs/library/add-jobs.html +++ b/docs/library/add-jobs.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ jobKey it can also be used to replace existing jobs.

    note

    The addJobs() JavaScript method simply defers to the underlying addJobs SQL function.

    The addJobs arguments are as follows:

    • jobSpecs: descriptions of the jobs you want to queue
    • jobKeyPreserveRunAt: optional boolean; if true, run_at will not be updated when a job is overwritten due to jobKey

    Example:

    await addJobs([
    { identifier: "send_email", payload: { to: "someone@example.com" } },
    { identifier: "send_email", payload: { to: "anyone@example.com" } },
    { identifier: "send_email", payload: { to: "thisone@example.com" } },
    { identifier: "send_email", payload: { to: "anotherone@example.com" } },
    ]);

    Definitions:

    export type AddJobsFunction = (
    jobSpecs: AddJobsJobSpec[],
    jobKeyPreserveRunAt?: boolean,
    ) => Promise<ReadonlyArray<Job>>;

    export interface AddJobsJobSpec {
    /**
    * The name of the task that will be executed for this job.
    */
    identifier: string;

    /**
    * The payload (typically a JSON object) that will be passed to the task executor.
    */
    payload: unknown;

    /**
    * The queue to run this task under (only specify if you want jobs in this
    * queue to run serially). (Default: null)
    */
    queueName?: string;

    /**
    * A Date to schedule this task to run in the future. (Default: now)
    */
    runAt?: Date;

    /**
    * Jobs are executed in numerically ascending order of priority (jobs with a
    * numerically smaller priority are run first). (Default: 0)
    */
    priority?: number;

    /**
    * How many retries should this task get? (Default: 25)
    */
    maxAttempts?: number;

    /**
    * Unique identifier for the job, can be used to update or remove it later if
    * needed. (Default: null)
    */
    jobKey?: string;

    /**
    * Flags for the job, can be used to dynamically filter which jobs can and
    * cannot run at runtime. (Default: null)
    */
    flags?: string[];
    }
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/library/logger.html b/docs/library/logger.html index d3e997ec..32641862 100644 --- a/docs/library/logger.html +++ b/docs/library/logger.html @@ -13,7 +13,7 @@ - + @@ -41,7 +41,7 @@ above) do not do this in production as these logs may include incredibly sensitive details such as your full database connection string including password.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/library/queue.html b/docs/library/queue.html index d6913716..2a7e9b37 100644 --- a/docs/library/queue.html +++ b/docs/library/queue.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,8 @@ database:
    • connectionString: A PostgreSQL connection string to the database containing the job queue, or
    • pgPool: A pg.Pool instance to use
  • schema can be used to change the default graphile_worker schema to -something else (equivalent to --schema on the CLI)
  • WorkerUtils

    A WorkerUtils instance has the following methods:

    • addJob(name: string, payload: JSON, spec: TaskSpec) a method you can +something else (equivalent to --schema on the CLI)
    If you use pgPool, ensure it has error handlers!

    If your pgPool doesn't have error handlers then connection issues with the +database may cause your Worker process to exit prematurely.

    import { Pool } from "pg";
    const pool = new Pool({
    /* ... */
    });

    // No action necessary
    function handleError() {}
    pool.on("error", handleError);
    pool.on("connect", (client) => void client.on("error", handleError));

    WorkerUtils

    A WorkerUtils instance has the following methods:

    • addJob(name: string, payload: JSON, spec: TaskSpec) a method you can call to enqueue a job, see addJob.
    • migrate() a method you can call to update the graphile-worker database schema; returns a promise.
    • release() call this to release the WorkerUtils instance. It's typically best to use WorkerUtils as a singleton, so you often won't @@ -39,7 +40,7 @@ as makeWorkerUtils as the first argument; the remaining arguments are for addJob.

      tip

      You are recommended to use makeWorkerUtils instead where possible, but in one-off scripts this convenience method may be enough.

      Runnable example:

      const { addJobAdhoc } = require("graphile-worker");

      async function main() {
      await addJobAdhoc(
      // makeWorkerUtils options
      { connectionString: "postgres:///my_db" },

      // Task identifier
      "calculate-life-meaning",

      // Payload
      { value: 42 },

      // Optionally, add further task spec details here
      );
      }

      main().catch((err) => {
      console.error(err);
      process.exit(1);
      });
      Three ants crawling atop the footer
      - + \ No newline at end of file diff --git a/docs/library/run.html b/docs/library/run.html index e144a428..b0f4a2a5 100644 --- a/docs/library/run.html +++ b/docs/library/run.html @@ -13,7 +13,7 @@ - + @@ -46,7 +46,7 @@ complete.
    • addJob: AddJobFunction see addJob.
    • promise: Promise<void> a promise that resolves once the runner has completed.
    • events: WorkerEvents a Node.js EventEmitter that exposes certain events within the runner (see WorkerEvents).

    Example: runner.addJob()

    See addJob for more details.

    await runner.addJob("testTask", {
    thisIsThePayload: true,
    });

    Example: runner.events

    See WorkerEvents for more details.

    runner.events.on("job:success", ({ worker, job }) => {
    console.log(`Hooray! Worker ${worker.workerId} completed job ${job.id}`);
    });
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/performance.html b/docs/performance.html index 2d3493e9..609dc11e 100644 --- a/docs/performance.html +++ b/docs/performance.html @@ -13,7 +13,7 @@ - + @@ -46,7 +46,7 @@ workers and the database (and a tonne of Chrome tabs, electron apps, and what not). Jobs=20000, parallelism=4, concurrency=10.

    Conclusion:

    • Startup/shutdown: 110ms
    • Jobs per second: 11,851
    • Average latency: 2.66ms (min: 2.39ms, max: 12.09ms)
    Timing startup/shutdown time...
    ... it took 110ms

    Scheduling 20000 jobs
    Adding jobs: 200.84ms
    ... it took 287ms


    Timing 20000 job execution...
    Found 999!

    ... it took 1797ms
    Jobs per second: 11851.90


    Testing latency...
    [core] INFO: Worker connected and looking for jobs... (task names: 'latency')
    Beginning latency test
    Latencies - min: 2.39ms, max: 12.09ms, avg: 2.66ms

    TODO: post perfTest results in a more reasonable configuration, e.g. using an RDS PostgreSQL server and a worker running on EC2.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/pro.html b/docs/pro.html index 8ceda5bf..64139349 100644 --- a/docs/pro.html +++ b/docs/pro.html @@ -13,7 +13,7 @@ - + @@ -99,7 +99,7 @@ distribute your own solution, ensure that you do it without using or being inspired by the source code to Graphile Pro. Figure out your own independent solution, please.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/pro/config.html b/docs/pro/config.html index cbd8cb54..d625ef09 100644 --- a/docs/pro/config.html +++ b/docs/pro/config.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ performing the migration to the newer database schema anyway. Defaults to 4 hours, but we recommend you set it to a smaller duration: the longest time you expect one of your jobs to take to execute, plus a bit of padding.

    Example

    graphile.config.ts
    import "graphile-config";
    import "graphile-worker";
    import { WorkerProPreset } from "@graphile-pro/worker";

    const preset: GraphileConfig.Preset = {
    extends: [WorkerProPreset],
    worker: {
    /* ... regular configuration here ...*/

    /* Example Worker Pro configuration options: */

    // Check in as active once per minute
    heartbeatInterval: 60 * 1000,

    // Check for and force-release inactive workers every 3 minutes
    sweepInterval: 3 * 60 * 1000,

    // Workers are deemed "inactive" 10 minutes after their last heartbeat
    sweepThreshold: 10 * 60 * 1000,

    // If old workers haven't exited within 30 minutes, go ahead and perform
    // the migration anyway:
    maxMigrationWaitTime: 30 * 60 * 1000,
    },
    };

    export default preset;
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/pro/migration.html b/docs/pro/migration.html index 4cca0307..132ae728 100644 --- a/docs/pro/migration.html +++ b/docs/pro/migration.html @@ -13,7 +13,7 @@ - + @@ -37,7 +37,7 @@ Worker Pro). This must be done before you migrate otherwise you risk receiving division by zero migration errors (these errors are convenient for assertions in the migrations).

    For Graphile Worker before (excluding) v0.16.0 this will look something like:

    begin;
    update graphile_worker.jobs
    set locked_at = null, locked_by = null
    where locked_by is not null and locked_by not in (
    select worker_id from graphile_worker._private_pro_workers
    );
    update graphile_worker.job_queues
    set locked_at = null, locked_by = null
    where locked_by is not null and locked_by not in (
    select worker_id from graphile_worker._private_pro_workers
    );
    commit;

    For Graphile Worker v0.16.x it would be:

    begin;
    update graphile_worker._private_jobs as jobs
    set locked_at = null, locked_by = null
    where locked_by is not null and locked_by not in (
    select worker_id from graphile_worker._private_pro_workers
    );
    update graphile_worker._private_job_queues as job_queues
    set locked_at = null, locked_by = null
    where locked_by is not null and locked_by not in (
    select worker_id from graphile_worker._private_pro_workers
    );
    commit;

    For Graphile Worker v0.17.x+ it would be:

    begin;
    update graphile_worker._private_jobs as jobs
    set locked_at = null, locked_by = null
    where locked_by is not null and locked_by not in (
    select pool_id from graphile_worker._private_pro_pools
    );
    update graphile_worker._private_job_queues as job_queues
    set locked_at = null, locked_by = null
    where locked_by is not null and locked_by not in (
    select pool_id from graphile_worker._private_pro_pools
    );
    commit;
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/pro/recovery.html b/docs/pro/recovery.html index a78608a4..11596491 100644 --- a/docs/pro/recovery.html +++ b/docs/pro/recovery.html @@ -13,7 +13,7 @@ - + @@ -46,7 +46,7 @@ deemed "inactive"
    info

    It might take anywhere from sweepThreshold to heartbeatInterval + sweepThreshold + sweepInterval (plus processing time, etc) milliseconds for jobs from a crashed worker to be released.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/project-status.html b/docs/project-status.html index 0fb49a4b..74dda124 100644 --- a/docs/project-status.html +++ b/docs/project-status.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ documented in the release notes.

    To give feedback please raise an issue, or reach out on Discord.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/requirements.html b/docs/requirements.html index 1878c138..ba5207dc 100644 --- a/docs/requirements.html +++ b/docs/requirements.html @@ -13,7 +13,7 @@ - + @@ -33,7 +33,7 @@ graphile_worker (15 chars)

    1. Might work with older versions, but has not been tested. Node 18 won't run our jest tests due to segfault, fixed in Node 20.8.1, so CI cannot run against Node 18.
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/scaling.html b/docs/scaling.html index b5fd80c6..5e109f35 100644 --- a/docs/scaling.html +++ b/docs/scaling.html @@ -13,7 +13,7 @@ - + @@ -54,7 +54,7 @@ touch!

    Also if you are suffering some acute performance issue and you can replicate your load onto a staging server or similar I'd love to run some experiments to see if we can't squeeze more performance out of the system.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/schema.html b/docs/schema.html index 1218197f..7398143e 100644 --- a/docs/schema.html +++ b/docs/schema.html @@ -13,7 +13,7 @@ - + @@ -53,7 +53,7 @@ based on whether or not the migrations table in the schema exists, so by creating the migrations table in addition to the graphile_worker schema Worker should be able to move on to the next step without raising an error.

    create schema graphile_worker;
    create table graphile_worker.migrations (
    id int primary key,
    ts timestamptz default now() not null,
    breaking bool default false not null
    );
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/sql-add-job.html b/docs/sql-add-job.html index b8f2b010..e788da16 100644 --- a/docs/sql-add-job.html +++ b/docs/sql-add-job.html @@ -13,7 +13,7 @@ - + @@ -65,7 +65,7 @@ job_key_mode='replace' is enabled by default, to change this to the same behavior as job_key_mode='preserve_run_at' you should set job_key_preserve_run_at to true.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/support.html b/docs/support.html index 8ae75c12..88c412e0 100644 --- a/docs/support.html +++ b/docs/support.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ ROI.

    If you can't help with sponsorship, then helping others with their problems on the GitHub issues and in the Graphile Discord are both appreciated.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/tasks.html b/docs/tasks.html index 78ba61ff..41d9ec8e 100644 --- a/docs/tasks.html +++ b/docs/tasks.html @@ -13,7 +13,7 @@ - + @@ -98,7 +98,7 @@ need a database transaction, you should do so yourself, but please note that keeping transactions open may decrease Graphile Worker's performance due to increasing contention over the pool of database clients.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/techniques.html b/docs/techniques.html index e066912f..b33f9944 100644 --- a/docs/techniques.html +++ b/docs/techniques.html @@ -13,7 +13,7 @@ - + @@ -45,7 +45,7 @@ run_at of a job that you start executing is significantly before the current time minus the pollInterval (assuming that your database and worker clocks are synchronized).

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/typescript.html b/docs/typescript.html index b4bee7ea..5102e995 100644 --- a/docs/typescript.html +++ b/docs/typescript.html @@ -13,7 +13,7 @@ - + @@ -45,7 +45,7 @@ we make have to take into account that older jobs may not have the from address set, like so:

    import type { Task, WorkerUtils } from "graphile-worker";
    import { ses } from "./aws";

    declare global {
    namespace GraphileWorker {
    interface Tasks {
    send_email: {
    to: string;
    subject: string;
    body: string;
    + from?: string;
    };
    }
    }
    }

    export const send_email: Task<"send_email"> = async function (payload) {
    - const { to, subject, body } = payload;
    + const { to, subject, body, from } = payload;
    await ses.sendEmail({
    Destination: {
    ToAddresses: [to],
    - FromAddresses: ["no-reply@example.com"],
    + FromAddresses: [from ?? "no-reply@example.com"],
    },
    Message: {
    Subject: {
    Charset: "UTF-8",
    Data: subject,
    },
    Body: {
    Text: {
    Charset: "UTF-8",
    Data: body,
    },
    },
    },
    });
    };
    tip

    All of the declarations would normally be put in a shared interface file, or similar. The example above defines one with the task for ease of reading.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/uninstall.html b/docs/uninstall.html index 62083e35..42582adb 100644 --- a/docs/uninstall.html +++ b/docs/uninstall.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ effects, and to do a schema-only dump of your database before and after to compare the changes and look for unexpected consequences.

    Scale to zero first!

    Before running this command, you should make sure there are no running Graphile Worker instances.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/docs/worker-events.html b/docs/worker-events.html index b66ee3e8..ccf6376f 100644 --- a/docs/worker-events.html +++ b/docs/worker-events.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ during Graphile Worker's startup procedure, before the run() promise resolves).

    Example: via runner.events

    runner.events.on("job:success", ({ worker, job }) => {
    console.log(`Hooray! Worker ${worker.workerId} completed job ${job.id}`);
    });

    Example: using EventEmitter

    /** @type {import("graphile-worker").WorkerEvents} */
    const events = new EventEmitter();
    events.on(...);
    events.on(...);
    events.on(...);

    const runner = await run({ events, ... });

    Example: In graphile configuration

    /** @type {import("graphile-worker").WorkerEvents} */
    const events = new EventEmitter();
    events.on(...);
    events.on(...);
    events.on(...);

    /** @type {GraphileConfig.Preset} */
    const preset = {
    worker: {
    events,
    ...
    }
    };

    export default preset;

    Definitions:

    Details of what events we support and what data is available on the event payload is detailed below in TypeScript syntax:

    export type WorkerEvents = TypedEventEmitter<{
    /**
    * When a worker pool is created
    */
    "pool:create": { workerPool: WorkerPool };

    /**
    * When a worker pool attempts to connect to PG ready to issue a LISTEN
    * statement
    */
    "pool:listen:connecting": { workerPool: WorkerPool };

    /**
    * When a worker pool starts listening for jobs via PG LISTEN
    */
    "pool:listen:success": { workerPool: WorkerPool; client: PoolClient };

    /**
    * When a worker pool faces an error on their PG LISTEN client
    */
    "pool:listen:error": {
    workerPool: WorkerPool;
    error: any;
    client: PoolClient;
    };

    /**
    * When a worker pool is released
    */
    "pool:release": { pool: WorkerPool };

    /**
    * When a worker pool starts a graceful shutdown
    */
    "pool:gracefulShutdown": { pool: WorkerPool; message: string };

    /**
    * When a worker pool graceful shutdown throws an error
    */
    "pool:gracefulShutdown:error": { pool: WorkerPool; error: any };

    /**
    * When a worker is created
    */
    "worker:create": { worker: Worker; tasks: TaskList };

    /**
    * When a worker release is requested
    */
    "worker:release": { worker: Worker };

    /**
    * When a worker stops (normally after a release)
    */
    "worker:stop": { worker: Worker; error?: any };

    /**
    * When a worker is about to ask the database for a job to execute
    */
    "worker:getJob:start": { worker: Worker };

    /**
    * When a worker calls get_job but there are no available jobs
    */
    "worker:getJob:error": { worker: Worker; error: any };

    /**
    * When a worker calls get_job but there are no available jobs
    */
    "worker:getJob:empty": { worker: Worker };

    /**
    * When a worker faces a fatal error, for example it was unable to inform the
    * database that it had completed/failed a job.
    */
    "worker:fatalError": { worker: Worker; error: any; jobError: any | null };

    /**
    * When a job is retrieved by get_job
    */
    "job:start": { worker: Worker; job: Job };

    /**
    * When a job completes successfully
    */
    "job:success": { worker: Worker; job: Job };

    /**
    * When a job throws an error
    */
    "job:error": { worker: Worker; job: Job; error: any };

    /**
    * When a job fails permanently (emitted after job:error when appropriate)
    */
    "job:failed": { worker: Worker; job: Job; error: any };

    /**
    * When a job has finished executing and the result (success or failure) has
    * been written back to the database
    */
    "job:complete": { worker: Worker; job: Job; error: any };

    /**
    * When the runner is terminated by a signal
    */
    gracefulShutdown: { signal: Signal };

    /**
    * When the runner is stopped
    */
    stop: {};
    }>;
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/errors/peh.html b/errors/peh.html index 71a07f48..bb78d70b 100644 --- a/errors/peh.html +++ b/errors/peh.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ shuts down). In these cases since the client is likely not actively being await-ed the error will have no handler, and will result in a process exit if unhandled.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/index.html b/index.html index 50d6f62c..1605a901 100644 --- a/index.html +++ b/index.html @@ -13,14 +13,14 @@ - +

    A high performance job queue for PostgreSQL, written in Node.js

    Coder sat at monitor

    Reliable

    Automatic retries with automatic exponential backoff; built on Postgres' reliable transactions. Never lose a job.

    High Performance

    Up to 10,000 jobs per second; keep your infrastructure simple (just Postgres and Node) and focus on your project!

    Low Latency

    Jobs start in milliseconds thanks to Postgres' LISTEN/NOTIFY; delight customers with near real-time background processing.

    Cron Jobs

    Set up repeating tasks with minute-by-minute granularity; optional backfill to cover times when your servers weren't running.

    Job Control

    Schedule jobs to run in the future. Debounce jobs to avoid redundant work. Cancel or update scheduled jobs.

    Easy Migration

    Want to migrate to a dedicated job queue later? No problem! Examples of exporting jobs to other queues are included!

    Use The Stack You Have

    Coder sat at monitor
    Etan

    Hey 👋 currently using Worker in production. It's been a fantastic library that has allowed us to really simplify our tech stack to bootstrap projects.

    theIntuitionist

    I have Worker running along with postgrest and it is the perfect companion. It helps keep the dev ops side super simple — Graphile Worker runs right from within the node project if you want it to — reducing costs and devops complexity.

    Max

    Worker let us scale out millions of tasks. Graphile tooling has become the standard of quality and thoughtfulness by which I judge all other libraries when evaluating them for use.

    bennyp101

    I use Postgres as a queue using Graphile Worker and it works perfectly. No need for another moving part when the data I need is in the db. Also avoids having to do outbox stuff.

    Crowd-funded open-source software

    We're extremely grateful to our sponsors, for helping to fund ongoing development on Graphile Worker, Graphile Migrate, PostGraphile and the wider Graphile suite of tools. THANK YOU!

    Development Support

    Priority text support straight from the maintainer

    Give your company access to the knowledge and experience of the Graphile team through your chat server and GitHub/GitLab organization. Reference your code verbatim and arrange calls for any trickier topics.

    Learn more

    Graphile Starter

    A quick-start project for full-stack application development in React, Node.js, GraphQL and PostgreSQL

    Graphile Starter includes the foundations of a modern web application, with a full user registration system, session management, optimized job queue using Graphile Worker, pre-configured tooling, tests and much more.

    Learn more

    Advanced planning and execution engine for GraphQL

    The latest project from the Graphile team

    Grafast’s plan-based approach helps developers avoid common pitfalls and achieve better backend efficiency, leading to increased scalability and incredible performance your customers will love.

    Grafast.org
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/news.html b/news.html index 9419d998..465710b4 100644 --- a/news.html +++ b/news.html @@ -13,7 +13,7 @@ - + @@ -108,7 +108,7 @@ suite of developer tools. Find out how to sponsor us at graphile.org/sponsor.

    Full release notes found on this site or at GitHub.

    A handdrawn image of an ant holding up a green heart

    Thank you Graphile sponsors!

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/news/2023-12-11-016-release.html b/news/2023-12-11-016-release.html index 9491ff13..0674a670 100644 --- a/news/2023-12-11-016-release.html +++ b/news/2023-12-11-016-release.html @@ -13,7 +13,7 @@ - + @@ -108,7 +108,7 @@ suite of developer tools. Find out how to sponsor us at graphile.org/sponsor.

    Full release notes found on this site or at GitHub.

    A handdrawn image of an ant holding up a green heart

    Thank you Graphile sponsors!

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/news/archive.html b/news/archive.html index 9c3b4304..c0c1bd09 100644 --- a/news/archive.html +++ b/news/archive.html @@ -13,13 +13,13 @@ - + - + \ No newline at end of file diff --git a/news/tags.html b/news/tags.html index 0871c8a1..11e7e29d 100644 --- a/news/tags.html +++ b/news/tags.html @@ -13,13 +13,13 @@ - + - + \ No newline at end of file diff --git a/news/tags/releases.html b/news/tags/releases.html index 70f269d9..0b8dfa88 100644 --- a/news/tags/releases.html +++ b/news/tags/releases.html @@ -13,7 +13,7 @@ - + @@ -108,7 +108,7 @@ suite of developer tools. Find out how to sponsor us at graphile.org/sponsor.

    Full release notes found on this site or at GitHub.

    A handdrawn image of an ant holding up a green heart

    Thank you Graphile sponsors!

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/pricing.html b/pricing.html index 024820c3..e8db625b 100644 --- a/pricing.html +++ b/pricing.html @@ -13,7 +13,7 @@ - + @@ -58,7 +58,7 @@ get in touch via email.

    I'm an enterprise user and need X, Y and Z

    Please get in touch and we'll be happy to help!

    What is the Worker Pro license?

    The license forbids publishing and redistribution but otherwise allows you to make your own modifcations for internal usage:

    Copyright © 2024 Benjie Gillam

    Use and modification of this software and associated documentation files (the
    “Software”) is permitted, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software. The Software is not to be
    distributed, published, sold, or sub-licensed.

    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
    FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
    COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
    IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    Last reviewed: 20th September 2024
    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/releases.html b/releases.html index b477b603..4986ef61 100644 --- a/releases.html +++ b/releases.html @@ -13,7 +13,7 @@ - + @@ -269,7 +269,7 @@ (see README)
  • query helper reduces boilerplate
  • Fixes:

    • We never needed uuid-ossp so we've removed the requirement (you may want to remove the extension from your DB manually)

    v0.1.0

    • Add database 'error' handler to avoid crashes (@madflow #26)
    • DATABASE_URL can now be used in place of connectionString (@madflow, @benjie #20 #27)
    • Improve documentation (@madflow, @archlemon, @benjie #11 #18 #31 #33)
    • Improve testing (@madflow #19 #30)

    v0.1.0-alpha.0

    Now usable as a library as well as a CLI.

    Changes:

    • Renamed a number of internals
      • start -> runTaskList
      • runAllJobs -> runTaskListOnce
      • workerCount -> concurrency
    • Add an easy way to run as a library (run and runOnce methods)
    • CLI code reduced as it uses new library code
    • Implemented linting
    • Exported more methods

    v0.0.1-alpha.7

    • Add missing tslib dependency

    v0.0.1-alpha.6

    • make poll interval configurable
    • overhaul TypeScript types/interfaces
    • more docs

    v0.0.1-alpha.5

    • Fix casting (REQUIRES DB RESET)

    v0.0.1-alpha.4

    • add addJob helper

    v0.0.1-alpha.3

    • Travis CI
    • Add index.js

    v0.0.1-alpha.2

    • Docs

    v0.0.1-alpha.1

    • More efficient job trigger
    • Reduce latency

    v0.0.1-alpha.0

    Initial release.

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/search.html b/search.html index aacb7e65..e9977de0 100644 --- a/search.html +++ b/search.html @@ -13,13 +13,13 @@ - +

    Search the documentation

    Three ants crawling atop the footer
    - + \ No newline at end of file diff --git a/sponsors.html b/sponsors.html index 57ff31f4..0df6eb12 100644 --- a/sponsors.html +++ b/sponsors.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ Grafast, Graphile Migrate and Graphile Starter. Sponsorship increases the rate of fixes, documentation improvements, and feature development on these and other projects.

    Three ants crawling atop the footer
    - + \ No newline at end of file