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.
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 schedule("@hourly", handler).
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
Hey Rob,
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!
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 pm2 and/or 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.
Implementing the tasks is pretty straight forward and I seem to be able to use services and database stuff without a problem.
Things I’m not happy with, but seem non breaking:
Importing stuff to a task in the script folder seems weird. As vscode doesn’t seem to figure out automatically, where to import stuff from.
I’m not fully sure, where packages get pulled from. It seems to work fine to import them in the package.json in the api folder. But it seems a bit out of control, it would be nice, if the scripts folder had it’s own package.json
Hi.
For somebody looking for async job worker working code examples, I created a sample implementation with graphile-worker and redwood.js.
It’s working beautifully at my local environment.