bcgov / entity

ServiceBC Registry Team working on Legal Entities
Apache License 2.0
23 stars 58 forks source link

Known work around Bug: Email delay-previously emails generated by examining a name had a 5-minute delay. #21835

Open ozamani9gh opened 2 months ago

ozamani9gh commented 2 months ago

Priority 3: Email delay-previously emails generated by examining a name had a 5-minute delay. This was helpful when examining as any mistakes (forgot to put condition on, made error in examining, etc.) wouldn’t result in multiple outputs that are confusing for the client. Preference for a short delay that only generates the last email. (Frequency 100%) Time cost: approx. 20-30min/week

ozamani9gh commented 2 months ago

Update from Joshua: • The removal of the output delay creates confusion for clients if an examiner were to catch a mistake and go back to fix it (generates multiple different results emails to clients, who then call or email in confusion which creates a cascade effect). Even a few minutes delay for output generation would help reduce this.

ozamani9gh commented 2 months ago

@Mihai-QuickSilverDev reach out to Joshua and get the exact delay he wants, we suggest 10 or 15 minutes.

Mihai-QuickSilverDev commented 2 months ago

Message sent to Joshua on June 28, 2024, 9 AM:

Hi Joshua,

Regarding this topic below, could you please let us know what would be a desirable duration for this delay? We could do 5, 10, 15 minutes, whatever would best fit the Name Examiners needs.

Update from Joshua: • The removal of the output delay creates confusion for clients if an examiner were to catch a mistake and go back to fix it (generates multiple different results emails to clients, who then call or email in confusion which creates a cascade effect). Even a few minutes delay for output generation would help reduce this.

Thank you,

ozamani9gh commented 2 months ago

Joshua stated 5 minutes is sufficient

EPortman commented 2 months ago

Clients are emailed about their NRs in the following scenarios:

  1. When NR goes to APPROVE, CONDITIONAL or REJECTED
  2. When a payment update is made to REAPPLY or UPGRADE
  3. When a NR is refunded
  4. When a NR updates to CONSENT_RECEIVED
EPortman commented 1 month ago

Async Operations with Flask Framework: https://flask.palletsprojects.com/en/3.0.x/async-await/# Async Operations with Gunicorn Server: https://docs.gunicorn.org/en/latest/design.html

NameX API uses the Flask Framework running on a Gunicorn WSGI Server

Why its not possible to us async/await on each email for 5 minutes Flask on its own is single-threaded (blocking) and does not natively support asynchronous operations across requests - only within them (can await a database operation, but cant schedule it - it will be cancelled once the request ends since flask handles 1 request at a time).

To get the desired behavior (non-blocking waiting for 5 minutes for each email)

  1. Change the Gunicorn worker to be of type gevent to allow for async operations

    • This would change the way the Server works - it would support asynchronous operations (have an event loop, gEVENT)
    • The section When to use Quart instead in the Flask docs seem to imply this is more of a work-around.
  2. Spawn a separate thread for async operations

    • Spawn a separate thread with an event loop to handle all asynchronous tasks.
      • This approach adds a layer of complexity - API would become multithreaded with a main sync thread and another async thread where emails tasks are scheduled.
  3. Use Celery to get the async effect

    • Celery is a separate process that acts as a task queue.
    • API would send asynchronous tasks to this separate process.
    • The recommended way, involves adding another dependency and separate running process to the api .
  4. Use a Cron Job to get the async effect

    • Any time an email needs to be sent, it is written to disk in the database.
    • A cron job then reads from this database every 5 minutes (or even at the end of every day) and determines what emails need to be sent.
EPortman commented 1 month ago

A good resource for this topic: https://testdriven.io/blog/flask-async/

image.png
EPortman commented 1 month ago

It is not really an option to change the functionality of the queue. The queue module is located here: https://github.com/bcgov/namex/blob/main/services/pubsub/gcp_queue/pubsub.py

Reasons why changing this queue is not an option