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 lifecycle of HttpClient and BlockingHttpClient #11319

Merged

Conversation

glorrian
Copy link
Contributor

@glorrian glorrian commented Nov 6, 2024

Fix a bug when a closed client issued an incorrect error as mentioned in #11307

Add special exceptions to simple requests and web sockets
Make tests for it

Add Lifecycle to the BlockingHttpClient interface as well as HttpClient interface

Implement new methods at BlockingHttpClient anonymous class at DefaultHttpClient
Implement new methods at JdkBlockingHttpClient

Fix tests where an undisclosed client was used

JsonStreamSpec: delete "cleanup" with closing clients on each test since the client is shared between all tests and closes automatically at the end(@AutoClosable)
HttpHeadSpec: replace "close" with "refresh" in "cleanup" of one test cause this instance of client is used by other tests
ClientHostNameSpec: replace "close" with "refresh" in "cleanup" of one test cause HttpClient.create() caching clients instances so actually all tests use one instance of client
ByteBufferSpec: make client field @shared cause @Inject fields caching so all test actually use one instance of client

@graemerocher graemerocher requested a review from yawkat November 7, 2024 10:23
@@ -193,6 +193,8 @@ public class ConnectionManager {
this.clientCustomizer = from.clientCustomizer;
this.informationalServiceId = from.informationalServiceId;
this.nettyClientSslBuilder = from.nettyClientSslBuilder;

refresh();
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is necessary

Copy link
Contributor Author

@glorrian glorrian Nov 7, 2024

Choose a reason for hiding this comment

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

This is necessary cause this constructor is used for copying ConnectionManager to new instance so we need to bootstrap new instance to setup states. For example AtomicBoolean running is false by default and without refresh() isRunning() will return false. I add this line cause i had failed tests. Hope you will get me, thanks for your review.

@@ -15,7 +15,7 @@ class ClientHostNameSpec extends Specification {
e.message.contains('Connect Error: foo_bar') || e.message.contains('Connect Error: No such host is known (foo_bar)')

cleanup:
client.close()
client.refresh()
Copy link
Member

Choose a reason for hiding this comment

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

why these changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cause if close this instance other tests will get an already closed client and then throw an exception when trying to use it

Copy link
Member

Choose a reason for hiding this comment

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

the client in this test is not shared

Copy link
Contributor Author

@glorrian glorrian Nov 7, 2024

Choose a reason for hiding this comment

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

Not shared but cached inside factory i guess. When trying to run these tests, I get “closed client” exceptions, when I replace them with refresh, all the tests actually pass. I made quick look up inside the impl of factory client method, and it seems to me that this is caching code, but maybe I'm wrong. I'll check it again and come back with a final answer.

Copy link
Contributor Author

@glorrian glorrian Nov 7, 2024

Choose a reason for hiding this comment

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

You're right! these tests failed because of the vpn on my mac. I removed refresh() in this spec.

@@ -364,7 +364,7 @@ class HttpHeadSpec extends Specification {
body == "success"

cleanup:
client.close()
client.refresh()
Copy link
Member

Choose a reason for hiding this comment

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

this one too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same as previous comment

Copy link
Contributor Author

@glorrian glorrian Nov 7, 2024

Choose a reason for hiding this comment

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

this one actually use one shared instance by hashCode
Screenshot 2024-11-07 at 23 46 33 copy

@yawkat yawkat self-assigned this Nov 8, 2024
@yawkat yawkat changed the base branch from 4.7.x to 4.8.x November 8, 2024 08:40
@yawkat yawkat added this to the 4.8.0 milestone Nov 8, 2024
@glorrian
Copy link
Contributor Author

glorrian commented Nov 9, 2024

@graemerocher @yawkat can you restart build? I think this one failed test is flaky cause it passed on 21 java and on all my local environments

@yawkat yawkat linked an issue Nov 11, 2024 that may be closed by this pull request
@yawkat yawkat merged commit c05249d into micronaut-projects:4.8.x Nov 11, 2024
16 checks passed
@yawkat
Copy link
Member

yawkat commented Nov 11, 2024

Thanks!

@glorrian glorrian deleted the features/closed-http-client-exception branch November 11, 2024 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Closed HTTP client reports incorrect error on request
2 participants