Commit Graph

43 Commits

Author SHA1 Message Date
Simon Backx
819d0d884c
Improved email verification required checks (#16060)
fixes https://github.com/TryGhost/Team/issues/2366
refs https://ghost.slack.com/archives/C02G9E68C/p1670232405014209

Probem described in issue.

In the old MEGA flow:
- The `email_verification_required` check is now repeated inside the job

In the new email service flow:
- The `email_verification_required` is now checked (didn't happen
before)
- When generating the email batch recipients, we only include members
that were created before the email was created. That way it is
impossible to avoid limit checks by inserting new members between
creating an email and sending an email.
- We don't need to repeat the check inside the job because of the above
changes

Improved handling of large imports:
- When checking `email_verification_required`, we now also check if the
import threshold is reached (a new method is introduced in
vertificationTrigger specifically for this usage). If it is, we start
the verification progress. This is required for long running imports
that only check the verification threshold at the very end.
- This change increases the concurrency of fastq to 3 (refs
https://ghost.slack.com/archives/C02G9E68C/p1670232405014209). So when
running a long import, it is now possible to send emails without having
to wait for the import. Above change makes sure it is not possible to
get around the verification limits.

Refactoring:
- Removed the need to use `updateVerificationTrigger` by making
thresholds getters instead of fixed variables.
- Improved awaiting of members import job in regression test
2023-01-04 11:22:12 +01:00
Simon Backx
4c166e11df
Added E2E tests for batch sending (#15910)
refs https://github.com/TryGhost/Team/issues/2339

- Includes a new pattern in the job manager that allows us to properly
await jobs.
- Added new convenience mocking methods to stub settings
- Tests the main flows for bulk sending:
    - Sending in multiple batches
    - Sending to multiple segments
    - Handling a failed batch and retrying that batch
- Fixes bug in batch generation (ordering not working)

In a different PR I'll add more detailed tests.
2022-12-01 13:43:49 +01:00
Simon Backx
f4fdb4fa6c
Added new email event processor (#15879)
fixes https://github.com/TryGhost/Team/issues/2310

This moves the processing of the events from the event-processor to a
new email-event-processor in the email-service package.

- The `EmailEventProcessor` only translates events from
providerId/emailId to their known emailId, memberId and recipientId, and
dispatches the corresponding events.
- Since `EmailEventProcessor` runs in a separate worker thread, we can't
listen for the dispatched events on the main thread. To accomplish this
communication, the events dispatched from the `EmailEventProcessor`
class are 'posted' via the postMessage method and redispatched on the
main thread.
- A new `EmailEventStorage` class reacts to the email events and stores
it in the database. This code mostly corresponds to the (now deleted)
subclass of the old `EmailEventProcessor`
- Updating a members last_seen_at timestamp has moved to the
lastSeenAtUpdater.
- Email events no longer store `ObjectID` because these are not
encodable across threads via postMessage
- Includes new E2E tests that test the storage of all supported Mailgun
events. Note that in these tests we run the processing on the main
thread instead of on a separate thread (couldn't do this because
stubbing is not possible across threads)

There are some missing pieces that will get added in later PRs (this PR
focuses on porting the existing functionality):
- Handling temporary failures/bounces
- Capturing the error messages of bounce events
2022-11-29 11:15:19 +01:00
Naz
f8b51822af
Fixed typos 2022-10-07 18:41:21 +08:00
Naz
54c19226bf
Fixed an unhandled exception in job manager
closes https://github.com/TryGhost/Toolbox/issues/402

- The SQL error was thrown whenever a job error was happening and was trying to persist an error. Persisting an error should only happen for "named" one-off jobs, instead of just one-off jobs.
2022-10-07 18:41:11 +08:00
Naz
5adcee1528 Added ability to readd failed one-off job
refs https://github.com/TryGhost/Toolbox/issues/358

- When a one-off job fails it could be restarted during the next call, given it has been cleared from the job queue.
- This readding WILL NOT work for jobs that are restarted within same process (while being kept in the bree's queue). It's specifically targetting one-off jobs like migrations that **might** fail and are only added once per process lifetime.
2022-07-28 19:07:49 +01:00
Naz
195973eae1 Added successful job run check
refs https://github.com/TryGhost/Toolbox/issues/358

- Allows to check for a **successfull** job run and restart/re-add the job in case it was a failed one off job
2022-07-28 19:07:49 +01:00
Naz
ee243f9ea3 Refactored job statuses
refs https://github.com/TryGhost/Toolbox/issues/358

- Without going into the model layer (schema) for a job it's hard to figure out which job statuses are available. Using an object with hard typed properties makes the code less prone to typos.
2022-07-28 19:07:49 +01:00
Naz
c88dcf749b Improved awaitCompletion interface
refs https://github.com/TryGhost/Toolbox/issues/358

- The method is a bit of a dangerous to use in cases when the job takes a long time to execute.
- Returning a boolean value did not make sense and provided no helpful information. Having a job model (or not having one) gives the context in which the "completion" happened.
2022-07-28 19:07:49 +01:00
Naz
6d5a5e90b1 Added job status checks to job manager
refs ttps://github.com/TryGhost/Toolbox/issues/358

- One off jobs need a way to check for prior execution and await for their completion (in cases when it is reasonably short).
- Added `hasExecuted` and `awaitCompletion` methods to the job manager allowing to monitor one off job state
2022-07-27 18:04:19 +01:00
Naz
b7853323ae 🐛 Fixed email sending job execution
refs https://github.com/TryGhost/Toolbox/issues/359

- Sending newsletters got broken because underlying "inline job" execution had a bug.
- The real problem was in the job manager trying to verify inline unnamed job status in the database without having a name.
2022-07-27 15:12:56 +01:00
Naz
7adf3a5410 Added support for one off inline jobs
refs https://github.com/TryGhost/Toolbox/issues/359

- Inline one off jobs are needed in situations when we want to run a certain operation only once in the lifecycle of the Ghost instance. These operations should not be extremely long to execute though (not suited for backups or import types of tasks)
2022-07-26 18:14:25 +01:00
Naz
822549c9ef Added defensive code for non-persistent job manager
refs https://github.com/TryGhost/Toolbox/issues/359

- It's up to a user to decide initializing the job manager without a "jobModel". In these cases the regular recurring job scheduling should work as it did before
2022-07-26 18:14:25 +01:00
Naz
013051a6c9 Made name parameter required for one off jobs
refs https://github.com/TryGhost/Toolbox/issues/359

- Without a "name" parameter it's impossible to identify a job in the storage. It was missed during the PoC inmplementation
2022-07-26 15:13:12 +01:00
Naz
df8a7f9b6b Fixed formatting 2022-07-22 16:44:28 +01:00
Naz
b0581c778e Added execution progress updates for one off jobs
refs https://github.com/TryGhost/Toolbox/issues/357

- Job persisted in the database need to track job's execution status such as completion, failure, execution start and end times. This changeset allows to hook into job/bree lifecycle to track job's progress.
- NOTE: only supports "offloaded" jobs at the moment. Support for "inline" jobs will be added once there's a clear usecase for it.
- The "started" status and "started_at" timestamp are assigned to a job at the moment when the worker thread is created inside of bree
- The "finished" status and "finished_at" timestamp are assigned to a job when a "done" event is passed from the job script (NOTE: using process.exit(0) will not trigger the "finished" state")
- The "failed" status is assigned when the job execution is interrupted with an error
2022-07-22 16:43:15 +01:00
Naz
5dae6d6acf Added support for one off jobs
refs https://github.com/TryGhost/Toolbox/issues/357

- This is a scaffolding for what will become a one off job scheduling mechanism. The aim is allowing to run jobs which can be only ever be run once in the lifetime of the instance - persisting through restarts.
2022-07-21 19:39:54 +01:00
Naz
13bfc0746b Revert "Transformed addJob to be an async method"
This reverts commit f8b1877253.
2022-07-21 18:56:35 +01:00
Naz
f8b1877253 Transformed addJob to be an async method
https://github.com/TryGhost/Toolbox/issues/357

- This is a groundwork before adding one-off (solo) jobs with persistance to the job manager
- Making the addJob method async also makes the whole interface consistent - removeJob and shutdown are also async
2022-07-20 20:41:02 +01:00
Sam Lord
a98ae3734f @tryghost/job-manager: Switch to @tryghost/logging from injected argument
refs: https://github.com/TryGhost/Toolbox/issues/146
2021-12-02 13:40:02 +00:00
Sam Lord
ee7b1e4dc6 Combine @tryghost/ignition-errors with @tryghost/errors
refs: https://github.com/TryGhost/Toolbox/issues/147
2021-11-30 11:31:10 +00:00
Naz
4b70c7e0c0 Removed use of native JS Error objects
closes https://linear.app/tryghost/issue/CORE-55/fix-errors-in-utils-repo-job-manager

- The latest ESLint rules forbid use of native JS errors, updated the codebase before bumping the ESLint version
2021-09-22 11:50:21 +02:00
Naz
55060e323c Added workerMessageHandler option to ctr options
refs https://github.com/TryGhost/Ghost/issues/12496

- `workerMessageHandler` option allows for custom worker message handling and allows to eliminate a need for loggers of any type inside of jobs.
- removing loggers from jobs solves file hanle leak which used to cause Ghost process to crash (see referenced issue)
2021-02-22 19:10:47 +13:00
Naz
57c3b4428d Fixed spelling mistakes 2021-02-22 13:11:19 +13:00
Naz
3bca4f63b8 Refactored job manager interface to consist of single addJob method
refs #122

- In future changes there's a plan to add "inline" scheduled jobs, which would conflict current method naming.
- The amount of parameters in the methods was more than 3, so it made sense to transform them into an options object
- Scheduling still doesn't work for "inline" jobs. This should be solved as a part of upstream library (https://github.com/breejs/bree/issues/68)
2021-01-06 13:45:23 +13:00
Naz
c13d8a2fa6 Added errorHandler option to customize job error logic
closes https://github.com/TryGhost/Ghost-Utils/issues/118

- Custom error handling is needed to be able to override default bree
error handling logic.
- bree bump to 4.1.0 also fixed logging errors (object Object fix in
tests)
- The handler function receives two parameters. First contains an error
that has been thrown by the job. Second, job and worker metadata
2020-12-14 16:09:36 +13:00
Naz
7ece94f411 Added support for immediate offloaded jobs
closes #117

- Having immediately executable offloaded jobs is necessary to be able to run usecases like: send batched emails now, or any other job that does not need to be scheduled
- Changed "simple" job timeout to make tests run faster
2020-12-09 19:11:17 +13:00
Naz
320e7feb0e Added ability to remove scheduled jobs
closes #119

- A future use-case which this feature caters for is allowing to migrate "post scheduler" to use job manager instead of managing scheduling itself
- removeJob method will be needed to allow "rescheduling" of the post
2020-12-08 16:43:18 +13:00
Naz
86b9f0d2ce Renamed when parameter
no issue

- Semantically "at" fits better as it matches the name of similarly purposed UNIX utility
2020-12-03 16:22:56 +13:00
Naz
eb0eb2d744 Added support for one off scheduled jobs
closes #115

- When scheduling one off job for future execution you can now pass in Date as a first parameter to `scheduleJob` method
2020-12-02 21:26:15 +13:00
Naz
35f8933070 Fixed cron definition not accepting seconds parameter 2020-12-02 00:19:01 +13:00
Naz
715789406d Improved job registration logging 2020-11-30 15:35:57 +13:00
Naz
3892e57194 Added docs on how each method executes the job 2020-11-30 15:30:45 +13:00
Naz
986a59abda Moved job metadata attribute to global bree config
no issue

- Because every job is getting this attribute anyways there's no need to keep it nested on per-job bases
2020-11-19 18:15:52 +13:00
Naz
4b18cbcbdb Added support for worker threads in scheduled jobs
no issue

- When jobs are performing CPU intensive tasks they block main process'
event loop. They also can cause memory leaks or unexpected crashes
effectively crashing the parent proccess. To address these issues jobs need to be performed off of main
process. Worker Threads (https://nodejs.org/dist/latest-v12.x/docs/api/worker_threads.html)
are the best candidate for such work.
- These changes introduce an integration on top of bree
(https://github.com/breejs/bree/) which allows to run recurring
jobs in worker thereads. It falls back to child process execution for
Node v10 running without `--experimental-worker` flag.
- bree was chosen not only because it gives a polyfill for older Node
versions. It has support for some of the future use-cases Ghost is looking to
implement, like scheduled jobs.
- This changeset also includes a complete example of job running on an
interval with a possibility for graceful shutdown
2020-11-19 17:59:36 +13:00
Naz
85b51524c9 Added loggign and more graceful error handling
no issue

- This is a quick implementation change to prevent from queue stalling and never becoming idle in case there's an error thrown from within the job function/module
- More robust error handling should be designed soon!
2020-11-10 17:11:24 +13:00
Naz
c85ec6aaa5 Added support for job execution from module path
no issue

- Jobs should not always be functions, one of the standard practices is having a job defined in a module as a self contained executable function
- First parameter of `addJob` function now also handles path to modules which it imports and executes
2020-11-10 16:32:47 +13:00
Naz
ae4f35ddd8 Changed scheduleJob method signature to take when parameter first
no issue

- Accepting the schedule or a data when scheduled job should be run would follow a signature used in other established frameworks: (1) https://github.com/mperham/sidekiq/wiki/Ent-Periodic-Jobs#definition
- Another reason to put scheduling parameter first is this would allow leaving an optional "data" parameter as last
2020-11-10 13:15:10 +13:00
Naz
d1bbd79ece Updated JSDoc 2020-11-05 17:36:51 +13:00
Naz
1b1794063f Added experimental job scheduling feature
no issue

- This method should be used with caution and should serve as a playground for upcoming new feature of scheduled jobs support
2020-11-05 17:36:29 +13:00
Naz
5506c64ae4 Added logging 2020-11-05 16:42:23 +13:00
Naz
48597b0056 Added JSDoc description 2020-11-05 16:41:16 +13:00
Hannah Wolfe
2c1417da88 Added new job manager package
- Minimal working version of a job manager
- Uses fastq for handling the queue
- Exposes 2 methods: addJob and shutdown
2020-08-11 21:17:52 +01:00