-
-
Notifications
You must be signed in to change notification settings - Fork 16
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
HTTPClient cannot perform multiple requests #9
Comments
You correctly understand what it is doing. However, it behaves that way on purpose. The Handler is related to the connection, not to the request. A connection can deal with multiple requests as this saves the time of tearing down and re-establishing the TCPConnection each time. In certain cases it is even possible to pipeline requests, with some restrictions, and if the particular server chooses to support that. So there is a certain amount of context associated with the connection (like if the server end closes it, backpressure, and so on) and a certain amount of context associated with each individual request. Your HandlerMaker is called only when a new connection is created. On the second request the apply method of the first Handler should be called, since it is using the same connection. |
From a usability perspective, the signature: HTTPClient.apply(request: Payload trn, handlermaker: HandlerFactory val): Payload val ? implies that the handler is associated with the payload, this is misleading because the handler factory is completely ignored for subsequent requests. In the API abstraction layer, you would need to maintain a collection of sent payloads, and have the handler call a behaviour of the abstraction layer, where you would need to match the response with the sent request. Given the signature of I entirely support TCPConnection reuse but it looks like the concepts of connection pooling and response handling have been merged, leading to the difficulty in using the Are you able to provide a simple example where the same client is used to perform multiple different requests to the same host, with each doing something different on receiving the response? |
In addition to just looking at the signature of the apply method, you need to read the extensive documentation in file Yes, if you need to distinguish between responses, you would need a Map of pending sent Requests. But some of the things coming back to the Handler have to do with the underlying TCPConnection, not individual Requests. I did not want to muddy things further by having two handlers. The Handler deals with the Session and the HTTP protocol - that is why the interface name is This is not a bug exactly, but a philosophical issue about what the API should look like. It does not have to be the way it is. I would like to hear more discussion on this. |
I would like to add to the discussion and propose a change that I implemented. I made the handler factory part of the identification of the _HostService, so now a new _ClientConnection is created when the HandlerFactory is different for the same scheme, host and port. This at least gives a better relationship between the apply accepting the handler factory as a parameter and the handler factory being used. Another change I want to propose concerns a bug in the code handling the payloads. This is the code in the _ClientConnection. In the current implementation sending two requests to the same _ConnectionHandler fails with the two payloads not being handled at all. After some searching I found the error in the code that determines whether or not the var _conn: (TCPConnection | None) is a valid, opened connection. The following scenario plays whent the HTTPClient apply is called with two payloads for the same _ClientConnection. This results in two apply behaviours being called which are then processed by the _ClientConnection asynchronously. This is the scenario:
It works when you only send one payload, because _send_pending is called again after be _connected is called and _conn is a connected TCPConnection. This is the scenario:
The fix was easy: I changed the type of _conn and gave it an extra type _ConnConnecting
The changed _new_conn() tests if it is connecting and returns if it is.
The behaviour _connected sets _conn to the received TCPConnection
|
I can send in the fix but could some help in preparing a pull request. |
The handler factory was supplied in the apply method of a client together with the Payload for the request. If the client already had a session for the new host, port and scheme, no new session was created and the supplied handler factory wasn't used. The new design makes it clear, that one client uses the same handler factory for all requests it makes. If different handler factories are needed, different clients need to be created. Closes ponylang#102 Closes ponylang#9
There appears no way to re-use a HTTPClient despite the documentation suggesting that one should create one HTTPClient and then re-using it.
The HandlerMaker's apply method is only called once when the HttpSession is created and then stored against the (scheme, host, port) tuple, thus when the second request is made, it uses the Handler from the first request.
Code that reproduces the issue & a more in-depth discussion of the problem:
https://gist.github.com/CandleCandle/260a284ece6d2e99520cfbd99798e739
The text was updated successfully, but these errors were encountered: