-
-
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
Add session setting support for specs #381
Add session setting support for specs #381
Conversation
7c8cf23
to
abd54a2
Compare
5c413c3
to
333108a
Compare
fb33c98
to
ab00a48
Compare
This adds support for session settings for the various specs formats. These session settings will be applied by the http/pg client before the spec is executed.
ab00a48
to
09110ba
Compare
@@ -63,7 +63,7 @@ def parse(self, string, name='<string>'): | |||
class SourceBuildTest(TestCase): | |||
|
|||
def test_build_from_branch(self): | |||
self.assertIsNotNone(get_crate('4.1')) | |||
self.assertIsNotNone(get_crate('5.8')) |
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.
Gradle based builds are failing on the ci machines.
@mfussenegger Ready for review! |
cr8/clients.py
Outdated
conn = aiohttp.TCPConnector(**self._connector_params) | ||
self.__session = session = aiohttp.ClientSession(connector=conn) | ||
for setting, value in self.session_settings.items(): | ||
payload = {'stmt': f'set {setting}={value}'} | ||
await _exec( | ||
session, | ||
next(self.urls), | ||
dumps(payload, cls=CrateJsonEncoder) | ||
) |
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.
TCPConnector
afaik internally does some pooling, so this will have the opposite problem of the asyncpg variant in that it only ever gets called once per session initialization instead of once per connection.
It's probably necessary to subclass the TCPConnector
to customize _create_connection
.
Running the spec mentioned above shows:
cr> select stmt, count(*) from sys.jobs_log group by stmt order by 2 desc ;
+----------------------------------+----------+
| stmt | count(*) |
+----------------------------------+----------+
| select count(*) from sys.summits | 1000 |
| set timezone=UTC | 2 |
| set application_name=my_app | 2 |
| ANALYZE | 1 |
+----------------------------------+----------+
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.
Why did you mark this as resolved, there are no changes for this?
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.
It's resolved, see the results.
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.
The settings were set for multiple clients.
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 i miss something here ? What should be the expected output for the spec with concurrency 10 ?
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.
It should run set ..
for each connection it establishes.
With concurrency = 10
I'd expect there to be more than 1 call in the sys.jobs_log
output.
You can also verify how many connections it made via:
cr> select connections from sys.nodes limit 10;
+-----------------------------------------------------------------------------------------------------------+
| connections |
+-----------------------------------------------------------------------------------------------------------+
| {"http": {"open": 1, "total": 12}, "psql": {"open": 0, "total": 0}, "transport": {"open": 0, "total": 0}} |
+-----------------------------------------------------------------------------------------------------------+
The numbers should add up
@mfussenegger Thanks for the feedback. Here are the results after the last changes. test.toml:
cr8 run-spec test.toml localhost:4200
cr8 run-spec test.toml asyncpg://localhost:5432
test.toml:
cr8 run-spec test.toml localhost:4200
cr8 run-spec test.toml asyncpg://localhost:5432
Note: The asyncpg client sets with concurrency 10, 12 pools with 10 connections, therefore each session setting is only applied once. |
cr8/engine.py
Outdated
for setting, value in self.session_settings.items(): | ||
stmt = f'set {setting}={value}' | ||
statements = itertools.repeat((stmt, ()), self.concurrency) | ||
aio.run_many(f, statements, self.concurrency, self.concurrency) |
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 works. it's not so elegant. It runs in parallel with the set statement n times for n connections. I tried various approaches but this is straight forward.
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.
@mfussenegger Do you have any opinion on this approach? I think this needs some cleanup, but would you be ok with this solution?
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.
Besides breaking encapsulation I think this might become unrealiable with a higher concurrency. The first set statements can finish before laters are triggered - which means a connection could get re-used instead of creating a new one for each set
I think I'd rather have a minimal extra pool implementation in the client on top of the session, and setting limit=1 on the underlying connector to ensure there is no double pooling.
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.
ok, makes sense. Thanks for the feedback.
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 think I'd rather have a minimal extra pool implementation in the client on top of the session, and setting limit=1 on the underlying connector to ensure there is no double pooling.
Do you mean a pool with multiple instances of TCPConnector
?
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 would mean I would need to create also multiple ClientSessions
, one for each TCPConnector
and pool them too.
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.
A custom Connector
where I maintain the connections is not an option, because I need to have a ClientSession to run HTTP operations on top of this.
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 can try the option of using multiple ClientSessions
each having it's own TCPConnector
with limit 1 and see how the performance is.
50b02a3
to
2d008ae
Compare
@mfussenegger Here is a naive pool implementation for the http client. Surprisingly this improves throughput on the spec: cr8 run-spec test.toml localhost:4200 master:
with pool:
|
However, on higher concurrency (100) this is very inefficient. |
I don't know how to proceed here. I think it's easier not to deal with this on the client level and instead create a user and set a session default. |
What do you think about dropping the support for session settings for the HTTP client and using the asyncpg client for the benchmarks? |
54d5fbc
to
e341947
Compare
b742916
to
08ce745
Compare
08ce745
to
1dcdcd3
Compare
Added a fixup for the pooling - as far as I can tell it should be working as intended now |
Thanks for the help. Appreciated! |
This adds support for session settings for specs. The session settings will be applied to each connection before executing the spec.