Skip to content
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

Fix transaction issues #36

Merged
merged 7 commits into from
Feb 12, 2024
Merged

Fix transaction issues #36

merged 7 commits into from
Feb 12, 2024

Conversation

hugorodgerbrown
Copy link
Collaborator

This is a refactoring of the internals so that when using the disable_side_effects context manager or decorator the run_side_effects method call is completely bypassed, and the suppressed_side_effect signal is immediately fired, rather than deferred till transaction.on_commit.

This should fix a bug whereby side-effects were deferred using transaction.on_commit, which meant that when they were called the registry was outside of the context manager and the is_suppressed attr was no longer true. i.e. side-effects were fired even when using disable_side_effects correctly.

When running inside an existing transaction the disable_side_effects
decorator has a bug. It disables and then enables the registry so
that side-effects don't run, but if the call to `run_side_effects`
is deferred using `transaction.on_commit` it may be called after
the context manager has exited, in which case the registry will
have been re-enabled. In this case the side-effects will run.

The fix is to pull some of the logic around suppression out so that
it runs immediately on calling `run_side_effects` - if the registry
is disabled at that point it will fire the signal and return
immediately.
@hugorodgerbrown hugorodgerbrown self-assigned this Jan 16, 2024
Comment on lines -66 to +65
# when in TEST_MODE do not defer the side-effects, as they
# are never fired anyway.
registry_func = (
registry.run_side_effects
if TEST_MODE
else registry.run_side_effects_on_commit
)
registry_func(label, *args, return_value=return_value, **kwargs)
registry.run_side_effects(label, *args, return_value=return_value, **kwargs)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Part one of the change is to always call run_side_effects rather than adding in fancy logic to the decorator. Simpler.

Comment on lines 162 to 180
# if the registry is suppressed we are inside disable_side_effects,
# so we send the signal and return early.
if _registry.is_suppressed:
suppressed_side_effect.send(Registry, label=label)
else:
transaction.on_commit(
partial(
_registry.run_side_effects,
label,
*args,
return_value=return_value,
**kwargs,
)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the meat of the change. Instead of having two separate methods we now always run the method on_commit, but we abort early if _registry.is_suppressed - which is True inside the disable_side_effects context. This means that we immediately return regardless of the transaction. The transaction is only relevant when actually running the side-effects for real, which is the desired behaviour.

Comment on lines -143 to -148
# TODO: this is all becoming over-complex - need to simplify this
self.try_bind_all(label, *args, return_value=return_value, **kwargs)
if self.is_suppressed:
self.suppressed_side_effect.send(Registry, label=label)
else:
self._run_side_effects(label, *args, return_value=return_value, **kwargs)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

TODONE - it was too complex so I have removed it.

@hugorodgerbrown hugorodgerbrown merged commit 8470bc3 into master Feb 12, 2024
15 checks passed
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.

1 participant