0

I have a fairly basic (so far) queue set up in my app:

  • Job 1 (backup): back up the SQL table I'm about to replace
  • Job 2 (update): do the actual table drop/update

very simplified code:

from rq import Queue
from rq.decorators import job


@job('backup')
def backup(db, table, conn_str):
    backup_sql = "SELECT * INTO {}.dbo.{}_backup from {}.dbo.{}".format(db, table, db, collection)

@job('update')
def update(db, table, conn_str, keys, data):
    truncate_sql = "TRUNCATE TABLE {}.dbo.{}".format(db, collection)
    sql_cursor.execute(truncate_sql)
            
    for sql_row in data:
        sql = "INSERT INTO {}.dbo.{} ({}) values ({})".format(db, table, ",".join(keys), ",".join(["?"] * len(sql_row)))
        sql_cursor.execute(sql, sql_row)
    sql_cursor.commit()

def update_data():
    ...
    update_queue = Queue('update', connection=redis_conn)

    backup_job = update_queue.enqueue('backup', db, table, conn_str, result_ttl=current_app.config['RESULT_TTL'],)
    update_job = update_queue.enqueue('update', db, table, conn_str, result_ttl=current_app.config['RESULT_TTL'],)


What I'd like to do, is find a way to watch the update. If it fails, I want to run a job to restore the backup created in the backup job. If it's successful, I want to run a different job to simply remove the backup.

What's the right way to go about this? I'm pretty new to rq and am looking around in the docs, but haven't found either a way to poll update for success/failure or an idiomatic way to handle either outcome.

ebbishop
  • 1,833
  • 2
  • 20
  • 45

1 Answers1

0

One option is to create another third job called "checker" for example, which will decide what to do based on the status of "update" job. For that, you have to specify a dependency relationship.

depends_on specifies another job (or job id) that must complete before this job will be queued.

def checker(*args, **kwargs):
    pass

checker_job = update_queue.enqueue('checker', *args, depends_on=update_job.id, result_ttl=current_app.config['RESULT_TTL'])

Then check the status of the dependency inside of "checker" and based on that status load backup or delete it.

def checker(*args, **kwargs):
    job = rq.get_current_job()

    update_job = job.dependency
    
    if update_job.status == 'failed':
        # do the stuff here
    else:  # or elif
        # do the stuff here
Davit Tovmasyan
  • 3,238
  • 2
  • 20
  • 36