Skip to content

Conversation

adamchainz
Copy link
Member

@jheld
Copy link
Contributor

jheld commented May 23, 2020

I don't have the savepoint/rollback code up right now, but I'm curious, does this flow honor if exception handling or custom savepoint/rollback logic is used, the way django (hopefully) does?

So, if an on_commit is added during part of a transaction (nested or otherwise), and if the developer either catches an exception in part of the flow, or rollsback to a previous savepoint, will this behave the same way as the connection's on_commit logic does?

At this point I'm assuming that django handles it correctly/as expected (e.g. removes the on_commits which are effectively rolled back, but keeps the ones which are still applicable/in-play).

@adamchainz
Copy link
Member Author

The answers to your questions are all in the documentation: https://docs.djangoproject.com/en/3.0/topics/db/transactions/#performing-actions-after-commit

@jheld
Copy link
Contributor

jheld commented May 23, 2020

My question is more related to your implementation. Since you are wrapping on_commit with your inner function, in it you copy the callable and add it to your self.callbacks but that makes me think that should django clean up part of the callbacks (the reasons I've written previously), this implementation will still hold a copy of all of the callbacks it has encountered, rather than the true list that django itself is managing. This is pure conjecture -- I haven't tried it out to see if my concern is valid. If I'm right, it is a bug -- although I'm not sure how many people would run into this issue, but it seems like it could be problematic. Should their test assertions be written tightly, their test should fail, which lowers the severity of this bug.

@adamchainz
Copy link
Member Author

Oh right, sorry I misunderstood your question. You're right - this currently captures every callback, even in the case of code that rolls back transactions and therefore throws away their commit hooks.

I think it can be improved to make the returned value a proxy to virtually construct the captured commit hooks - looking into it.

@adamchainz
Copy link
Member Author

I've made changes here and in django-capture-on-commit-callbacks to solve that, by populating the list only as the context manager exits.

@tolomea
Copy link
Contributor

tolomea commented Jun 25, 2020

I've looked over the pull and it makes sense and I can't see anything wrong. We've installed the associated package and are using it happily in tests.

@adamchainz adamchainz force-pushed the ticket_30457 branch 2 times, most recently from 368a619 to 0fe515b Compare July 11, 2020 12:32
adamchainz added a commit to adamchainz/django-capture-on-commit-callbacks that referenced this pull request Jul 11, 2020
adamchainz added a commit to adamchainz/django-capture-on-commit-callbacks that referenced this pull request Jul 11, 2020
Copy link
Member

@felixxm felixxm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adamchainz Thanks for updates 👍

I added docstring to TestCase.captureOnCommitCallbacks(), added test_different_using() and test_pre_callback() tests, and small edits to docs.

@felixxm
Copy link
Member

felixxm commented Jul 13, 2020

@adamchainz Do you want to take a look at my edits?

Copy link
Member Author

@adamchainz adamchainz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your edits LGTM

One minor thought - I think we should push this up into SimpleTestCase. Whilst rare, it's possible to use the DB from within SimpleTestCase subclasses by using databases = {...} so it would be useful to have this helper available there too. What do you think?

@felixxm
Copy link
Member

felixxm commented Jul 13, 2020

I would leave it in TestCase. SimpleTestCase doesn't wrap test cases into transactions, so the main reason why we accepted ticket-30457 is not valid there.

@adamchainz
Copy link
Member Author

Yes that's fair, one could always test the side effects, or copy it into the specific testcase class.

@felixxm felixxm merged commit e906ff6 into django:master Jul 13, 2020
@adamchainz adamchainz deleted the ticket_30457 branch July 15, 2020 08:46
wedamija added a commit to getsentry/sentry that referenced this pull request Jul 27, 2020
This backports `capture_on_commit_callbacks` from django/django#12944. We
need this when using `transaction.on_commit` in tests, since the callbacks will never fire due to
Django always rolling back the transaction.

Specifically backported for use in https://github.com/getsentry/sentry/pull/19974/files.
wedamija added a commit to getsentry/sentry that referenced this pull request Jul 28, 2020
…20056)

This backports `capture_on_commit_callbacks` from django/django#12944. We
need this when using `transaction.on_commit` in tests, since the callbacks will never fire due to
Django always rolling back the transaction.

Specifically backported for use in https://github.com/getsentry/sentry/pull/19974/files.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants