File tree 2 files changed +38
-0
lines changed
main/java/com/softwaremill/jox
test/java/com/softwaremill/jox 2 files changed +38
-0
lines changed Original file line number Diff line number Diff line change @@ -100,6 +100,13 @@ public static <U> Object selectOrClosed(SelectClause<? extends U>... clauses) th
100
100
101
101
@ SafeVarargs
102
102
private static <U > Object doSelectOrClosed (SelectClause <? extends U >... clauses ) throws InterruptedException {
103
+ // short-circuiting if any of the channels is in error; otherwise, we might have selected a clause, for which
104
+ // a value was available immediately - even though a channel for a clause appearing later was in error
105
+ var anyError = getAnyChannelInError (clauses );
106
+ if (anyError != null ) {
107
+ return anyError ;
108
+ }
109
+
103
110
// check that the clause doesn't refer to a channel that is already used in a different clause
104
111
var allRendezvous = verifyChannelsUnique_getAreAllRendezvous (clauses );
105
112
@@ -132,6 +139,20 @@ private static boolean verifyChannelsUnique_getAreAllRendezvous(SelectClause<?>[
132
139
return allRendezvous ;
133
140
}
134
141
142
+ private static ChannelError getAnyChannelInError (SelectClause <?>[] clauses ) {
143
+ for (var clause : clauses ) {
144
+ var ch = clause .getChannel ();
145
+ if (ch != null ) {
146
+ // if a channel is in error, closedForSend() will return that information
147
+ var closedForSend = clause .getChannel ().closedForSend ();
148
+ if (closedForSend instanceof ChannelError ce ) {
149
+ return ce ;
150
+ }
151
+ }
152
+ }
153
+ return null ;
154
+ }
155
+
135
156
public static <T > SelectClause <T > defaultClause (T value ) {
136
157
return defaultClause (() -> value );
137
158
}
Original file line number Diff line number Diff line change @@ -222,4 +222,21 @@ void testBufferExpandedWhenSelecting() throws InterruptedException {
222
222
void testSelectFromNone () throws InterruptedException {
223
223
assertEquals (new ChannelDone (), selectOrClosed ());
224
224
}
225
+
226
+ @ Test
227
+ public void testSelect_immediate_withError () throws InterruptedException {
228
+ // given
229
+ Channel <String > ch1 = new Channel <>(2 );
230
+ ch1 .send ("x" );
231
+
232
+ var e = new RuntimeException ("boom!" );
233
+ Channel <String > ch2 = new Channel <>(2 );
234
+ ch2 .error (e );
235
+
236
+ // when
237
+ var result = selectOrClosed (ch1 .receiveClause (), ch2 .receiveClause ());
238
+
239
+ // then
240
+ assertEquals (new ChannelError (e ), result );
241
+ }
225
242
}
You can’t perform that action at this time.
0 commit comments