Closed daisycrego closed 3 years ago
bull
to manage the queued jobs./events/api/fub/callback
.Reading the code to understand how this works:
Code here
This is getting too long, I created a wiki
Now I understand how the example app works. It uses Node Foreman
to actually run 2 processes. 1 process is to handle the workers, and supports clustering at scale (although we'll still be using a low-level Heroku dyno in this implementation, it could support scaling).
In the worker
process (worker.js
) throng
is a worker manager for clustered Node.js apps. We don't really need a clustered Node.js app, but having the infrastructure is useful, so we won't explicitly remove that. Also, throng is touted as a "dead-simple one-liner for clustered Node.js apps. It "forks N workers and creates new ones if they go down". We define a
startmethod which we pass to
throng, and
throngwill create multiple clusters and call
starton each of them. The number of worker processes (the number of clusters) is going to be either
process.env.WEB_CONCURRENCY, which is set by Heroku based on your dyno, or
2if that isn't set. You can play around with the value of
workers` if you're trying to take advantage of more CPU cores.
Within start
we have the interesting part of worker.js
. We define a process for the Queue
, workQueue
, to perform whatever the job is and return a value once the job is done.
That's it. Now we can initialize a Queue
using the same REDIS_URL
in the web
process (server.js
) so that we can add
jobs to the Queue
, now that process
is defined so we have something to do with the job. And we can also check the state of the job from another route in the web
process to send that data back to the UI when it called the updateJobs
method.
Adding this to the existing codebase shouldn't be too crazy. But we are somewhat changing the hierarchy of this app, so we need to go back to understanding how the package.json
works currently before we just expect we can add Node Foreman
into the mix with no hassles.
Integrated the basics of the bull
work queue by adding a new worker process and some client-side code (currently injected in template.js
but I can move it to somewhere else when I do the refactoring). At least was able to work around the concerns I had of making Node Foreman work with webpack. It all seems to work ok. And the jobs seem to be successfully created and then completed.
Defining the background process, here is the skeleton:
workQueue.process(maxJobsPerWorker, async (job) => {
console.log(`Initiating a job in the worker process`);
console.log(`job.data:`);
console.log(job.data);
// This is an example job that just slowly reports on progress
// while doing no work. Replace this with your own job logic.
let progress = 0;
job.progress(progress);
// do the work here
// check if the event already exists
// define the status of the event -> newLead, existingLead
// send an alert if the status of the event === existingLead && source == Zillow or Zillow Flex
// create a new Event object
/*
incoming job.data will look like this:
{
eventId: 'dc6d4d68-f27a-4940-bd10-e60b4fe3b5dc',
eventCreated: '2021-05-30T21:46:02+00:00',
event: 'eventsCreated',
resourceIds: [ 90490 ],
uri: 'https://api.followupboss.com/v1/events/90490'
}
*/
progress = 100;
job.progress(progress);
// A job can return values that will be stored in Redis as JSON
// This return value is unused in this demo application.
return { value: "This will be stored" };
});
}
The job will expect the following data:
{
eventId: 'dc6d4d68-f27a-4940-bd10-e60b4fe3b5dc',
eventCreated: '2021-05-30T21:46:02+00:00',
event: 'eventsCreated',
resourceIds: [ 90490 ],
uri: 'https://api.followupboss.com/v1/events/90490'
}
uri
field is missing AND the resourceIds
array is empty, log that the job has failed.uri
for the rest of the event data (should include personId
)personId
to fetch the rest of the person data, to determine if this is a new lead or not. /api/events/fub/callback
route, successfully runs and retrieves (1) extra event data, (2) person data to determine if this is a new lead, and then determines if an email should be sent to alert the admins this is a possible Zillow exemption. Either way, the important (really arbitrarily decided by me, could be changed) parts of the event data are stored in our own database, so we can follow up on these events. Modified the logic to only send emails for "Zillow Flex" leads. Now we can set the email alert system for a time and let it run, see if it works. The Log
s can also be used to backtrack.
Background Jobs in Node.js with Redis
Redis
How does Redis work?
Redis - Popular Use Cases
Caching
Chat, messaging, and queues
Gaming leaderboards
Session store
Install Redis