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

Re-fix #395 by adjusting the processBeforeResponse option #459

Closed
wants to merge 2 commits into from

Conversation

seratch
Copy link
Member

@seratch seratch commented Apr 1, 2020

Summary

This pull request fixes #462 by correcting the #444 implementation to work at any case.

Requirements (place an x in each [ ])

@seratch seratch added the bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented label Apr 1, 2020
@seratch seratch added this to the v2.0 milestone Apr 1, 2020
@seratch seratch self-assigned this Apr 1, 2020
@codecov
Copy link

codecov bot commented Apr 1, 2020

Codecov Report

Merging #459 into master will decrease coverage by 1.06%.
The diff coverage is 33.33%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #459      +/-   ##
==========================================
- Coverage   84.72%   83.65%   -1.07%     
==========================================
  Files           7        7              
  Lines         550      563      +13     
  Branches      163      167       +4     
==========================================
+ Hits          466      471       +5     
- Misses         57       65       +8     
  Partials       27       27              
Impacted Files Coverage Δ
src/ExpressReceiver.ts 62.39% <0.00%> (-4.58%) ⬇️
src/App.ts 89.49% <100.00%> (+0.24%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d4a3f2a...c2bb022. Read the comment docs.

if (this.processBeforeResponse) {
let spentMillis = 0;
const millisForTimeout = 10;
// Wait here until the isAcknowledged is marked as true or 3 seconds have passed
Copy link
Member Author

Choose a reason for hiding this comment

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

I know this is not ideal but I haven't figured out any other solutions yet.

Copy link
Member

Choose a reason for hiding this comment

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

I'm a little confused by this. Can you explain the error use case you are fixing here?

Copy link
Member Author

@seratch seratch Apr 1, 2020

Choose a reason for hiding this comment

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

@stevengill
I didn't mention clearly in the description (sorry!) but I have to say that processBeforeResponse just doesn't work for most cases (I haven't verified if it actually works in the code review, so that was not able to detect it 🙇 ). There are two issues with the current implementation as below:

  • processBeforeResponse doesn't respond to non-event requests such as commands (listeners are executed but no HTTP response is submitted - resulting in timeouts)
  • For Events API, processBeforeResponse doesn't wait for the completion of listeners and responds to incoming requests immediately (= it's not working as the solution for FaaS compatibility)

The change here is addressing the latter one both.

This fix surely holds off responding until verifying the acknowledgment on the App's processEvent method side. It works. However, I'm a bit hesitant to go with this "sleep" approach in Node.js. The most mysterious behavior I haven't fully understood yet is that await this.bolt?.processEvent(event); doesn't wait for the completion of listeners. The line returns before the completion of const settledListenerResults = await allSettled(listenerResults) in the method. That's why I had to implement this part in the Receiver side. I'm still trying to get rid of this part. It'd be greatly appreciated if you could dive deep into the issue.

Copy link
Member Author

@seratch seratch Apr 1, 2020

Choose a reason for hiding this comment

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

One additional note: I've added a unit test verifying App's behavior with processBeforeResponse. But I haven't added any tests for ExpressReceiver. So, even if all the unit tests have passed, it doesn't mean the behavior is valid. It's necessary to make sure if it works in real apps. I was going to add tests to the ExpressReceiver side as well but if we could get rid of this "sleep" part, probably it is no longer needed.

Copy link
Member

@stevengill stevengill left a comment

Choose a reason for hiding this comment

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

Thanks for sending this! And thanks for adding tests!

// Events API requests are acknowledged right away, since there's no data expected
await ack();
// If processBeforeResponse is true, ack() call should be after the listener completion
if (!this.processBeforeResponse) {
Copy link
Member

Choose a reason for hiding this comment

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

Nice Fix!

if (this.processBeforeResponse) {
let spentMillis = 0;
const millisForTimeout = 10;
// Wait here until the isAcknowledged is marked as true or 3 seconds have passed
Copy link
Member

Choose a reason for hiding this comment

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

I'm a little confused by this. Can you explain the error use case you are fixing here?

@aoberoi
Copy link
Contributor

aoberoi commented Apr 3, 2020

update: i'm still looking into a fix for the underlying issue here.

we've narrowed that down to the processMiddleware() function not behaving as we expect. as far as we can tell the Promise it returns will resolve before all the entire set of middleware is processed.

i'm starting by producing a test case for ExpressReceiver so we can isolate the issue.

@aoberoi aoberoi removed the bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented label Apr 4, 2020
@aoberoi aoberoi removed this from the v2.0 milestone Apr 4, 2020
@seratch
Copy link
Member Author

seratch commented Apr 10, 2020

It seems @aoberoi figured out the root cause at #462 . We can stop considering this not-ideal solution now.

@seratch seratch closed this Apr 10, 2020
@seratch seratch deleted the processBeforeResponse branch June 20, 2020 00:09
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.

processBeforeRepsonse: true doesn't work when a Bolt listener function has WebClient calls inside
3 participants