-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle SystemExit gracefully in two phase commit mode #21
base: master
Are you sure you want to change the base?
Conversation
self._tpc_activated = True | ||
finally: | ||
if self._conn.status == psycopg2.extensions.STATUS_BEGIN: | ||
self._tpc_activated = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what this have to do with SystemExit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If SystemExit is raised in just the right time, _tpc_activated
flag was not being set (because of exception) even though tpc_begin
had just completed. So when PJDataManager tried to clean up, it called _conn.rollback()
- this is invalid call for a connection in status STATUS_BEGIN
. And so it failed with ProgrammingError
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SystemExit is just an exception we encountered in production, when a celery worker is being shut down while still trying to process some database task.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean you think this happens when SystemExit
is raised right between tpc_begin()
and _tpc_activated = True
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, this makes sense. but the code needs in addition:
- Comment, explaining why this code is there
- Logging message on warning level when we don't set _tpc_activated to True.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kedder re-arranged the code a bit and added logging. Hope it reads better now.
self._tpc_activated = True | ||
finally: | ||
if self._conn.status == psycopg2.extensions.STATUS_BEGIN: | ||
self._tpc_activated = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, this makes sense. but the code needs in addition:
- Comment, explaining why this code is there
- Logging message on warning level when we don't set _tpc_activated to True.
80efc38
to
05317e0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good
src/pjpersist/datamanager.py
Outdated
"PJDataManager._begin: tried to call connection.tpc_begin," | ||
" but it did not change connection status to STATUS_BEGIN," | ||
" failing with a generic exception %s." | ||
" Not setting TPC mode on PJDataManager." % exc) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpicking: , exc please instead of %
…ining a transaction in two-phase-commit mode.
05317e0
to
4e6b59d
Compare
If SystemExit was raised while PJDataManager was joining a transaction in two-phase-commit mode, PJDataManager failed to clean up after itself.