-
Notifications
You must be signed in to change notification settings - Fork 79
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 config store #193
Add config store #193
Conversation
|
||
configStore.set("foo", "bar"); | ||
unlockedByTestThread.countDown(); | ||
unlockedBySubscribeThread.await(2, SECONDS); |
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.
CyclicBarrier seems more appropriate for this use case.
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 don't know what difference that would make.
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 would be using only one synchronising primitive instead of two. That cuts the complexity by 50% ;-).
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 this is conceptually much simpler:
public void listensOnSeparateThread2() {
final CyclicBarrier barrier = new CyclicBarrier(2);
configStore.watch("foo", String.class)
.subscribe(value -> {
await(barrier);
});
configStore.set("foo", "bar");
await(barrier);
}
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.
/** | ||
* Wrapper for CountDownLatch to make it more convenient to use. | ||
*/ | ||
public class Latch { |
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 per our unwritten naming conventions, utility classes names like this would have their name pluralised.
That is, the class name should be Latches
.
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 not a utility class. Utility classes have only static methods. This is a normal 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.
Right of course. Now I see that. I should have seen that straight away.
But why to implement these await methods as a composed class?
By making it a public test support class you are promoting its use in other tests. But then again the Latch
class is not type compatible with CountDownLatch
. Sooner or later some parts of the codebase will be using Latch
while other parts stick to CountDownLatch
. After that we will need to bridge the two classes at the interface level.
But all we really want is to re-propagate checked exceptions as runtime exceptions in await
method.
For these reasons, please convert this to a utility class with await
as a static utility 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.
I'll look into this.
/** | ||
* Wrapper for CountDownLatch to make it more convenient to use. | ||
*/ | ||
public class Latch { |
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 of course. Now I see that. I should have seen that straight away.
But why to implement these await methods as a composed class?
By making it a public test support class you are promoting its use in other tests. But then again the Latch
class is not type compatible with CountDownLatch
. Sooner or later some parts of the codebase will be using Latch
while other parts stick to CountDownLatch
. After that we will need to bridge the two classes at the interface level.
But all we really want is to re-propagate checked exceptions as runtime exceptions in await
method.
For these reasons, please convert this to a utility class with await
as a static utility method.
throw new IllegalStateException(format("Latch timed out: max wait was %s %s", timeout, unit)); | ||
} | ||
} catch (InterruptedException e) { | ||
currentThread().interrupt(); |
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.
Surely we need to re-throw something from the InterruptedException case? Otherwise await
just returns and the calling code carries on as if nothing happened.
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.
Sure I failed to notice that we had stopped throwing an Exception here. My advice is that we just let InterruptedException propagate...
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.
Unfortunately, Observable.subscribe
takes an Action1
as its argument, which will not allow InterruptedException
to be thrown.
private LatchesAndBarriers() { | ||
} | ||
|
||
public static void await(CountDownLatch latch, long timeout, TimeUnit unit) throws IllegalStateException { |
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.
We could have a method that receives (and returns) a lambda and catches/propagates the exception instead 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 think the problem is with the lambda expressions. Without this utility you would be forced to try/catch inside lambda expressions.
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 Mikko says, the problem is that InterruptedException
is a checked exception, and the interfaces our lambdas are implementing do not allow checked exceptions to be thrown.
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.
Oh, sure. I think some of the code inside the tests uses the Latch outside a lambda.
Then my suggestion of using a method that receives a lambda (with InterruptedException in the signature) and propagates InterruptedException as a RuntimeException (but keeping the Thread.interrupt() ) makes more sense than wrapping specific classes.
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.
Hi @dvlato. It no longer wraps a class. It is just a static helper method that accepts a CountDownLatch
as an argument. IMO it should just set the interrupted flag and propagate an InterruptedException wrapped inside a RuntimeException.
throw new IllegalStateException(format("Latch timed out: max wait was %s %s", timeout, unit)); | ||
} | ||
} catch (InterruptedException e) { | ||
currentThread().interrupt(); |
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.
Sure I failed to notice that we had stopped throwing an Exception here. My advice is that we just let InterruptedException propagate...
Cherry-picked from previous branch to styx-1.0-dev