daisycrego / jbg-admin

Admin app for Jill Biggs Group follow-up boss event management
1 stars 0 forks source link

Redis - Run background process for every `eventsCreated` webhook POST #7

Closed daisycrego closed 3 years ago

daisycrego commented 3 years ago

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

daisycrego commented 3 years ago

Todo

daisycrego commented 3 years ago

Reading the code to understand how this works:

Screen Shot 2021-05-29 at 7 47 54 PM
daisycrego commented 3 years ago

Code here

daisycrego commented 3 years ago

This is getting too long, I created a wiki

daisycrego commented 3 years ago

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 astartmethod which we pass tothrong, andthrongwill create multiple clusters and callstarton each of them. The number of worker processes (the number of clusters) is going to be eitherprocess.env.WEB_CONCURRENCY, which is set by Heroku based on your dyno, or2if that isn't set. You can play around with the value ofworkers` 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.

daisycrego commented 3 years ago

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.

daisycrego commented 3 years ago

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" };
  });
}
daisycrego commented 3 years ago

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'
    }
daisycrego commented 3 years ago

Progress Update

daisycrego commented 3 years ago

Use an App Password for the SMTP

daisycrego commented 3 years ago

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 Logs can also be used to backtrack.