Maybe you want to send emails, process data, run some lengthly calculations, fan out tasks to/from a queue. How would I do that with RedwoodJS? Truth be told, the long running and/or scheduled job has been a missing piece in the Jamstack puzzle for some time.
Bear in mind that you can deploy your RedwoodJS app to a serverless (Netlify, Vercel) or a serverful (Render, bare metal) provider. In the serverless world, lambdas only run for a short time – typically 10 seconds. So, your job you have to run rather quick.
Thankfully, there are now some options.
If you deploy to a serverful context, like Render then you do have access to cron, redis, and a job runner that can perform these tasks. You may want to consider Creating a Background Worker with Exec and Faktory and Redwood’s exec script CLI command.
Netlify’s background functions allow you to set up serverless function processes that run longer than 10 seconds and up to 15 minutes.
Supabase offers cron inside Postgres where you can schedule requests that RedwoodJS can consume via a signed, secure webhook. It’s a great fit for that asynchronous background Netlify function.
Want integrated cron? Netlify recently added scheduled functions that enable you to run them on a regular and consistent schedule, much like a cron job. But, you can define that schedule in code like
Repeater is a Job Queue as a Service … service. It provides an API for you to schedule tasks that will call an http endpoint to run (similar to the Supabase cron approach).
bare metal job running option TODO: @rob can you explain this? As done in Algostake
I’m going to be updating the baremetal deploy docs with this info soon, but here’s the Stack Overflow post that I used to unlock the magic! How to make a task job with PM2? - Stack Overflow
Note that you don’t have to use the baremetal deploy option to do this, but you do need a real server that you can connect to and run pm2.
Also Ryan Chenkie wrote up how to uses queues with RedwoodJS!
this is great and all, but it just focuses on the deployment. I am still wondering how I can “mock” the production server on my local.
Thing is: I’d like to implement a scheduler/cron job that executes one of my scripts/ on a regular basis - and I would like to test this on my local before moving to deploy on production. Is that possible?
I have researched a bunch and my blocker comes down to the non-existence of a Service.ts or similar, basically where the App starts and where I could initialize the cron service.
Or is the solution to create a wholly new service myself, write the pm2 launch config and let my redwood service interact with my custom written scheduler service?
Any advice would be much appreciated. I’ve also seen a request for a first-level support for cron jobs and just want to give that suggestion a +1!
Love redwood, keep rocking
I think I figured it out, here is how I handle the cron jobs on my local now (the same thing should work for any baremetal linux server):
- Install and setup a cronjob manager, I opted for
cronie as described in the Arch Wiki
- Then added a new crontab with
crontab -e and added the following:
*/5 * * * * cd /path/to/my/redwood/project && /usr/bin/yarn rw exec nameOfScript
- Now, when I check the
systemctl status cronie I can see the output of my script, indicating that it has run.
Pretty basic, somewhat a workaround, since we don’t have the “classical” cron implementation for NodeJS. But seems to be more in line with the Redwood design.
Something like this could be used for syncing from an external service once a day. Just put the functionality in the script and call it with the crontab at the desired time.
I was thinking something similar but if the job was a Webhook, to use a tunneler like
ngrok and then have the cron job make a http request to the hook.
But, having the cron task be a script exec make perfect sense.
Nice! I’ve got an open issue for adding recurring jobs to
cron, but I didn’t have any plan for getting them running locally with a scheduler: whenever I had them in previous apps I wouldn’t have them actually running on recurring basis locally, I’d just start/stop them off on an as-needed basis to make sure they’re working. Having them in
cron locally means they’d be running forever which wasn’t ideal.
So I’d just manually run
yarn rw exec scriptName when I need to have the job run.
But maybe another process, like the api and web servers, that will start with
yarn rw dev and only run while that command is running…that’d be great for simulating a persistent runner, but without eating up resources even when the rest of the app isn’t running. And it just runs
yarn rw exec scriptName for you on whatever schedule.
Task scheduling is the obvious call out here, but if you ever consider doing some baked into Redwood implementation for task scheduling, I hope it wont be overkill to consider doing it based on a work queue with a scheduled fallback so that you have the option of firing off a worker prior to the scheduled check if the work queue gets too full. The example I can think of here is Flume where it sends logs in batches when the batch is full, but if the batch never gets full due to a lull in traffic, you still have a minimum SLA met by a scheduler that will take care of whatever work is available.