14
14
* limitations under the License.
15
15
*/ package rx .quasar ;
16
16
17
+ import co .paralleluniverse .fibers .FiberAsync ;
17
18
import co .paralleluniverse .fibers .SuspendExecution ;
18
19
import co .paralleluniverse .fibers .Suspendable ;
19
20
import co .paralleluniverse .strands .Strand ;
20
21
import co .paralleluniverse .strands .channels .Channel ;
21
22
import co .paralleluniverse .strands .channels .Channels ;
22
23
import co .paralleluniverse .strands .channels .ReceivePort ;
23
24
import co .paralleluniverse .strands .channels .SendPort ;
25
+ import java .util .concurrent .ExecutionException ;
26
+ import java .util .concurrent .TimeUnit ;
27
+ import java .util .concurrent .TimeoutException ;
24
28
import rx .Observable ;
25
29
import rx .Observer ;
26
30
import rx .Scheduler ;
@@ -45,7 +49,7 @@ private ChannelObservable() {
45
49
* @return an Observable that emits each message received on the source {@link ReceivePort}
46
50
* @see <a href="https://github.com/Netflix/RxJava/wiki/Creating-Observables#wiki-from">RxJava Wiki: from()</a>
47
51
*/
48
- public final static <T > Observable <T > from (ReceivePort <T > channel ) {
52
+ public static <T > Observable <T > from (ReceivePort <T > channel ) {
49
53
return Observable .create (new OnSubscribeFromChannel <T >(channel ));
50
54
}
51
55
@@ -67,7 +71,7 @@ public final static <T> Observable<T> from(ReceivePort<T> channel) {
67
71
* @see <a href="https://github.com/Netflix/RxJava/wiki/Creating-Observables#wiki-from">RxJava Wiki: from()</a>
68
72
* @see <a href="http://msdn.microsoft.com/en-us/library/hh212140.aspx">MSDN: Observable.ToObservable</a>
69
73
*/
70
- public final static <T > Observable <T > from (ReceivePort <T > channel , Scheduler scheduler ) {
74
+ public static <T > Observable <T > from (ReceivePort <T > channel , Scheduler scheduler ) {
71
75
return Observable .create (new OnSubscribeFromChannel <T >(channel )).subscribeOn (scheduler );
72
76
}
73
77
@@ -79,7 +83,7 @@ public final static <T> Observable<T> from(ReceivePort<T> channel, Scheduler sch
79
83
* @param channel the target {@link SendPort}
80
84
* @return
81
85
*/
82
- public final static <T > Observer <T > to (final SendPort <T > channel ) {
86
+ public static <T > Observer <T > to (final SendPort <T > channel ) {
83
87
return new Observer <T >() {
84
88
85
89
@ Override
@@ -115,9 +119,9 @@ public void onError(Throwable e) {
115
119
* @param o the observable
116
120
* @return A new channel with the given buffer size and overflow policy that will receive all events emitted by the observable.
117
121
*/
118
- public final static <T > ReceivePort <T > subscribe (int bufferSize , Channels .OverflowPolicy policy , Observable <T > o ) {
122
+ public static <T > ReceivePort <T > subscribe (int bufferSize , Channels .OverflowPolicy policy , Observable <T > o ) {
119
123
final Channel <T > channel = Channels .newChannel (bufferSize , policy );
120
-
124
+
121
125
o .subscribe (new Observer <T >() {
122
126
@ Override
123
127
@ Suspendable
@@ -143,4 +147,72 @@ public void onError(Throwable e) {
143
147
});
144
148
return channel ;
145
149
}
150
+
151
+ /**
152
+ * Takes an observable that generates <i>at most one value</i>, blocks until it completes and returns the result.
153
+ * If the observable completes before a value has been emitted, this method returns {@code null}.
154
+ * It the observable fails, this function throws an {@link ExecutionException} that wraps the observable's exception.
155
+ *
156
+ * @param o the observable
157
+ * @return the observable's result, or {@code null} if the observable completes before a value is emitted.
158
+ * @throws ExecutionException if the observable fails
159
+ */
160
+ public static <T > T get (final Observable <T > o ) throws ExecutionException , SuspendExecution , InterruptedException {
161
+ return new AsyncObservable <T >(o ).run ();
162
+ }
163
+
164
+ /**
165
+ * Takes an observable that generates <i>at most one value</i>, blocks until it completes or the timeout expires, and returns the result.
166
+ * If the observable completes before a value has been emitted, this method returns {@code null}.
167
+ * It the observable fails, this function throws an {@link ExecutionException} that wraps the observable's exception.
168
+ *
169
+ * @param o the observable
170
+ * @param timeout the maximum time this method will blcok
171
+ * @param unit the timeout's time unit
172
+ * @return the observable's result, or {@code null} if the observable completes before a value is emitted.
173
+ * @throws ExecutionException if the observable fails
174
+ * @throws TimeoutException if the timeout expires before the observable completes
175
+ */
176
+ public static <T > T get (final Observable <T > o , long timeout , TimeUnit unit ) throws ExecutionException , SuspendExecution , InterruptedException , TimeoutException {
177
+ return new AsyncObservable <T >(o ).run (timeout , unit );
178
+ }
179
+
180
+ private static class AsyncObservable <T > extends FiberAsync <T , Void , ExecutionException > implements Observer <T > {
181
+ private final Observable <T > o ;
182
+
183
+ public AsyncObservable (Observable <T > o ) {
184
+ this .o = o ;
185
+ }
186
+
187
+ @ Override
188
+ protected Void requestAsync () {
189
+ o .subscribe (this );
190
+ return null ;
191
+ }
192
+
193
+ @ Override
194
+ public void onNext (T t ) {
195
+ if (isCompleted ())
196
+ throw new IllegalStateException ("Operation already completed" );
197
+ asyncCompleted (t );
198
+ }
199
+
200
+ @ Override
201
+ public void onError (Throwable e ) {
202
+ if (isCompleted ())
203
+ throw new IllegalStateException ("Operation already completed" );
204
+ asyncFailed (e );
205
+ }
206
+
207
+ @ Override
208
+ public void onCompleted () {
209
+ if (!isCompleted ())
210
+ asyncCompleted (null );
211
+ }
212
+
213
+ @ Override
214
+ protected ExecutionException wrapException (Throwable t ) {
215
+ return new ExecutionException (t );
216
+ }
217
+ }
146
218
}
0 commit comments