Skip to content

Commit 0fc2dfc

Browse files
committed
[#20,#26] Use Memoized Handler for send, always use timeouts for replies
1 parent 79e299e commit 0fc2dfc

File tree

3 files changed

+90
-35
lines changed

3 files changed

+90
-35
lines changed

src/main/java/io/vertx/rxcore/java/eventbus/RxEventBus.java

+42-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.vertx.rxcore.java.eventbus;
22

33
import io.vertx.rxcore.java.impl.HandlerSubscription;
4+
import io.vertx.rxcore.java.impl.MemoizeHandler;
45
import io.vertx.rxcore.java.impl.SingleSubscriptionHandler;
56
import org.vertx.java.core.AsyncResult;
67
import org.vertx.java.core.Handler;
@@ -34,17 +35,17 @@ public class RxEventBus {
3435
// Customer handlers
3536

3637
/** Standard SendHandler */
37-
protected static class SendHandler<R> extends SingleSubscriptionHandler<RxMessage<R>,Message<R>> {
38+
protected class SendHandler<R> extends MemoizeHandler<RxMessage<R>,Message<R>> {
3839
@Override public void handle(Message m) {
39-
fireResult(new RxMessage(m));
40+
complete(new RxMessageImpl(m));
4041
}
4142
}
4243

4344
/** Async SendHandler */
44-
protected static class AsyncSendHandler<R> extends SingleSubscriptionHandler<RxMessage<R>, AsyncResult<Message<R>>> {
45+
protected class AsyncSendHandler<R> extends SingleSubscriptionHandler<RxMessage<R>, AsyncResult<Message<R>>> {
4546
@Override public void handle(AsyncResult<Message<R>> r) {
4647
if (r.succeeded()) {
47-
fireResult(new RxMessage(r.result()));
48+
fireResult(new RxMessageImpl(r.result()));
4849
}
4950
else {
5051
fireError(r.cause());
@@ -53,7 +54,7 @@ protected static class AsyncSendHandler<R> extends SingleSubscriptionHandler<RxM
5354
}
5455

5556
/** Async HandlerSubscription */
56-
protected static class AsyncSendSubscription<R> extends HandlerSubscription<AsyncResult<Message<R>>,RxMessage<R>> {
57+
protected class AsyncSendSubscription<R> extends HandlerSubscription<AsyncResult<Message<R>>,RxMessage<R>> {
5758

5859
/** Create new AsyncSendSubscription */
5960
public AsyncSendSubscription(Subscriber<RxMessage<R>> s) {
@@ -63,7 +64,7 @@ public AsyncSendSubscription(Subscriber<RxMessage<R>> s) {
6364
/** Handle event */
6465
public void handle(AsyncResult<Message<R>> evt) {
6566
if (evt.succeeded()) {
66-
fireComplete(new RxMessage(evt.result()));
67+
fireComplete(new RxMessageImpl(evt.result()));
6768
}
6869
else {
6970
fireError(evt.cause());
@@ -72,19 +73,48 @@ public void handle(AsyncResult<Message<R>> evt) {
7273
}
7374

7475
/** Receive handler */
75-
protected static class ReceiveHandler<R> extends SingleSubscriptionHandler<RxMessage<R>,Message> {
76+
protected class ReceiveHandler<R> extends SingleSubscriptionHandler<RxMessage<R>,Message> {
7677
@Override public void handle(Message m) {
77-
fireNext(new RxMessage(m));
78+
fireNext(new RxMessageImpl(m));
7879
}
7980
}
80-
81+
82+
/** RxMessage implementation with inherited timeouts */
83+
protected class RxMessageImpl<R> extends RxMessage<R>
84+
{
85+
/** Create new RxMessageImpl */
86+
public RxMessageImpl(Message<R> coreMessage) {
87+
super(coreMessage);
88+
}
89+
90+
/** Observe a reply */
91+
public <R,T> Observable<RxMessage<T>> observeReply(final R msg)
92+
{
93+
return Observable.create(new AsyncSendHandler<T>() {
94+
@Override public void execute() {
95+
coreMessage.replyWithTimeout(msg,defaultTimeout,this);
96+
}
97+
});
98+
}
99+
100+
/** Observe a reply with timeout */
101+
public <R,T> Observable<RxMessage<T>> observeReplyWithTimeout(final R msg, final long timeout) {
102+
return Observable.create(new AsyncSendHandler<T>() {
103+
@Override public void execute() {
104+
coreMessage.replyWithTimeout(msg,timeout,this);
105+
}
106+
});
107+
}
108+
109+
}
110+
81111
// Instance variables
82112

83113
/** Core bus */
84114
private final EventBus eventBus;
85115

86116
/** Default timeout */
87-
private final int defaultTimeout;
117+
protected final int defaultTimeout;
88118

89119
// Public
90120

@@ -103,7 +133,7 @@ public RxEventBus(EventBus eventBus, int defaultTimeout) {
103133
public <S,R> Observable<RxMessage<R>> send(final String address, final S msg) {
104134
SendHandler<R> h=new SendHandler<R>();
105135
this.eventBus.send(address,msg,(Handler)h);
106-
return Observable.create(h);
136+
return Observable.create(h.subscribe);
107137
}
108138

109139
/** Send a message with timeout */
@@ -131,7 +161,7 @@ public <S,R> Observable<RxMessage<R>> observeSendWithTimeout(final String addres
131161
/** Send message for each subscription */
132162
public void call(Subscriber<? super RxMessage<R>> subscriber) {
133163
AsyncSendSubscription hs=new AsyncSendSubscription(subscriber);
134-
eventBus.sendWithTimeout(address, (Object)msg, timeout, (Handler)hs);
164+
eventBus.sendWithTimeout(address, (Object)msg, timeout, hs);
135165
subscriber.add(hs);
136166
}
137167
});

src/main/java/io/vertx/rxcore/java/eventbus/RxMessage.java

+5-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.vertx.rxcore.java.eventbus;
22

3+
import org.vertx.java.core.Handler;
34
import org.vertx.java.core.eventbus.Message;
45
import rx.Observable;
56

@@ -20,10 +21,10 @@
2021
*
2122
* @author <a href="http://tfox.org">Tim Fox</a>
2223
*/
23-
public class RxMessage<T> {
24+
public abstract class RxMessage<T> {
2425

2526
/** Core Message */
26-
private final Message<T> coreMessage;
27+
protected final Message<T> coreMessage;
2728

2829
/** Wrap Message with RxMessage */
2930
RxMessage(Message<T> coreMessage) {
@@ -49,7 +50,6 @@ public String replyAddress() {
4950
return coreMessage.replyAddress();
5051
}
5152

52-
5353
/**
5454
* @return The underlying core message
5555
*/
@@ -68,20 +68,8 @@ public <R> void reply(final R msg) {
6868
}
6969

7070
/** Observe a reply */
71-
public <R,T> Observable<RxMessage<T>> observeReply(final R msg) {
72-
return Observable.create(new RxEventBus.SendHandler<T>() {
73-
@Override public void execute() {
74-
coreMessage.reply(msg,this);
75-
}
76-
});
77-
}
71+
public abstract <R,T> Observable<RxMessage<T>> observeReply(final R msg);
7872

7973
/** Observe a reply with timeout */
80-
public <R,T> Observable<RxMessage<T>> observerReplyWithTimeout(final R msg, final long timeout) {
81-
return Observable.create(new RxEventBus.AsyncSendHandler<T>() {
82-
@Override public void execute() {
83-
coreMessage.replyWithTimeout(msg,timeout,this);
84-
}
85-
});
86-
}
74+
public abstract <R,T> Observable<RxMessage<T>> observeReplyWithTimeout(final R msg, final long timeout);
8775
}

src/test/java/io/vertx/rxcore/test/integration/java/EventBusIntegrationTest.java

+43-6
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
* @author <a href="http://tfox.org">Tim Fox</a>
1919
*/
2020

21+
import java.util.concurrent.TimeoutException;
2122
import java.util.concurrent.atomic.AtomicInteger;
2223

23-
import io.vertx.rxcore.RxSupport;
2424
import io.vertx.rxcore.java.eventbus.RxEventBus;
2525
import io.vertx.rxcore.java.eventbus.RxMessage;
2626
import io.vertx.rxcore.java.eventbus.RxStream;
@@ -29,17 +29,15 @@
2929
import org.vertx.java.core.Handler;
3030
import org.vertx.java.core.buffer.Buffer;
3131
import org.vertx.java.core.eventbus.Message;
32+
import org.vertx.java.core.eventbus.ReplyException;
3233
import org.vertx.java.core.json.JsonArray;
3334
import org.vertx.testtools.TestVerticle;
3435
import rx.Observable;
35-
import rx.Subscriber;
36-
import rx.Subscription;
3736
import rx.functions.*;
38-
import rx.subscriptions.Subscriptions;
3937

4038
import static io.vertx.rxcore.test.integration.java.RxAssert.assertCountThenComplete;
4139
import static io.vertx.rxcore.test.integration.java.RxAssert.assertMessageThenComplete;
42-
import static io.vertx.rxcore.test.integration.java.RxAssert.assertSingle;
40+
import static io.vertx.rxcore.test.integration.java.RxAssert.assertError;
4341
import static org.vertx.testtools.VertxAssert.assertEquals;
4442
import static org.vertx.testtools.VertxAssert.testComplete;
4543

@@ -64,6 +62,31 @@ public void call(RxMessage<String> message) {
6462
});
6563
}
6664

65+
@Test
66+
public void testDeferredSubscribe() {
67+
RxEventBus rxEventBus = new RxEventBus(vertx.eventBus());
68+
rxEventBus.<String>registerHandler("foo").subscribe(new Action1<RxMessage<String>>() {
69+
@Override
70+
public void call(RxMessage<String> message) {
71+
message.reply("pong!");
72+
}
73+
});
74+
// Message is sent on send
75+
final Observable<RxMessage<String>> obs = rxEventBus.send("foo", "ping!");
76+
// Defer the subscribe
77+
vertx.setTimer(100,new Handler<Long>() {
78+
public void handle(Long ev) {
79+
obs.subscribe(new Action1<RxMessage<String>>() {
80+
@Override
81+
public void call(RxMessage<String> message) {
82+
assertEquals("pong!", message.body());
83+
testComplete();
84+
}
85+
});
86+
}
87+
});
88+
}
89+
6790
@Test
6891
// Send some messages in series - i.e. wait for result of previous one before sending next one
6992
// PMCD: Added check to enforce 1-at-a-time
@@ -232,6 +255,21 @@ public Observable<RxMessage<String>> call(RxMessage<String> stringRxMessage) {
232255
assertMessageThenComplete(obsSend2,"goodday2");
233256
}
234257

258+
@Test
259+
public void testTimeout() {
260+
final RxEventBus rx=new RxEventBus(vertx.eventBus());
261+
262+
// Register handler that timesout
263+
rx.<String>registerHandler("thewall").subscribe(new Action1<RxMessage<String>>() {
264+
public void call(RxMessage<String> req) {
265+
// No-one listens
266+
assertError(req.observeReplyWithTimeout("pong",200),ReplyException.class);
267+
}
268+
});
269+
270+
rx.send("thewall","ping");
271+
}
272+
235273
@Test
236274
public void testRetry() {
237275

@@ -359,5 +397,4 @@ public Buffer call(JsonArray data) {
359397

360398
assertCountThenComplete(regulator.stream(res,out),401);
361399
}
362-
363400
}

0 commit comments

Comments
 (0)