@@ -26,48 +26,32 @@ failure and the task is rescheduled using an exponential-backoff algorithm.
2626
2727Each task function is passed two arguments:
2828
29- - ` payload ` &mdash ; the ( JSON) payload you passed when calling
29+ - ` payload ` &mdash ; the JSON payload you passed when calling
3030 ` graphile_worker.add_job(...) ` in the database, or ` addJob(...) ` via the JS
3131 API
32- - ` helpers ` (see [ ` helpers ` ] ( #helpers ) below) &mdash ; an object containing:
33- - ` logger ` &mdash ; a scoped [ Logger] ( /docs/library/logger ) instance, to aid
34- tracing/debugging
35- - ` job ` &mdash ; the whole job (including ` uuid ` , ` attempts ` , etc) &mdash ; you
36- shouldn't need this
37- - ` getQueueName() ` &mdash ; get the name of the queue the job is in (may or may
38- not return a promise - recommend you always ` await ` it)
39- - ` abortSignal ` &mdash ; could be an ` AbortSignal ` , or ` undefined ` if not
40- supported by this release of worker; if set, use this to abort your task
41- early on graceful shutdown (can be passed to a number of asynchronous
42- Node.js methods)
43- - ` abortPromise ` &mdash ; if present, a promise that will reject when
44- ` abortSignal ` aborts; convenient for exiting your task when the abortSignal
45- fires: ` Promise.race([abortPromise, doYourThing()]) `
46- - ` withPgClient ` &mdash ; a helper to use to get a database client
47- - ` query(sql, values) ` &mdash ; a convenience wrapper for
48- ` withPgClient(pgClient => pgClient.query(sql, values)) `
49- - ` addJob ` &mdash ; a helper to schedule a job
32+ - ` helpers ` see [ ` helpers ` ] ( #helpers ) below
5033
5134:::warning Important
5235
53- Your jobs must wait for all asynchronous work to be completed before returning,
54- otherwise we might think they were successful prematurely. Every promise that a
55- task executor triggers must be ` await ` -ed; task executors _ should not_ create
56- &ldquo ; untethered&rdquo ; promises.
36+ Your task executors must wait for all asynchronous work for a job to be
37+ completed before returning, otherwise Graphile Worker might think they were
38+ successful prematurely. Every promise that a task executor triggers must be
39+ ` await ` -ed; task executors _ should not_ create &ldquo ; untethered&rdquo ;
40+ promises.
5741
5842:::
5943
6044::: tip
6145
62- We automatically retry the job if it fails, so it&apos ; s often sensible to split
63- a large job into multiple smaller jobs, this also allows them to run in parallel
64- resulting in faster execution. This is particularly important for tasks that are
65- not idempotent (i.e. running them a second time will have extra side effects)
66- &mdash ; for example sending emails.
46+ Graphile Worker automatically retries the job if it fails, so it&apos ; s often
47+ sensible to split a large job into multiple smaller jobs, this also allows them
48+ to run in parallel resulting in faster execution. This is particularly important
49+ for tasks that are not idempotent (i.e. running them a second time will have
50+ extra side effects) &mdash ; for example sending emails.
6751
6852:::
6953
70- ## Example task executors
54+ ## Example JS task executors
7155
7256``` js title="tasks/task_1.js"
7357module .exports = async (payload ) => {
@@ -82,44 +66,39 @@ module.exports = async (payload, helpers) => {
8266};
8367```
8468
85- ## The ` tasks/ ` folder
69+ ## The task directory
8670
87- When you run ` graphile-worker ` , it will look in the current directory for a
88- folder called ` tasks ` , and it will recursively look for files suitable to run as
89- tasks. File names excluding the extension and folder names must only use
90- alphanumeric characters, underscores and dashes (` /^[A-Za-z0-9_-]+$/ ` ) to be
91- recognized. Graphile Worker will then attempt to load the file as a task
92- executor; the task identifier for this will be all the folders and the file name
93- (excluding the extension) joined with ` / ` characters; e.g.
94- ` tasks/send_notification.js ` would get the identifier ` send_notification ` and
95- ` tasks/users/emails/verify.js ` would get the identifier ` users/emails/verify ` .
96- How the file is loaded as a task executor will depend on the file in question
97- and the plugins you have loaded.
71+ When you run Graphile Worker, it will look in the configured
72+ [ ` taskDirectory ` ] ( ./config#workertaskdirectory ) for files suitable to run as
73+ tasks.
9874
99- ```
100- current directory
101- ├── package.json
102- ├── node_modules
103- └── tasks
104- ├── send_notification.js
105- ├── generate_pdf.js
106- └── users
107- ├── congratulate.js
108- └── emails
109- ├── verify.js
110- └── send_otp.js
111- ```
75+ File names excluding the extension and folder names must only use alphanumeric
76+ characters, underscores, and dashes (` /^[A-Za-z0-9_-]+$/ ` ) to be recognized.
77+
78+ Graphile Worker will then attempt to load the file as a task executor; the task
79+ identifier for this task will be all the folders and the file name (excluding
80+ the extension) joined with ` / ` characters:
81+
82+ - ` ${taskDirectory}/send_notification.js ` would get the task identifier
83+ ` send_notification ` .
84+ - ` ${taskDirectory}/users/emails/verify.js ` would get the task identifier
85+ ` users/emails/verify ` .
86+
87+ How the file is loaded as a task executor will depend on the specific file and
88+ the plugins you have loaded.
11289
11390## Loading JavaScript files
11491
115- Out of the box , Graphile Worker will load ` .js ` , ` .cjs ` and ` .mjs ` files using
116- the ` import() ` function. If the file is a CommonJS module then Worker will
117- expect ` module.exports ` to be the task executor function; if the file is an
118- ECMAScript module (ESM) then Worker will expect the default export to be the
119- task executor function.
92+ With the default preset , Graphile Worker will load ` .js ` , ` .cjs ` and ` .mjs `
93+ files as task executors using the ` import() ` function. If the file is a CommonJS
94+ module, then Worker will expect ` module.exports ` to be the task executor
95+ function; if the file is an ECMAScript module (ESM) then Worker will expect the
96+ default export to be the task executor function.
12097
121- Via plugins, support for other ways of loading task files can be added; look at
122- the source code of ` LoadTaskFromJsPlugin.ts ` for inspiration.
98+ You can add support for other ways of loading task executors via plugins; look
99+ at the source code of
100+ [ ` LoadTaskFromJsPlugin.ts ` ] ( https://github.com/graphile/worker/blob/main/src/plugins/LoadTaskFromJsPlugin.ts )
101+ for inspiration.
123102
124103### Loading TypeScript files
125104
@@ -130,19 +109,19 @@ TypeScript files to JS and then have Graphile Worker load the JS files.
130109
131110:::
132111
133- To load TypeScript files directly as tasks (without precompilation), one way is
134- to :
112+ To load TypeScript files directly as task executors (without precompilation),
113+ one way is to do the following :
135114
136- 1 . install ` ts-node ` ,
137- 2 . add ` ".ts" ` to the ` worker.fileExtensions ` list in your ` graphile.config.ts ` ,
138- 3 . run Graphile Worker with the environmental variable
115+ 1 . Install ` ts-node ` .
116+ 2 . Add ` ".ts" ` to the ` worker.fileExtensions ` list in your preset.
117+ 3 . Run Graphile Worker with the environment variable
139118 ` NODE_OPTIONS="--loader ts-node/esm" ` set.
140119
141120``` ts title="Example graphile.config.ts"
142- import type { GraphileConfig } from " graphile-config" ;
143- import type {} from " graphile-worker" ;
121+ import { WorkerPreset } from " graphile-worker" ;
144122
145123const preset: GraphileConfig .Preset = {
124+ extends: [WorkerPreset ],
146125 worker: {
147126 connectionString: process .env .DATABASE_URL ,
148127 concurrentJobs: 5 ,
@@ -167,16 +146,21 @@ This feature is currently experimental.
167146:::
168147
169148If you're running on Linux or Unix (including macOS) then if Graphile Worker
170- finds an executable file inside of ` tasks/ ` it will create a task executor for
171- it. When a task of this kind is found, Graphile Worker will execute the file
172- setting the relevant environmental variables and passing in the payload
149+ finds an executable file inside of the ` taskDirectory ` it will create a task
150+ executor for it. When a task of this kind is found, Graphile Worker will execute
151+ the file with the relevant environment variables and pass in the payload
173152according to the encoding. If the executable exits with code ` 0 ` then Graphile
174- Worker will see this as success, all other exit codes are seen as failure.
153+ Worker will see this as success. All other exit codes are seen as failure.
175154
176- ### Environmental variables
155+ This feature is added via the
156+ [ LoadTaskFromExecutableFilePlugin plugin] ( https://github.com/graphile/worker/blob/main/src/plugins/LoadTaskFromExecutableFilePlugin.ts )
157+ in the default
158+ [ Worker Preset] ( https://github.com/graphile/worker/blob/main/src/preset.ts ) .
159+
160+ ### Environment variables
177161
178162- ` GRAPHILE_WORKER_PAYLOAD_FORMAT ` &mdash ; the encoding that Graphile Worker
179- uses to pass the payload to the binary. Currently this will be the string
163+ used to pass the payload to the binary. Currently this will be the string
180164 ` json ` , but you should check this before processing the payload in case the
181165 format changes.
182166- ` GRAPHILE_WORKER_TASK_IDENTIFIER ` &mdash ; the identifier for the task this
@@ -198,40 +182,69 @@ Worker will see this as success, all other exit codes are seen as failure.
198182
199183In the JSON payload format, your binary will be fed via stdin
200184` JSON.stringify({payload}) ` ; for example, if you did
201- ` addJob('myScript ', {mol: 42}) ` then your ` myScript ` task would be sent
185+ ` addJob('my_script ', {mol: 42}) ` then your ` my_script ` task would be sent
202186` {"payload":{"mol":42}} ` via stdin.
203187
204188## Handling batch jobs
205189
206- If the payload is an array, then _ optionally_ your task may choose to return an
207- array of the same length, the entries in which are promises. Should any of these
208- promises reject, then the job will be re-enqueued, but the payload will be
209- overwritten to only contain the entries associated with the rejected promises
210- &mdash ; i.e. the successful entries will be removed.
190+ If the payload is an array, then _ optionally_ your task executor may choose to
191+ return an array of the same length, the entries in which are promises. Should
192+ any of these promises reject, then the job will be re-enqueued, but the payload
193+ will be overwritten to only contain the entries associated with the rejected
194+ promises &mdash ; i.e. the successful entries will be removed.
211195
212196## ` helpers `
213197
198+ ### ` helpers.abortPromise `
199+
200+ ** Experimental**
201+
202+ This is a promise that will reject when [ ` abortSignal ` ] ( #helpersabortsignal )
203+ aborts. This makes it convenient for exiting your task when the abortSignal
204+ fires: ` Promise.race([abortPromise, doYourAsyncThing()]) ` .
205+
206+ ### ` helpers.abortSignal `
207+
208+ ** Experimental**
209+
210+ This is a ` AbortSignal ` that will be triggered when the job should exit early.
211+ It is used, for example, for a graceful shutdown request. ` AbortSignal ` s can be
212+ passed to a number of asynchronous Node.js methods like
213+ [ ` http.request() ` ] ( https://nodejs.org/api/http.html#httprequesturl-options-callback ) .
214+
215+ ### ` helpers.addJob() `
216+
217+ See [ ` addJob ` ] ( /library/add-job.md ) .
218+
219+ ### ` helpers.addJobs() `
220+
221+ See [ ` addJobs ` ] ( /library/add-job.md#add-jobs ) .
222+
223+ ### ` helpers.getQueueName() `
224+
225+ Get the queue name of the given queue ID (or of the currently executing job if
226+ no queue ID is specified). This function may or may not return a promise. We
227+ recommend that you always ` await ` it.
228+
229+ ### ` helpers.job `
230+
231+ The whole, currently executing job, including ` uuid ` , ` attempts ` , etc.
232+
214233### ` helpers.logger `
215234
216- So that you may redirect logs to your preferred logging provider, we have
217- enabled you to supply your own logging provider. Overriding this is currently
218- only available in library mode (see [ Logger] ( /library/logger.md ) ). We then wrap
219- this logging provider with a helper class to ease debugging; the helper class
220- has the following methods:
235+ A logger instance scoped to this job. See [ Logger] ( ./library/logger )
221236
222- - ` error(message, meta?) ` : for logging errors, similar to ` console.error `
223- - ` warn(message, meta?) ` : for logging warnings, similar to ` console.warn `
224- - ` info(message, meta?) ` : for logging informational messages, similar to
225- ` console.info `
226- - ` debug(message, meta?) ` : to aid with debugging, similar to ` console.log `
227- - ` scope(additionalScope) ` : returns a new ` Logger ` instance with additional
228- scope information
237+ ### ` helpers.query() `
238+
239+ This is a convenience wrapper for
240+ ` withPgClient(pgClient => pgClient.query(sql, values)) ` . See
241+ [ ` withPgClient() ` ] ( #helperswithpgclient )
229242
230243### ` helpers.withPgClient() `
231244
232- ` withPgClient ` gets a ` pgClient ` from the pool, calls
233- ` await callback(pgClient) ` , and finally releases the client and returns the
234- result of ` callback ` . This workflow can make testing your tasks easier.
245+ ` withPgClient ` gets a ` pgClient ` from the pool that Graphile Worker uses. It
246+ calls ` await callback(pgClient) ` , and finally releases the client and returns
247+ the result of ` callback ` . This workflow can make testing your tasks easier.
235248
236249Example:
237250
@@ -249,19 +262,3 @@ keeping transactions open may decrease Graphile Worker's performance due to
249262increasing contention over the pool of database clients.
250263
251264:::
252-
253- ### ` helpers.addJob() `
254-
255- ``` ts
256- await helpers .addJob (identifier , payload , options );
257- ```
258-
259- See [ ` addJob ` ] ( /library/add-job.md ) .
260-
261- ### ` helpers.addJobs() `
262-
263- ``` ts
264- await helpers .addJobs (specs , preserveRunAt );
265- ```
266-
267- See [ ` addJobs ` ] ( /library/add-job.md#add-jobs ) .
0 commit comments