Say I have an observableA which gets data from network and emits it, if I do subscription to this observable each time it tries to request data from network which is heavy.
I want to create BehaviorSubject and connect it to observableA, so that any other threads/objects will subscribe to BehaviorSubject in order to get latest emitted data.
So far I couldnt manage it to code. I cannot create empty BehaviorSubject and call inside observableA, because they are not related to each other.
I cannot subscribe to observableA and get BehaviorSubject as observer, any idea how can I accomplish it? or maybe even better?
You can use multicast. E.g.,
Observable<String> o = ...;
ConnectableObservable<String> co = o.multicast(BehaviorSubject.<String> create());
co.connect();
co.subscribe(...);
co.subscribe(...);
co.subscribe(...);
I had similar scenario in javascript where I wrapped promise within Rx and I didn't want to make network call again when I subscribe to observable. This is how I ended up implementing:
subject = new Rx.AsyncSubject();
observable = Rx.Observable.fromPromise(....).subscribe(subject);
You can now consume the promise response as subject.subscribe(...) and it will always emit promise result from subject as we are using AsyncSubject (AsyncSubject - Represents the result of an asynchronous operation. The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers).
In Rx.NET we'd use one of the Publish overloads that accepts an initialValue parameter. Essentially, it's just a shorter way of doing a multicast like zsxwing described. I'm not sure whether Rx.Java offers these overloaded Publish methods.
Related
I am new to testing un RxSwift.
I manage to test that an Observable emits values with RxBlocking. But I can't find the syntax to make a test pass if an Observable did not send any value.
I think I should use toBlocking(timeout: ),but I can't find how (I have an error that it timed out, but the test fail).
Thank you for your help
Does your observable complete? It looks like you're testing to see if the observable emits any events not values
Assuming you are testing on the XCTest Framework,
If you are testing to see if the observable emits no elements before it completes,
XCTAssertNil(try observable.toBlocking().first())
If you are testing to see if the observable does not emit any elements, nor completes
// Check error if necessary
XCTAssertThrowsError(try observable.toBlocking(timeout: timeout).first())
I am using ReplaySubject as a pipe when I feed the Observer with OnNext messages and then I subscribe to the message in another part of the code.
I tried ISubject first, by using Subject.Create(observer:, observable:) but this seems to do nothing, or in other words, the Observer is a sink that goes nowhere. Is there some code that will make the Subject do something pipe-like. For example, I want to inject onNext messages with a integral countN and I want the observable to broadcast N-many 0.00E0(s) in sequence.
UPDATE:
It seems I need to implement the ISubject interface. Is there source code for a simple implementation that functions the same as ReplaySubject, with simple, proper memory handling of buffer size and Observer collection and Disposable return object.
Ok, so you use
new Subject<Int32>()
to get a subject that is a pipe-line.
Someone care to explain what Subject.Create does?
Can you inherit from Subject or ReplaySubject? Should you be able to?
Since I'm quite new to Reactive Extensions, I was curious about the following things.
By using Rx in Scala, I want to be able to call a method that retrieves content from an API every second.
So far, I've taken a look at the creational operators used within Rx such as Interval, Timer and so forth. But unfortunately, I cannot come up with the correct solution.
Does anyone have some experience with this, and preferably code examples to share?
Thanks in advance!
Using RxJava:
Observable.interval(1, TimeUnit.SECONDS)
.map(interval -> getSuffFromApi()) //Upto here, we have an observable the spits out the data from the API every second
.subscribe(response-> System.out.println(response)); //Now we just subscribe to it
Or:
Observable.interval(1, TimeUnit.SECONDS) //Emit every second
.subscribe(interval ->System.out.println(getSuffFromApi())) //onNext - get the data from the API and print it
I'm using the Play Framework with scala. I'm new to scala, akka, and play.
This is my actor system. I'm not sure I'm doing this right, but I have 2 routers. 1 for Actor A, and 1 for Actor B:
val system = ActorSystem("ActionSystem")
val actorARouter = system.actorOf(Props[ActionParser].withRouter(
SmallestMailboxRouter(Runtime.getRuntime.availableProcessors())), name = "actorARouter")
val actorBRouter = system.actorOf(Props[ActionDispatcher].withRouter(
SmallestMailboxRouter(Runtime.getRuntime.availableProcessors())), name = "actorBRouter")
This is the current setup that I have:
The play framework provides a Controller for me that receives a http rest call with some json. Whenever the Controller receives a rest call, I do an ask sends the json to a router for Actor A. Here is what that looks like:
(actorARouter ? request.body.asJson.get).map {
case m: controllers.HttpMessages.OK => Ok(m.body)
case m: controllers.HttpMessages.HttpResponse => Status(m.status)(m.body)
}
Actor A then parses the json into a Seq of objects and then sends them via an ask to Actor B. Actor B is supposed to eventually process those by sending them to other actors, but for now is just returning generic responses.
The generic responses are being received back by ActorA via the future, then being parsed to JSON and then returned to the Controller via an OK response... or at least that's what is supposed to happen.
What's happening:
So what's happening is the controller sends to ActorA, ActorA sends to ActorB. ActorB sends generic responses to ActorA. ActorA parses generic responses into JSON and tries to do sender ! OK(json) but I get a message in the console saying it wasn't delivered as it's a "dead letter". when I debug into it when I look at sender, sender is a reference to the actor akka://ActionSystem/deadLetters
My questions:
Obviously I'm doing something wrong. Maybe I shouldn't be chaining these actors responses together like this. Again, I mentioned I only had plans to further this by having ActorB send out requests to other actors.
When I do an ask in an actor, that doesn't hog that thread and stop it from processing other messages while it's waiting for a response does it?
EDIT:
I found out I can save a reference to the sender for later use, and then send to that, and that seems to fix the dead letter problem. But I'm still very uncertain if this is the right way to be doing things. It feels like every time I'm adding another layer of actors 10's of milliseconds are being added onto my response time. Perhaps that's due to other factors though.
Without looking at your code, I cannot really comment on what caused the dead letter, from your edit I guess you closed over sender() instead of assigning it to a variable and closing over that.
To respond to your questions:
It is much easier to construct message flows with actors if you only use fire-and-forget messages. The ask Pattern is useful in some cases, but most of the time you should try to avoid it. What you can do instead is to pass the original sender along through your actors by using forward instead of tell. This way a response can be generated by the last actor in your message flow. The first actor only needs the code to handle the response, and does not need to care about generating the response. Nice separation of concerns right there. If you need to aggregate several responses in order to send out a single response afterwards, you can also use a temporary actor that all other actors will send their response to, and that knows the orignal sender. Temporary actors need to be stopped after doing their work.
As far as I know the ask pattern is asynchronous and uses temporary actors internally. However, if you wait for the result of the future in your actor, that will block that actor, and it will not be able to process further messages. A nice method to use the ask pattern is in combination with the pipeTo Pattern, which you can use to send the result of ask to an actor (usally self)
I am reading libpq reference. It has both of sync and async methods. Bu I discovered something strange.
When I see PQsendQuery function, it seems to send a query and return immediately. And I expected a callback function to get notified, but there was no such thing and the manual says to poll for data availability.
I don't understand why async method is written in polling way. Anyway, as libp is the official client implementation, I believe there should be a good reason for this design. What is that? Or am I missing correct callback stuffs mentioned somewhere else?
In the execution model of a mono-threaded program, the execution flow can't be interrupted by data coming back from an asynchronous query, or more generally a network socket. Only signals (SIGTERM and friends) may interrupt the flow, but signals can't be hooked to data coming in.
That's why having a callback to get notified of incoming data is not possible. The piece of code in libpq that would be necessary to emit the callback would never run if your code doesn't call it. And if you have to call it, that defeats the whole point of a callback.
There are libraries like Qt that provide callbacks, but they're architectured from the ground up with a main loop that acts as an event processor. The user code is organized in callbacks and event-based processing of incoming data is possible. But in this case the library takes ownership of the execution flow, meaning its mainloop polls the data sources. That just shifts the responsibility to another piece of code outside of libpq.
This page is describing how I can get be notified for async result fetch.
http://www.postgresql.org/docs/9.3/static/libpq-events.html#LIBPQ-EVENTS-PROC
PGEVT_RESULTCREATE
The result creation event is fired in response to any query execution
function that generates a result, including PQgetResult. This event
will only be fired after the result has been created successfully.
typedef struct {
PGconn *conn;
PGresult *result; } PGEventResultCreate; When a PGEVT_RESULTCREATE event is received, the evtInfo pointer should be cast to a
PGEventResultCreate *. The conn is the connection used to generate the
result. This is the ideal place to initialize any instanceData that
needs to be associated with the result. If the event procedure fails,
the result will be cleared and the failure will be propagated. The
event procedure must not try to PQclear the result object for itself.
When returning a failure code, all cleanup must be performed as no
PGEVT_RESULTDESTROY event will be sent.