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: support async afterEach hook #1242

Merged
merged 2 commits into from
Oct 8, 2024

Conversation

lhokktyn
Copy link
Contributor

@lhokktyn lhokktyn commented Oct 5, 2024

Currently a asynchronous afterEach hook will execute concurrently with the underlying express request lifecycle.

This fix allows async hooks to complete before allowing the express request to continue through its middleware stack.

Resolves #1241

Currently a asynchronous afterEach hook will execute concurrently
with the underlying express request lifecycle. This fix allows async
hooks to complete before allowing the express request to continue
through its middleware stack.

Fixes pact-foundation#1241
@lhokktyn lhokktyn force-pushed the fix-async-aftereach branch from 891566a to 891e0cb Compare October 5, 2024 09:10
Copy link
Contributor

@TimothyJones TimothyJones left a comment

Choose a reason for hiding this comment

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

Nice! Thanks for this. I'm not a maintainer any more, but it looks right to me.

src/dsl/verifier/proxy/hooks.ts Show resolved Hide resolved
@@ -31,19 +31,17 @@ export const registerAfterHook = (
config: ProxyOptions,
stateSetupPath: string
): void => {
logger.trace("registered 'afterEach' hook");
Copy link
Contributor

Choose a reason for hiding this comment

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

This is now slightly misleading- it always registers the hook, but the hook is only connected to something if config.afterEach is set.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now checks for presence of configured hooks before logging.

I've got another PR being lined up to refactor this bit a little more, but looking like it'll best for a separate discussion 🙂

@lhokktyn lhokktyn force-pushed the fix-async-aftereach branch from 891e0cb to d368c80 Compare October 5, 2024 12:31
@lhokktyn
Copy link
Contributor Author

lhokktyn commented Oct 8, 2024

@mefellows just a heads up that I'm lining up another PR that builds on top of this PR, which contains some further refactoring around the hooks stuff - mainly with the aim of ensuring hooks are only run once during each interaction's setup/teardown phase respectively.

I've got it marked as a breaking change at the moment - hence wanting to raise as a separate PR - but I'm not sure it is actually a break to be honest so a little discussion around that would be great once this PR is merged if you don't mind.

@YOU54F
Copy link
Member

YOU54F commented Oct 8, 2024

@mefellows just a heads up that I'm lining up another PR that builds on top of this PR, which contains some further refactoring around the hooks stuff - mainly with the aim of ensuring hooks are only run once during each interaction's setup/teardown phase respectively.

I've got it marked as a breaking change at the moment - hence wanting to raise as a separate PR - but I'm not sure it is actually a break to be honest so a little discussion around that would be great once this PR is merged if you don't mind.

That makes sense, looking forward to seeing the change.

Thanks for the repro and fix. I'll get this merged and released today

@YOU54F YOU54F merged commit 96c5e54 into pact-foundation:master Oct 8, 2024
25 checks passed
@TimothyJones
Copy link
Contributor

FWIW, I took a look at your branch and it looks more like a bugfix to me.

Current behaviour will run the beforeEach and afterEach hooks
multiple times if there are several provider states defined in
an interaction. This change will ensure each of those hooks is
run only once, regardless of how many provider states are
defined in an interaction.

Yes, technically this is a break (as are most bug fixes, as they change behaviour), but the test I would usually apply is:

  • Would anyone reasonably expect the old behaviour? (I don't think so)
  • Would anyone reasonably rely on the old behaviour? (I don't think so)
  • Was it already documented to work the old way? (no, it was documented to work the fixed way here)

I think it's still a bit surprising that the afterEach runs at the start of the state teardowns rather than after all of them, but it's hard to do that with Pact-JS's proxy.

Really, the afterEach should be first class options run by the pact core, so all languages get them, and the core can reason about the interactions with the teardowns too. This was one of the design philosophies I took when designing ContractCase - which won't work for you here, as it doesn't have afterEach / beforeEach methods at all yet.

@TimothyJones
Copy link
Contributor

I think it's still a bit surprising that the afterEach runs at the start of the state teardowns rather than after all of them, but it's hard to do that with Pact-JS's proxy.

You might be able to count the state setup calls, and rely on the same number of teardowns, maybe.

@lhokktyn
Copy link
Contributor Author

lhokktyn commented Oct 8, 2024

Thanks both. I'll take another look at the fix with those suggestion in mind.

@lhokktyn
Copy link
Contributor Author

lhokktyn commented Oct 8, 2024

Opened #1243 which takes your comments into account.

@mefellows
Copy link
Member

@mefellows just a heads up that I'm lining up another PR that builds on top of this PR, which contains some further refactoring around the hooks stuff - mainly with the aim of ensuring hooks are only run once during each interaction's setup/teardown phase respectively.

I've got it marked as a breaking change at the moment - hence wanting to raise as a separate PR - but I'm not sure it is actually a break to be honest so a little discussion around that would be great once this PR is merged if you don't mind.

Thanks for this, I agree with the comments above - I wouldn't consider this a breaking change. It's incidentally working this way currently, and for most people this is unexpected behaviour.

Thanks for merging Yousaf, I wanted to test myself before merging as middleware can be hard to reason about by just looking at the code and it's not an area that is well covered by tests. I was concerned it

Really, the afterEach should be first class options run by the pact core, so all languages get them, and the core can reason about the interactions with the teardowns too

I agree @TimothyJones and created this issue to track that: pact-foundation/pact-reference#468 (I thought I had previously done this, but it seems like it was a figment of my imagination).

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.

afterEach does not support async operation
4 participants