-
Notifications
You must be signed in to change notification settings - Fork 70
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
Allow shared reqwest client configuration #357
base: main
Are you sure you want to change the base?
Conversation
5a3104c
to
734d79b
Compare
Merge conflict needs to be resolved |
It's unclear to me if this will result in cookies and headers being shared between all |
… we can share the client across all running GooseUser
Goose point, I did not think about it and I'm not using cookies in my current load tests, I didn't detect it. I moved the cookies handling to the |
734d79b
to
66e6123
Compare
This addresses cookies, but there’s still a problem from shared headers. For example, if using http header authentication, with this PR once one GooseUser logs in all would be. |
For example, as documented here it's currently possible to set different headers with different GooseUsers, and this is required functionality for many load tests: |
This example will also need to be updated to show how to set custom cookies: |
Remove set_client_builder from GooseUser API. Rename set_client to set_client_builder on GooseAttack
I added support for default headers and custom cookies to the GooseUser. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the intent of this change? Why are you trying to share a single Client pool?
Goose intentionally maintains a unique client-per-GooseUser
, with the intent of better simulating independent users -- sharing a Client pool adds complexity and I worry this could result in unintended bugs. It also further ties Goose to the inner-workings of Reqwest, whereas the goal is to enhance Goose to support other client libraries and be less-tied to specific Reqwest implementation details.
I imagine there could be reduced memory requirements through this change, and possibly better startup-performance? (I am on the road an unable to test/validate this, which seems to be the only potential advantage of this added complexity?)
At this time I do not see sufficient value in merging this PR.
@@ -853,22 +853,21 @@ pub struct GooseUser { | |||
pub(crate) task_name: Option<String>, | |||
|
|||
session_data: Option<Box<dyn GooseUserData>>, | |||
|
|||
cookie_store: Jar, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add comments to the new fields (it seems this was also missed for the new session_data
; we can address that in a followup PR)
@@ -1582,6 +1586,12 @@ impl GooseUser { | |||
self.weighted_users_index, | |||
); | |||
|
|||
// Set cookies |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency add a .
to the end of the comment.
// Set cookies | ||
self.add_cookie_header(&mut request); | ||
|
||
// Set default headers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency add a .
to the end of the comment.
} | ||
|
||
// insert default headers in the request headers | ||
// without overwriting already appended headers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency, please start comment with a capital letter. Also, the line-break in the comment should come after appended
instead of after headers
.
/// | ||
/// In the following example, the Goose client is configured with a different user agent, | ||
/// sets a default header on every request, stores cookies, and supports gzip compression. | ||
/// Custom cookies can be manually set to each [`GooseUser`](./goose/struct.GooseUser.html). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set on
instead of set to
/// - You must include all desired configuration, as you are completely replacing Goose | ||
/// defaults. For example, if you want Goose clients to store cookies, you will have to | ||
/// include | ||
/// [`.cookie_store(true)`](https://docs.rs/reqwest/*/reqwest/struct.ClientBuilder.html#method.cookie_store). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe these last two comments remain relevant, and so should be preserved somewhere in the inline documentation.
The first two comments about test_start
and test_stop
I believe are no longer true with this PR?
The third comment about building a custom client per GooseUser is no longer possible with this PR?
self.cookie_store.add_cookie_str(cookie, &self.base_url); | ||
} | ||
|
||
/// Default headers can be manually set to each [`GooseUser`](./goose/struct.GooseUser.html). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set on
instead of set to
} | ||
|
||
/// Default headers can be manually set to each [`GooseUser`](./goose/struct.GooseUser.html). | ||
/// The headers will automatically been added to each request made by the [`GooseUser`](./goose/struct.GooseUser.html). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
be added
instead of been added
/// [`reqwest::cookie::Jar::add_cookie_str`]. Finally, the new cookie jar must be specified as the | ||
/// [`reqwest::ClientBuilder::cookie_provider`] for the custom client. | ||
/// | ||
/// Default headers doesn't overwrite already appended headers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do not
(or don't
) instead of doesn't
/// } | ||
/// ``` | ||
pub fn set_client_builder(mut self, client_builder: ClientBuilder) -> Result<Self, GooseError> { | ||
self.client = client_builder.cookie_store(false).build()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to make it impossible to enable the cookie_store
-- if that's the intent it needs to be documented.
@finnefloyd Thanks for all your contributions so far! I share Jeremy's sentiment that I would like to understand the motivation of the change a little bit more, before considering this PR. |
I used Goose recently, and I needed to create thoudands of users. Starting Goose took about thirty seconds. The tests themselves were not terribly long, so the startup time was significant. I solved this by monkey-patching goose to use a single reqwest client. (Cookies and headers weren't an issue for me.) This way the statup time disappeared. I know this is a corner case, but IMHO worth implementing client sharing. The general argument would be "because it's just more resource efficient". |
From Reqwest official documentation:
This PR, use a shared reqwest client among all GooseUser and allow the user the configure the global client.