-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Implement flush coalescing in OkHttp. #4763
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
Conversation
ejona86
left a comment
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.
Note that checkstyle is failing in the CIs.
| @Before | ||
| public void setUp() throws Exception { | ||
| queueingExecutor = new QueueingExecutor(); | ||
| asyncFrameWriter = spy(new AsyncFrameWriter(transport, new SerializingExecutor(queueingExecutor))); |
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, please no spies. They are so very magical, I don't trust tests with them.
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.
spy is gone!
| queueingExecutor.runAll(); | ||
|
|
||
| verify(frameWriter, times(1)).ping(anyBoolean(), anyInt(), anyInt()); | ||
| verify(asyncFrameWriter, times(1)).flush(); |
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 point of this verification, here and elsewhere? Isn't this test the thing that called this method, on line 56?
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.
right. removed unnecessary verify.
|
|
||
| private static abstract class PartiallyTrackingFrameWriter implements FrameWriter { | ||
|
|
||
| private static final List<Method> methods = new ArrayList<Method>(); |
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 is just asking for trouble, as one test can influence another. Actually... how is flushCoalescing_shouldMergeTwoQueuedFlushes working? Nothing is clearing out these methods.
Implementation is skipping flush task if another flush is queued.
b9a47eb to
7df7e80
Compare
| @@ -0,0 +1,151 @@ | |||
| /* | |||
| * Copyright 2015 The gRPC Authors | |||
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.
2018
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.
thanks!
|
|
||
| verify(frameWriter, times(2)).ping(anyBoolean(), anyInt(), anyInt()); | ||
| verify(frameWriter, times(1)).flush(); | ||
| assertThat(Iterables.getLast(PartiallyTrackingFrameWriter.getAllInvokedMethodsHistory())) |
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 not use inOrder?
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.
didn't know that exists. thanks!
e1b8e8b to
26ef499
Compare
carl-mastrangelo
left a comment
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.
One nit but LGTM
| } | ||
|
|
||
| /** | ||
| * Executor queues incoming runnables instead of running it. Runnables can be invoked via {@code |
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 should be #link
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.
|
|
||
| @Before | ||
| public void setUp() throws Exception { | ||
| queueingExecutor = new QueueingExecutor(); |
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.
nit: Initialize at the declaration above.
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.
|
|
||
| @After | ||
| public void tearDown() throws Exception { | ||
| asyncFrameWriter.close(); |
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's the point of this? It is guaranteed to do nothing. If we wanted to close the (mock) socket there would need to be a runAll() here.
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.
| @RunWith(MockitoJUnitRunner.class) | ||
| public class AsyncFrameWriterTest { | ||
|
|
||
| @Mock private OkHttpClientTransport transport; |
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.
Mocking a functional class like the transport is worrisome to me. Only a single method is used, could we make an interface for it and have the transport implement that interface?
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.
yes, created an interface TransportExceptionHandler, can you review this part?
…ndler which makes AsyncFrameWriter accept the interface rather than a transport.
|
|
||
| @After | ||
| public void tearDown() throws Exception { | ||
| queueingExecutor.clear(); |
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 does nothing, as this test class instance will be thrown away. So you're clearing something before it is cleared by the GC.
|
|
||
| @Override | ||
| public void onException(Throwable throwable) { | ||
| throw Status.INTERNAL.asRuntimeException(); |
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 throws away the Throwable, and we don't use StatusRuntimeException too much like this. How about just new AssertionError(throwable)?
| @Before | ||
| public void setUp() throws Exception { | ||
| asyncFrameWriter = | ||
| new AsyncFrameWriter(transportExceptionHandler, new SerializingExecutor(queueingExecutor)); |
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.
nit: this could also be moved up to the declaration, now that the transport isn't a mock.
ejona86
left a comment
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.
Looks good. Make sure to squash when merging.
Implementation is skipping flush task if another flush is queued.
Resolves #3258