Allow thrimshim to safely cancel a job while it is cutting

This differs from the existing reset row by only suceeding if the upload is not
in finalizing.

We also make some changes to cutter to handle this situation gracefully.
pull/138/head
Mike Lang 5 years ago
parent b27e06d068
commit 3dfe0e8722

@ -86,6 +86,10 @@ class CandidateGone(Exception):
"""Exception indicating a job candidate is no longer available"""
class JobCancelled(Exception):
"""Exception indicating a job was cancelled by an operator after we had claimed it."""
class Cutter(object):
NO_CANDIDATES_RETRY_INTERVAL = 1
ERROR_RETRY_INTERVAL = 5
@ -125,7 +129,10 @@ class Cutter(object):
self.claim_job(job)
except CandidateGone:
continue
self.cut_job(job)
try:
self.cut_job(job)
except JobCancelled:
self.logger.info("Job was cancelled while we were cutting it: {}".format(format_job(job)))
def refresh_conn(self):
"""After errors, we reconnect in case the error was connection-related."""
@ -332,6 +339,10 @@ class Cutter(object):
))
result = query(self.conn, built_query, id=job.id, name=self.name, **kwargs)
if result.rowcount != 1:
# If we hadn't yet set finalizing, then this means an operator cancelled the job
# while we were cutting it. This isn't a problem.
if not finalize_begun:
raise JobCancelled()
raise JobConsistencyError("No job with id {} and uploader {} when setting: {}".format(
job.id, self.name, ", ".join("{} = {!r}".format(k, v) for k, v in kwargs.items())
))
@ -372,7 +383,7 @@ class Cutter(object):
tags=self.tags + [job.category, job.sheet_name],
data=upload_wrapper(),
)
except (JobConsistencyError, UploadError):
except (JobConsistencyError, JobCancelled, UploadError):
raise # this ensures these aren't not caught in the except Exception block
except Exception as ex:
self.refresh_conn()

@ -300,15 +300,24 @@ def manual_link(ident, editor=None):
@request_stats
@authenticate
def reset_row(ident, editor=None):
"""Clear state and video_link columns and reset state to 'UNEDITED'."""
"""Clear state and video_link columns and reset state to 'UNEDITED'.
If force is 'true', it will do so regardless of current state.
Otherwise, it will only do so if we know no video has been uploaded
(state is UNEDITED, EDITED or CLAIMED)
"""
force = (flask.request.args.get('force', '').lower() == "true")
conn = app.db_manager.get_conn()
results = database.query(conn, """
query = """
UPDATE events
SET state='UNEDITED', error = NULL, video_id = NULL, video_link = NULL,
uploader = NULL, editor = NULL, edit_time = NULL, upload_time = NULL
WHERE id = %s""", ident)
WHERE id = %s{}
""".format(
"" if force else " AND state IN ('UNEDITED', 'EDITED', 'CLAIMED')",
)
results = database.query(conn, query, ident)
if results.rowcount != 1:
return 'Row id = {} not found'.format(ident), 404
return 'Row id = {} not found or not in cancellable state'.format(ident), 404
logging.info("Row {} reset to 'UNEDITED'".format(ident))
return ''

Loading…
Cancel
Save