Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds background job scheduling and execution #11238

Merged
merged 272 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
272 commits
Select commit Hold shift + click to select a range
1de0a44
Use console if logger not yet, remove private #log() function
cannikin Jun 28, 2024
c927e35
Find job in any subdirectory of api/src/jobs
cannikin Jun 28, 2024
8b12c77
Comment loaders
cannikin Jun 28, 2024
d8fbab0
Import setTimeout
cannikin Jun 28, 2024
91ca380
Remove index file in adapters
cannikin Jun 28, 2024
192e929
Comments, remove unused args
cannikin Jun 28, 2024
7d90508
Convert sqlite query to regular prisma calls
cannikin Jun 28, 2024
f6caf73
Update worker debug message to include queue name being searched
cannikin Jun 28, 2024
67fb339
Comments
cannikin Jun 28, 2024
626bcee
Make sure await imports work on windows
cannikin Jun 28, 2024
0b4222b
Fix some jest -> vi mocking differences
cannikin Jun 28, 2024
54315c8
Don’t load ENV files in worker.js for now
cannikin Jun 28, 2024
328d341
Placeholder tests
cannikin Jun 28, 2024
0fddf26
Fix vitest watch
cannikin Jun 28, 2024
4c28c64
Remove scenarios file
cannikin Jun 28, 2024
745febe
Fix PrismaAdapter tests
cannikin Jun 29, 2024
88a7c41
Finishes PrismaAdapter.schedule() tests
cannikin Jul 1, 2024
f2d83d4
Refactor .find() for just the single default query
cannikin Jul 2, 2024
ae59600
Rename bins
cannikin Jul 2, 2024
f9073ee
Remove unneeded awaits
cannikin Jul 3, 2024
6693d5f
Convert loaders to TS
cannikin Jul 3, 2024
c4c822f
Add TS to BaseAdapter, add separate types file for shared types
cannikin Jul 3, 2024
cccf759
Add TS to Executor
cannikin Jul 3, 2024
b8247b8
Comments on types
cannikin Jul 3, 2024
a121a89
Switches PrismaAdapter to TS
cannikin Jul 4, 2024
83f4770
Update tests to it() instead of test(), reword a couple tests
cannikin Jul 7, 2024
d46dda8
PrismaAdapter should return the records that were created/edited/dele…
cannikin Jul 7, 2024
a866761
Adds changeset
cannikin Jul 8, 2024
ae38c44
Enable dual build?
cannikin Jul 8, 2024
825076e
Always await PrismaAdapter responses
cannikin Jul 8, 2024
8b683cf
Fix return type
cannikin Jul 8, 2024
df5e702
Convert errors to TS
cannikin Jul 8, 2024
e6065da
Converts Worker to TS
cannikin Jul 8, 2024
b3a2181
Fix test
cannikin Jul 8, 2024
620698b
Queue can be `null` meaning "work on any queue"
cannikin Jul 8, 2024
495ee80
Converts RedwoodJob to TS
cannikin Jul 8, 2024
fbfa697
Converts node scripts to TS, couple unknowns for Tobbe (marked TODO T…
cannikin Jul 8, 2024
71e812d
Have rw-log-formatter listen for SIGINT and exit with a 0 (default ex…
cannikin Jul 9, 2024
a845a87
Remove "Received SIGINT signal, existing..." output message from tele…
cannikin Jul 9, 2024
b932013
Add `yarn rw jobs` cli command to invoke `yarn rw-jobs`
cannikin Jul 9, 2024
bf9272d
Stricter types
Tobbe Jul 10, 2024
fde562f
loadEnvFiles
Tobbe Jul 10, 2024
367b921
Merge branch 'main' into rc-background-jobs
Tobbe Jul 10, 2024
ba073f8
chore(cli-helpers): loadEnvFiles cleanup (#10935)
Tobbe Jul 10, 2024
bfccf26
Merge branch 'main' into rc-background-jobs
Tobbe Jul 10, 2024
6210532
Remove accidentally added code
Tobbe Jul 10, 2024
3bda79d
Merge branch 'main' into rc-background-jobs
Tobbe Jul 10, 2024
bf9f093
Undo random code change
Tobbe Jul 10, 2024
33855d0
Adds `yarn rw setup jobs` command
cannikin Jul 10, 2024
06c910b
Adds @ts-expect-error when setting process.title
cannikin Jul 10, 2024
ea7ac96
Be sure to include ENV when forking workers
cannikin Jul 10, 2024
dff8343
Revert 'import * as'
Tobbe Jul 10, 2024
571fce4
Merge branch 'main' into rc-background-jobs
cannikin Jul 10, 2024
9290165
Don't import * as it makes process.title read-only
cannikin Jul 10, 2024
c8161cd
Update error message when api/src/lib/jobs.js not found
cannikin Jul 10, 2024
aa1269b
Add BackgroundJob database table during setup command
cannikin Jul 10, 2024
8106bf4
Support TS jobs
Tobbe Jul 11, 2024
003e4e2
parseArgs full names
Tobbe Jul 11, 2024
0a613ab
Abstract RedwoodJobs
Tobbe Jul 11, 2024
4d7280c
Update types for setting process, remove TODO
cannikin Jul 11, 2024
5a521b0
Remove TODO
cannikin Jul 11, 2024
605ade5
Allow `queue` to be null
cannikin Jul 11, 2024
df241b3
Adds `yarn rw g job` generator
cannikin Jul 12, 2024
9581ea6
Merge branch 'main' into rc-background-jobs
cannikin Jul 12, 2024
714189b
Switch to `enable` to skip model creation steps altogether, cleanup o…
cannikin Jul 12, 2024
8dc207c
Switch to `enable` to skip model creation steps altogether, cleanup o…
cannikin Jul 12, 2024
5dd7b8e
Start of job docs
cannikin Jul 12, 2024
01cea5a
Add new job to lib/jobs config
cannikin Jul 13, 2024
5fb4180
Remove accessor from PrismaAdapterOptions
cannikin Jul 13, 2024
eaa6091
Add a couple TODOs
cannikin Jul 13, 2024
8bd6bc7
Move default priority to a constant
cannikin Jul 13, 2024
5561e82
Start of job docs
cannikin Jul 13, 2024
3c74c4f
Remove migrate command, add to output message
cannikin Jul 18, 2024
0a19463
Update exit message
cannikin Jul 18, 2024
ecd1e32
Use skip instead of enable
cannikin Jul 18, 2024
aaa6a31
Pass the maxAttemps, maxRuntime and deleteFailedJobs options to the a…
cannikin Jul 18, 2024
35965f8
Adds error for missing config file, show proper filename
cannikin Jul 19, 2024
07805aa
Adds loadWorkerConfig, removes loadAdapter and loadLogger
cannikin Jul 19, 2024
0cfc832
Get logger from workerConfig
cannikin Jul 19, 2024
59854c2
Passed named workerConfig to worker script
cannikin Jul 19, 2024
a546ffd
Adds additional options and passes them to Executor
cannikin Jul 19, 2024
2ff2c05
Accept new options and use
cannikin Jul 19, 2024
88fa4a7
Updates PrismaAdapter tests
cannikin Jul 19, 2024
0e2d0c7
Make sure sleepDelay is turned into milliseconds
cannikin Jul 19, 2024
ada86e9
Updates Worker, Executor tests
cannikin Jul 19, 2024
7427ca7
Updates RedwoodJob tests
cannikin Jul 19, 2024
46ce8a5
Add tests for new worker default settings
cannikin Jul 19, 2024
20730b4
Update Executor to use merged default options
cannikin Jul 23, 2024
102d76e
RedwoodJob: TS private syntax
Tobbe Jul 24, 2024
a0118d8
RedwoodJob: declare constructor type
Tobbe Jul 24, 2024
5678061
RedwoodJob: Reenable exception tests
Tobbe Jul 24, 2024
0e11524
Adapter TypeScript tests
Tobbe Jul 24, 2024
035ef23
RedwoodJob.ts: Fix comment after myOptions rename
Tobbe Jul 12, 2024
e1ef77a
RedwoodJob TS test
Tobbe Jul 24, 2024
e40715a
Check for logger and fall back to console
cannikin Jul 24, 2024
679c387
Mock console to quiet down test output
cannikin Jul 24, 2024
a952c52
Update jobs setup template
cannikin Jul 24, 2024
b54d753
Better options types for Worker and Executor, export a couple of type…
cannikin Jul 24, 2024
fba419c
Remove .js test files
cannikin Jul 24, 2024
1306e31
Silence log messages in test suite
cannikin Jul 24, 2024
928a921
Prettify and lint jobs config file after generator adds imports/exports
cannikin Jul 24, 2024
499439f
Refactor, getters for all options, options back to REAL private, move…
cannikin Jul 25, 2024
7854c80
Runner script refactor: accept most config options as command line fl…
cannikin Jul 25, 2024
e68567e
Can pass name of adapter and logger to use in individual workers
cannikin Jul 25, 2024
767e139
Load jobs and job config from /dist in production
cannikin Jul 26, 2024
5e79641
Update job setup template
cannikin Jul 26, 2024
7efdbd2
Docs looking good
cannikin Jul 26, 2024
20edfeb
Update setup template
cannikin Jul 26, 2024
4656eb0
Have loaders look at NODE_ENV as to whether to load from src or dist
cannikin Jul 26, 2024
e31c66a
Add NODE_ENV to .env.defaults when you setup jobs?
cannikin Jul 26, 2024
12bb920
Merge branch 'main' into rc-background-jobs
cannikin Jul 26, 2024
2f81947
Send arguments as an array
cannikin Jul 26, 2024
f3d1521
yarn install
cannikin Jul 26, 2024
942eba2
Update dependency versions
cannikin Jul 26, 2024
9f2034b
Fix lint warnings
cannikin Jul 26, 2024
9275839
Update packages/jobs/src/adapters/PrismaAdapter.ts
cannikin Jul 27, 2024
889228a
Update packages/jobs/src/core/consts.ts
cannikin Jul 27, 2024
b41ad99
Update packages/jobs/src/core/consts.ts
cannikin Jul 27, 2024
2d5c7c8
Update packages/jobs/src/core/consts.ts
cannikin Jul 27, 2024
f0cbdb8
Update packages/jobs/src/core/consts.ts
cannikin Jul 27, 2024
cbbbdae
Update packages/jobs/src/core/errors.ts
cannikin Jul 27, 2024
7c77298
Tobbe review changes
Tobbe Jul 27, 2024
f0db8bd
Switch to tstyche
Tobbe Jul 27, 2024
b869578
Better types
Tobbe Jul 28, 2024
13704f5
more tests, some that fail
Tobbe Jul 28, 2024
a5d4027
Rename "hander" to "job"
cannikin Aug 2, 2024
ae62078
Adds errors
cannikin Aug 2, 2024
b07615d
Always load from api/dist
cannikin Aug 2, 2024
0bb3d5a
Start of rewrite for new design
cannikin Aug 2, 2024
2bc24c6
Moves shared files to root
cannikin Aug 5, 2024
9e302e4
Removes unused types
cannikin Aug 5, 2024
909e28d
Update import from moved files
cannikin Aug 5, 2024
53394d6
Just get this building
cannikin Aug 5, 2024
1148493
Updates for new worker config
cannikin Aug 5, 2024
35bddeb
initial typing stuff
Josh-Walker-GM Aug 3, 2024
b364ede
Merge remote-tracking branch 'origin/rc-background-jobs' into rc-back…
Josh-Walker-GM Aug 6, 2024
08f1b9a
basic case plugin
Josh-Walker-GM Aug 6, 2024
0f0d149
Update jobs setup template
cannikin Aug 7, 2024
588500f
Sort of fix loadEnvFiles? 😬
cannikin Aug 7, 2024
3e691ba
NodeNext
cannikin Aug 7, 2024
b98a8d4
ts-expect-error on CJS/ESM stuff
cannikin Aug 7, 2024
d89ab82
Update adapters for new format
cannikin Aug 7, 2024
4acf789
Remove type export in index
cannikin Aug 7, 2024
781e1ad
Update loads for new job design
cannikin Aug 7, 2024
b7faeaf
Job worker script updates
cannikin Aug 7, 2024
c981769
Worker and Executor updates for new job structure
cannikin Aug 7, 2024
4a385c2
Updates BaseAdapter and PrismaAdapter to have similar method signatur…
cannikin Aug 8, 2024
57ace06
Updates Executor to make the call between adapter.error() and adapter…
cannikin Aug 9, 2024
38ac0f4
Updates Worker with new options, updates tests
cannikin Aug 9, 2024
8853142
Adds missing queues error
cannikin Aug 9, 2024
0e6a67f
Updates Executor log messages
cannikin Aug 9, 2024
8da268d
Remove unused import
cannikin Aug 9, 2024
1daf9f3
Update mocks
cannikin Aug 9, 2024
b783022
Updates Worker and Executor tests
cannikin Aug 9, 2024
4d049e4
Remove need to mock isTypescriptProject()
cannikin Aug 9, 2024
aeb9de0
Updated types
cannikin Aug 9, 2024
b3efb19
Add JobManager tests
cannikin Aug 9, 2024
29268bc
Remove debug
cannikin Aug 9, 2024
2ce3b42
Remove old tests
cannikin Aug 9, 2024
ebe7d39
Reset mocks properly in Worker tests
cannikin Aug 9, 2024
08ace15
Start of Scheduler tests
cannikin Aug 9, 2024
a23c975
remove fast-glob dep
Josh-Walker-GM Aug 10, 2024
5469738
add required package during setup
Josh-Walker-GM Aug 10, 2024
1a3c46c
update job generator
Josh-Walker-GM Aug 10, 2024
002fc8c
cast to allow successful build
Josh-Walker-GM Aug 10, 2024
ceba0a7
move and minor refactor BaseAdapter
Josh-Walker-GM Aug 10, 2024
32a8717
move and minor refactor PrismaAdapter
Josh-Walker-GM Aug 10, 2024
3723f3a
move prisma specific error
Josh-Walker-GM Aug 10, 2024
5041998
update executor
Josh-Walker-GM Aug 10, 2024
636c22c
fix jobs having name and path
Josh-Walker-GM Aug 10, 2024
11bcf95
add await to fix bins
Josh-Walker-GM Aug 10, 2024
14d5c87
fix prisma adapter tests
Josh-Walker-GM Aug 10, 2024
cbdf2d5
update comments
Josh-Walker-GM Aug 10, 2024
06978d0
remove type testing package for now
Josh-Walker-GM Aug 10, 2024
f1242bb
Merge branch 'main' into rc-background-jobs
Josh-Walker-GM Aug 10, 2024
333f6a2
fix deps
Josh-Walker-GM Aug 10, 2024
505e175
actually fix deps
Josh-Walker-GM Aug 10, 2024
054ebbb
Updates log messages to be consistent
cannikin Aug 12, 2024
d7bc65a
Scheduler tests
cannikin Aug 12, 2024
0314521
Update signature for computeRunAt to be an object
cannikin Aug 12, 2024
2bd6cad
Await response to scheduling before returning `true`
cannikin Aug 12, 2024
b25a278
Fix DEFAULT_LOGGER usage and [RedwoodJob] prefix
cannikin Aug 13, 2024
88db895
Add adapter exports
cannikin Aug 13, 2024
d2f59ee
Fix/remove TODOs
cannikin Aug 13, 2024
f39ae36
Add @prisma/client as dev dependency
cannikin Aug 13, 2024
594ab3e
Remove unused babel mock
cannikin Aug 13, 2024
3b61b8e
Move worker instantiation to JobManager
cannikin Aug 13, 2024
484da82
Update command line flag descriptions
cannikin Aug 13, 2024
83ca4e6
Don’t execute script if imported in test env
cannikin Aug 13, 2024
3c7432e
Reorg imports
cannikin Aug 13, 2024
9749bee
Fix types in Worker
cannikin Aug 13, 2024
7dc7e60
Use completeJobPath to test if file exists
cannikin Aug 13, 2024
b250186
Update templates
cannikin Aug 13, 2024
688b0a5
loadEnvFiles in jobs worker, switch to warn() level for startup logs
cannikin Aug 13, 2024
0b39586
Fix script name
cannikin Aug 13, 2024
5b27f31
Adds changeset
cannikin Aug 13, 2024
3ececde
Removes comment
cannikin Aug 13, 2024
9ca39cd
Adds `id` as a required PossibleJob attribute
cannikin Aug 13, 2024
d803d7a
Use job.id and unique job identifier string in log messages
cannikin Aug 13, 2024
65c4aa5
Merge branch 'main' into rc-background-jobs
cannikin Aug 13, 2024
c86d7dc
Remove NODE_ENV insert in jobs setup
cannikin Aug 13, 2024
0c00238
update deps
Josh-Walker-GM Aug 13, 2024
3566f63
Merge remote-tracking branch 'origin/main' into rc-background-jobs
Josh-Walker-GM Aug 19, 2024
406033e
update paths test snapshot
Josh-Walker-GM Aug 19, 2024
f5be93e
remove unneeded includes
Josh-Walker-GM Aug 19, 2024
8c67e4d
update tsconfig
Josh-Walker-GM Aug 19, 2024
bcf658f
switch comments to jsdoc
Josh-Walker-GM Aug 19, 2024
08596c3
initial lint
Josh-Walker-GM Aug 19, 2024
2c6f3ed
format
Josh-Walker-GM Aug 19, 2024
47a1b88
remove cjs/esm hack
Josh-Walker-GM Aug 19, 2024
e672f55
don't skip placeholder test
Josh-Walker-GM Aug 19, 2024
1e8aa72
add missing word
Josh-Walker-GM Aug 19, 2024
1624c5c
Merge remote-tracking branch 'origin/main' into rc-background-jobs
Josh-Walker-GM Aug 19, 2024
fccb823
TEMP: track dist
Josh-Walker-GM Aug 19, 2024
1b3b4ac
update build
Josh-Walker-GM Aug 19, 2024
eef2363
add relative extensions
Josh-Walker-GM Aug 19, 2024
d7e8e5a
untrack dist
Josh-Walker-GM Aug 19, 2024
36fd31e
add queue and update cli test snapshot
Josh-Walker-GM Aug 19, 2024
5c5ffd6
Start of jobs docs update
cannikin Aug 19, 2024
7def462
More jobs docs
cannikin Aug 19, 2024
1506a9d
First draft of new jobs doc
cannikin Aug 19, 2024
e0c198e
Update script examples
cannikin Aug 19, 2024
5696a39
Doc updates
cannikin Aug 19, 2024
cd9fc6b
Jobs docs looking good
cannikin Aug 20, 2024
ae767b5
Add comment about queues to setup template
cannikin Aug 20, 2024
421b9d9
Use mockLogger from core mocks
cannikin Aug 20, 2024
192e6a5
Reorganize cases
cannikin Aug 20, 2024
0bee631
Adds tests for rw-jobs
cannikin Aug 20, 2024
1de3bd9
Merge remote-tracking branch 'origin/main' into rc-background-jobs
Josh-Walker-GM Aug 20, 2024
0a1d82c
use underline for link styling
Josh-Walker-GM Aug 20, 2024
5b1c7ea
update deps and building
Josh-Walker-GM Aug 20, 2024
13b2458
ensure tests are ts
Josh-Walker-GM Aug 20, 2024
d958e5f
log heap usage
Josh-Walker-GM Aug 21, 2024
446ea5d
update util mocks
Josh-Walker-GM Aug 21, 2024
45b8663
update worker test
Josh-Walker-GM Aug 21, 2024
6ae9f5f
update executor test
Josh-Walker-GM Aug 21, 2024
1a5b91b
update job manager test
Josh-Walker-GM Aug 21, 2024
26e51d0
update schedular test
Josh-Walker-GM Aug 21, 2024
f44fe04
revert cli-helpers change
Josh-Walker-GM Aug 21, 2024
b19cfff
misc docs updates
Josh-Walker-GM Aug 21, 2024
e89363f
fix __dirname and cjs typegen issue
Josh-Walker-GM Aug 21, 2024
f5a579c
Rewrite docs for type
cannikin Aug 20, 2024
b48bf1c
Add demandCommand() to jobs cli
cannikin Aug 21, 2024
1a3181f
Merge remote-tracking branch 'origin/rc-background-jobs' into rc-back…
Josh-Walker-GM Aug 21, 2024
fbf7e51
remove stray comment
Josh-Walker-GM Aug 21, 2024
bdb0807
Back to strict options
cannikin Aug 21, 2024
e13464d
Check for first command so that starting with `yarn rw jobs` and `yar…
cannikin Aug 21, 2024
1d48740
Replace command name in rw-jobs so help output matches actual yarn co…
cannikin Aug 21, 2024
401a8d5
Make --index and --id required
cannikin Aug 21, 2024
9b12601
Merge branch 'main' into rc-background-jobs
Josh-Walker-GM Aug 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .changesets/11238.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- Adds background job scheduling and execution (#10906) by @cannikin

This new package provides scheduling and processing of background jobs. We want everything needed to run a modern web application to be included in Redwood itself—you shouldn't need any third party integrations if you don't want.

Background jobs have been sorely missed, but the time has come! (If you do want to use a third party service we have had an [integration with Inngest](https://community.redwoodjs.com/t/ship-background-jobs-crons-webhooks-and-reliable-workflows-in-record-time-with-inngest-and-redwoodjs/4866) since May of 2023!)

## Features

- Named queues: you can schedule jobs in separate named queues and have a different number of workers monitoring each one—makes it much easier to scale your background processing
- Priority: give your jobs a priority from 1 (highest) to 100 (lowest). Workers will sort available jobs by priority, working the most important ones first.
- Configurable delay: run your job as soon as possible (default), wait a number of seconds before running, or run at a specific time in the future
- Auto-retries with backoff: if your job fails it will back off at the rate of attempts \*\* 4 for a default of 24 tries, the time between the last two attempts is a little over three days.
- Run inline: instead of scheduling to run in the background, run immediately
- Integrates with Redwood's [logger](https://docs.redwoodjs.com/docs/logger): use your existing one in api/src/lib/logger or create a new one just for job logging
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"baremetal",
"bazinga",
"corepack",
"daemonized",
"envinfo",
"execa",
"Fastify",
Expand Down
744 changes: 744 additions & 0 deletions docs/docs/background-jobs.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ module.exports = {
{ type: 'doc', id: 'auth/supertokens' },
],
},
'background-jobs',
'builds',
'cells',
'cli-commands',
Expand Down
Binary file added docs/static/img/background-jobs/jobs-after.png
cannikin marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/background-jobs/jobs-before.png
cannikin marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/background-jobs/jobs-db.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/background-jobs/jobs-queues.png
cannikin marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
cannikin marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/background-jobs/jobs-workers.png
cannikin marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions packages/api-server/src/logFormatter/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@ const input = process.stdin
const output = process.stdout

input.pipe(split(LogFormatter())).pipe(output)

// assume that receiving a SIGINT (Ctrl-C) is a normal event, so don't exit with
// a 129 error code, which makes execa blow up. Just return a nice quiet 0.
process.on('SIGINT', () => {
process.exit(0)
})
7 changes: 7 additions & 0 deletions packages/babel-config/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import pluginRedwoodContextWrapping from './plugins/babel-plugin-redwood-context
import pluginRedwoodDirectoryNamedImport from './plugins/babel-plugin-redwood-directory-named-import'
import pluginRedwoodGraphqlOptionsExtract from './plugins/babel-plugin-redwood-graphql-options-extract'
import pluginRedwoodImportDir from './plugins/babel-plugin-redwood-import-dir'
import pluginRedwoodJobPathInjector from './plugins/babel-plugin-redwood-job-path-injector'
import pluginRedwoodOTelWrapping from './plugins/babel-plugin-redwood-otel-wrapping'

export const TARGETS_NODE = '20.10'
Expand Down Expand Up @@ -178,6 +179,12 @@ export const getApiSideBabelOverrides = ({ projectIsEsm = false } = {}) => {
],
],
},
// Add import names and paths to job definitions
{
// match */api/src/jobs/*.js|ts
test: /.+api(?:[\\|/])src(?:[\\|/])jobs(?:[\\|/]).+.(?:js|ts)$/,
plugins: [[pluginRedwoodJobPathInjector]],
},
].filter(Boolean)
return overrides as TransformOptions[]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import fsPath from 'node:path'

import type { PluginObj, types } from '@babel/core'

import { getPaths } from '@redwoodjs/project-config'

// This plugin is responsible for injecting the import path and name of a job
// into the object that is passed to createJob. This is later used by adapters
// and workers to import the job.

export default function ({ types: _t }: { types: typeof types }): PluginObj {
const paths = getPaths()
return {
name: 'babel-plugin-redwood-job-path-injector',
visitor: {
ExportNamedDeclaration(path, state) {
// Extract the variable declaration from the export
const declaration = path.node.declaration
if (!declaration) {
return
}
if (declaration.type !== 'VariableDeclaration') {
return
}
// Extract the variable declarator from the declaration
const declarator = declaration.declarations[0]
if (!declarator) {
return
}
if (declarator.type !== 'VariableDeclarator') {
return
}

// Confirm that the init it a call expression
const init = declarator.init
if (!init) {
return
}
if (init.type !== 'CallExpression') {
return
}
// Confirm that the callee is a member expression
const callee = init.callee
if (!callee) {
return
}
if (callee.type !== 'MemberExpression') {
return
}
// The object is imported and so could be aliased so lets check the property
const property = callee.property
if (!property) {
return
}
if (property.type !== 'Identifier') {
return
}
if (property.name !== 'createJob') {
return
}

// From this point on we're confident that we're looking at a createJob call
// so let's start throwing errors if we don't find what we expect

// Extract the variable name from the declarator
const id = declarator.id
if (!id) {
return
}
if (id.type !== 'Identifier') {
return
}

const filepath = state.file.opts.filename
if (!filepath) {
throw new Error('No file path was found in the state')
}

const importName = id.name
const importPath = fsPath.relative(paths.api.jobs, filepath)
const importPathWithoutExtension = importPath.replace(/\.[^/.]+$/, '')

// Get the first argument of the call expression
const firstArg = init.arguments[0]
if (!firstArg) {
throw new Error('No first argument found in the createJob call')
}
// confirm it's an object expression
if (firstArg.type !== 'ObjectExpression') {
throw new Error(
'The first argument of the createJob call is not an object expression',
)
}
// Add a property to the object expression
firstArg.properties.push(
_t.objectProperty(
_t.identifier('path'),
_t.stringLiteral(importPathWithoutExtension),
),
)
firstArg.properties.push(
_t.objectProperty(
_t.identifier('name'),
_t.stringLiteral(importName),
),
)
},
},
}
}
2 changes: 1 addition & 1 deletion packages/cli-helpers/src/lib/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ export const colors = {
tip: chalk.green,
important: chalk.magenta,
caution: chalk.red,
link: chalk.hex('#e8e8e8'),
link: chalk.underline,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Single word default files > creates a single word function file > Scenario snapshot 1`] = `
"import type { ScenarioData } from '@redwoodjs/testing/api'

export const standard = defineScenario({
// Define the "fixture" to write into your test database here
// See guide: https://redwoodjs.com/docs/testing#scenarios
})

export type StandardScenario = ScenarioData<unknown>
"
`;

exports[`Single word default files > creates a single word function file > Test snapshot 1`] = `
"import { SampleJob } from './SampleJob'

describe('SampleJob', () => {
it('should not throw any errors', async () => {
await expect(SampleJob.perform()).resolves.not.toThrow()
})
})
"
`;

exports[`Single word default files > creates a single word function file 1`] = `
"import { jobs } from 'src/lib/jobs'

export const SampleJob = jobs.createJob({
queue: 'default',
perform: async () => {
jobs.logger.info('SampleJob is performing...')
},
})
"
`;

exports[`multi-word files > creates a multi word function file 1`] = `undefined`;
86 changes: 86 additions & 0 deletions packages/cli/src/commands/generate/job/__tests__/job.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
globalThis.__dirname = __dirname
// Load shared mocks
import '../../../../lib/test'

import path from 'path'

import { describe, it, expect } from 'vitest'

import * as jobGenerator from '../job'

// Should be refactored as it's repeated
type WordFilesType = { [key: string]: string }

describe('Single word default files', async () => {
const files: WordFilesType = await jobGenerator.files({
name: 'Sample',
queueName: 'default',
tests: true,
typescript: true,
})

it('creates a single word function file', () => {
expect(
files[
path.normalize('/path/to/project/api/src/jobs/SampleJob/SampleJob.ts')
],
).toMatchSnapshot()

expect(
files[
path.normalize(
'/path/to/project/api/src/jobs/SampleJob/SampleJob.test.ts',
)
],
).toMatchSnapshot('Test snapshot')

expect(
files[
path.normalize(
'/path/to/project/api/src/jobs/SampleJob/SampleJob.scenarios.ts',
)
],
).toMatchSnapshot('Scenario snapshot')
})
})

describe('multi-word files', () => {
it('creates a multi word function file', async () => {
const multiWordDefaultFiles = await jobGenerator.files({
name: 'send-mail',
queueName: 'default',
tests: false,
typescript: true,
})

expect(
multiWordDefaultFiles[
path.normalize(
'/path/to/project/api/src/functions/SendMailJob/SendMailJob.js',
)
],
).toMatchSnapshot()
})
})

describe('generation of js files', async () => {
const jsFiles: WordFilesType = await jobGenerator.files({
name: 'Sample',
queueName: 'default',
tests: true,
typescript: false,
})

it('returns tests, scenario and job file for JS', () => {
const fileNames = Object.keys(jsFiles)
expect(fileNames.length).toEqual(3)

expect(fileNames).toEqual(
expect.arrayContaining([
expect.stringContaining('SampleJob.js'),
expect.stringContaining('SampleJob.test.js'),
expect.stringContaining('SampleJob.scenarios.js'),
]),
)
})
})
Loading
Loading