-
-
Notifications
You must be signed in to change notification settings - Fork 213
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
Receive packet after each block insert, so profile events are not missed #392
Changes from 2 commits
015eac6
d52f4ab
0cf555c
4ec897f
a1eeedc
ce63ac6
7bb9a63
a771321
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from tests.testcase import BaseTestCase | ||
|
||
|
||
class LongInsertTestCase(BaseTestCase): | ||
client_kwargs = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would say that this settings deserves some comments:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @insomnes we have time limit of 10s for each test. Is 5s enough for reproducing? It seems that Should we patch def side_receive_profile_events(*args, **kwargs):
# do something, toggle flag, etc.
return receive_profile_events(*args, **kwargs)
with patch('socket.getaddrinfo') as side_receive_profile_events:
receive_profile_events.side_effect = side_receive_profile_events
self.client.execute('INSERT INTO ...')
# assert something happened in side_receive_profile_events See There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @xzkostyan thank you for the clarification. I would need a bit of time to wrap my head around this. This test depends on server behavior and I can't come up with an appropriate mock from the get-go. With the unpatched function and this synthetic data, this will for sure error in the first 5 seconds as With the patched one it would take a long for the proper ending cause we process 100 000 ProfileEvents packets on new server versions. I will try to think about it a bit more and come back with a solution. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @xzkostyan sorry for the long pause. What do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just out of curiosity I looked at this change, and this hack looks nice, though it was not clear how it works at first glance (when the driver do not receive profile events it will call receive_end_of_query, which will read all ProfileEvents and also EndOfStream, but it will sleep each time to 2 seconds, so eventually the server will timed out, and it does not timed out for EndOfStream, because it will be written to socket buffer) But I think that it should be fixed differently, instead And this will match with how ClickHouse handle this protocol internally for INSERT, so this is preferable I would say. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Something like this - https://gist.github.com/azat/da85ff0bde3f0da259144b0ba361cd64 BTW it also founds one problem in this patch - missing reading of ProfileEvents after empty block P.S. @insomnes this patch is done on top of your latest changes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @xzkostyan hello again! I've applied @azat suggestion with a slight adjustment of moving method to client, and accepting possible Progress event in it (I found the possibility of Progress packet coming before ProfileEvents in test). Azat confirmed that it is normal and expected behavior from the server side. There is only a simple insert test now. I have deleted the previous one, cause it still fails due to timeout inside github. If you think, that some more direct test should be applied, maybe we can check that This breaks backward compatibility in some sens, so If you think this should be made other way, I would be happy to change code according to your vision. |
||
'settings': { | ||
'insert_block_size': 1, | ||
'send_timeout': 1, | ||
'receive_timeout': 1, | ||
}, | ||
'send_receive_timeout': 2, | ||
} | ||
|
||
def test_long_insert(self): | ||
data = [{'x': 1}] * 100_000 | ||
self.client.execute( | ||
'insert into function null(\'x Int\') (x) values', | ||
data | ||
) |
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 it is better to explicitly allow only
ServerPacketTypes.PROFILE_EVENTS
(to make it compatible with ClickHouse code base).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've used the existing function cause it receives the packet and also correctly handles the exception type. And as I get from sources, there is no extra processing function for ProfileEvent.
My goal was a minimal intervention, cause I am not familiar enough with overall packet processing in the library.
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.
As I get it you propose adding some method like this on connection class?
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.
Exactly.
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.
Done