What do the various ISubject implementations do and when would they be used? - system.reactive

I have a fairly good idea of what the Subject class does and when to use it, but I've just been looking through the language reference on msdn and see there are various other ISubject implementations such as:
AsyncSubject
BehaviorSubject
ReplaySubject
As the documentation is pretty thin on the ground, whats the point of each of these types and under what situations would you use them?

These subjects all share a common property - they take some (or all) of what gets posted to them via OnNext and record it and play it back to you - i.e. they take a Hot Observable and make it Cold. This means, that if you Subscribe to any of these more than once (i.e. Subscribe => Unsubscribe => Subscribe again), you'll see at least one of the same value again.
ReplaySubject: Every time you subscribe to the Subject, you get the entire history of what has been posted replayed back to you, as fast as possible (or a subset, like the last n items)
AsyncSubject: Always plays back the last item posted and completes, but only after the source has completed. This Subject is awesome for async functions, since you can write them without worrying about race conditions: even if someone Subscribes after the async method completes, they get the result.
BehaviorSubject: Kind of like ReplaySubject but with a buffer of one, so you always get the last thing that was posted. You also can provide an initial value. Always provides one item instantly on Subscribe.

In light of the latest version (v1.0.2856.0) and to keep this question up to date, there has been a new set of subject classes:
FastSubject, FastBehaviorSubject, FastAsyncSubject and FastReplaySubject
As per the release notes they
are much faster than regular subjects
but:
don’t decouple producer and consumer by an IScheduler
(effectively limiting them to
ImmediateScheduler);
don’t protect against stack overflow;
don’t synchronize input messages.
Fast subjects are used by Publish and
Prune operators if no scheduler is
specified.

In regards to AsyncSubject
This code:
var s = new AsyncSubject<int>();
s.OnNext(1);
s.Subscribe(Console.WriteLine);
s.OnNext(2);
s.OnNext(3);
s.OnCompleted();
prints a single value 3. And it prints same if subscription is moved to after completion. So it plays back not the first, but the last item, plays it after completion (until complete, it does not produce values), and it does not work like Subject before completion.
See this Prune discussion for more info (AsyncSubject is basically the same as Prune)

Paul's answer pretty much nails it. There's a few things worth adding, though:
AsyncSubject works as Paul says, but only after the source completes. Before that, it works like Subject (where "live" values are received by subscribers)
AsyncSubject has changed since I last ran tests against it. It no longer acts as a live subject before completion, but waits for completion before it emits a value. And, as Sergey mentions, it returns the last value, not the first (though I should have caught that as that's always been the case)
AsyncSubject is used by Prune, FromAsyncPattern, ToAsync and probably a few others
BehaviorSubject is used by overloads of Publish that accept an initial value
ReplaySubject is used by Replay
NOTE: All operator references above refer to the publishing set of operators as they were before they were replaced with generalised publish operators in rev 2838 (Christmas '10) as it has been mentioned that the original operators will be re-added

Related

second merged branch ignored in XStreams

I'm working on a Cycle JS app using storage and state plugins.
The app use xstream as reactive library.
I'm incapped in a strange behaviour.
My streams are as this diagram
On first session var update I got this debug result:
debug 0
debug 1
debug 3
PROBLEM: "Debug 2" branch is not executed
If I update the session item (so to produce a new storage event) the two branch ar all executed as expected
debug 0
debug 1
debug 2
debug 3
The same good behavior happen happen if add .remember() at "debug 0"
debug 0
debug 1
debug 2
debug 3
Even stranger, the flow work as expected if I remove filter
Without Filter (and without remember) the flow give this result since the first event
debug 0
debug 1
debug 2
debug 3
My suspect is something observe at "debug 0" before the second branch is attached and so the first event is already consumed.
But how can this happen if the two branch are xs.merged together? How can one branch be executed and second not? The two branch dosen't got filters or other processing, they mererly mapTo a reducer function.
Any suggestion on how to debug and resolve this situations?
The problem happens because storage.session.getItem emits as soon as it's subscribed, and merge(a$, b$) subscribes to a$ before it subscribes to b$, so a$ gets the event, but by the time b$ is subscribed, it has arrived too late. This problem is well known and is called a glitch (in reactive programming), and usually occurs when there is a diamond shaped stream graph, which is exactly your case.
I have two blog posts about glitches which can give you more context: Primer on RxJS schedulers and Rx glitches aren't actually a problem. It mentions RxJS, but xstream is quite close to RxJS in terms of implementation. The difference between xstream and RxJS is that xstream streams are always multicast ("shared"), and RxJS has many scheduler types, but xstream has only one. The default scheduler in RxJS is the same behavior as xstream has.
The solution is to apply .remember() before reaching the diamond. This is because the value being emitted needs to be cached for other consumers of that stream. .remember() simply converts the Stream to a MemoryStream. I think the source stream was initially a MemoryStream, and mapping a MemoryStream creates other MemoryStreams, but filter is an operator that breaks that. filter always returns a Stream, and the reason for this is that MemoryStreams should always have a current value, but filter can remove values, so it's possible that a filtered stream would not have any current value.
As the author of Cycle.js I believe the way cyclejs/storage is designed is not the best, and I think we will find ways of designing these APIs so that confusion with MemoryStream versus Stream is minimized. But for the time being, it's important to understand the difference between these two and plan your app so to avoid diamonds (and glitches), or to use .remember() in the right spots.

Clarification about Scala Future that never complete and its effect on other callbacks

While re-reading scala.lan.org's page detailing Future here, I have stumbled up on the following sentence:
In the event that some of the callbacks never complete (e.g. the callback contains an infinite loop), the other callbacks may not be executed at all. In these cases, a potentially blocking callback must use the blocking construct (see below).
Why may the other callbacks not be executed at all? I may install a number of callbacks for a given Future. The thread that completes the Future, may or may not execute the callbacks. But, because one callback is not playing footsie, the rest should not be penalized, I think.
One possibility I can think of is the way ExecutionContext is configured. If it is configured with one thread, then this may happen, but that is a specific behaviour and a not generally expected behaviour.
Am I missing something obvious here?
Callbacks are called within an ExecutionContext that has an eventually limited number of threads - if not by the specific context implementation, then by the underlying operating system and/or hardware itself.
Let's say your system's limit is OS_LIMIT threads. You create OS_LIMIT + 1 callbacks. From those, OS_LIMIT callbacks immediately get a thread each - and none ever terminate.
How can you guarantee that the remaining 1 callback ever gets a thread?
Sure, there could be some detection mechanisms built into the Scala library, but it's not possible in the general case to make an optimal implementation: maybe you want the callback to run for a month.
Instead (and this seems to be the approach in the Scala library), you could provide facilities for handling situations that you, the developer, know are risky. This removes the element of surprise from the system.
Perhaps most importantly - it enables the developer to "bake in" the necessary information about handler/task characteristics directly into his/her program, rather than relying on some obscure piece of language functionality (which may change from version to version).

Remove read topic from DDS

I have a problem with subscribing the data (using the java platform). When a subscriber subscribes to a topic, that subscribed data must be removed from the DDS. But in my case whenever I subscribe to the data the same data is subscribed many times. The data is not removed from the DDS. I tried with QoS but I don't know how to use it.
Please suggest how I can remove the read data from the DDS.
This behavior is not caused by your QoS settings, but by your method of accessing the DataReader. When you retrieve your data, you are probably calling something like the following read() in a loop:
FooReader.read(
dataSeq, infoSeq, 10,
ANY_SAMPLE_STATE.value,
ANY_VIEW_STATE.value,
ANY_INSTANCE_STATE.value);
The read() method invoked like this will return all currently available samples in your FooReader. After the read(), those samples still remain available in the FooReader, that is how the read() method behaves. Think of a read as a "peek". The next time that you invoke the read() method in this way, you will see all samples that you saw before, unless they have been overwritten by a new update from a DataWriter.
To resolve your issue, you could replace the read() with a take(), like this:
FooReader.take(
dataSeq, infoSeq, 10,
ANY_SAMPLE_STATE.value,
ANY_VIEW_STATE.value,
ANY_INSTANCE_STATE.value);
The take() method is different from the read() method in that it does a destructive read; it not only reads the data but also removes it from FooReader. That way, you will never receive the same sample twice. In fact, if you consistently use take() as opposed to read(), you will never be able to see any sample twice.
Another way to resolve your issue is to stick with read(), but adjust the requested SAMPLE_STATE, from ANY to NOT_READ, like this:
FooReader.read(
dataSeq, infoSeq, 10,
NOT_READ_SAMPLE_STATE.value,
ANY_VIEW_STATE.value,
ANY_INSTANCE_STATE.value);
That way, you will only read samples that you have not read previously. The difference with take() in this case is that the data does remain available in your FooReader, which might be useful if you want to re-read it at a later stage (in which case you need to use the ANY sample state as opposed to NOT_READ to obtain previously read samples).

Implementing snapshot in FRP

I'm implementing an FRP framework in Scala and I seem to have run into a problem. Motivated by some thinking, this question I decided to restrict the public interface of my framework so Behaviours could only be evaluated in the 'present' i.e.:
behaviour.at(now)
This also falls in line with Conal's assumption in the Fran paper that Behaviours are only ever evaluated/sampled at increasing times. It does restrict transformations on Behaviours but otherwise we find ourselves in huge problems with Behaviours that represent some input:
val slider = Stepper(0, sliderChangeEvent)
With this Behaviour, evaluating future values would be incorrect and evaluating past values would require an unbounded amount of memory (all occurrences used in the 'slider' event would have to be stored).
I am having trouble with the specification for the 'snapshot' operation on Behaviours given this restriction. My problem is best explained with an example (using the slider mentioned above):
val event = mouseB // an event that occurs when the mouse is pressed
val sampler = slider.snapshot(event)
val stepper = Stepper(0, sampler)
My problem here is that if the 'mouseB' Event has occurred when this code is executed then the current value of 'stepper' will be the last 'sample' of 'slider' (the value at the time the last occurrence occurred). If the time of the last occurrence is in the past then we will consequently end up evaluating 'slider' using a past time which breaks the rule set above (and your original assumption). I can see a couple of ways to solve this:
We 'record' the past (keep hold of all past occurrences in an Event) allowing evaluation of Behaviours with past times (using an unbounded amount of memory)
We modify 'snapshot' to take a time argument ("sample after this time") and enforce that that time >= now
In a more wacky move, we could restrict creation of FRP objects to the initial setup of a program somehow and only start processing events/input after this setup is complete
I could also simply not implement 'sample' or remove 'stepper'/'switcher' (but I don't really want to do either of these things). Has anyone any thoughts on this? Have I misunderstood anything here?
Oh I see what you mean now.
Your "you can only sample at 'now'" restriction isn't tight enough, I think. It needs to be a bit stronger to avoid looking into the past. Since you are using an environmental conception of now, I would define the behavior construction functions in terms of it (so long as now cannot advance by the mere execution of definitions, which, per my last answer, would get messy). For example:
Stepper(i,e) is a behavior with the value i in the interval [now,e1] (where e1 is the
time of first occurrence of e after now), and the value of the most recent occurrence of e afterward.
With this semantics, your prediction about the value of stepper that got you into this conundrum is dismantled, and the stepper will now have the value 0. I don't know whether this semantics is desirable to you, but it seems natural enough to me.
From what I can tell, you are worried about a race condition: what happens if an event occurs while the code is executing.
Purely functional code does not like to have to know that it gets executed. Functional techniques are at their finest in the pure setting, such that it does not matter in what order code is executed. A way out of this dilemma is to pretend that every change happened in one sensitive (internal, probably) piece of imperative code; pretend that any functional declarations in the FRP framework happen in 0 time so it is impossible for something to change during their declaration.
Nobody should ever sleep, or really do anything time sensitive, in a section of code that is declaring behaviors and things. Essentially, code that works with FRP objects ought to be pure, then you don't have any problems.
This does not necessarily preclude running it on multiple threads, but to support that you might need to reorganize your internal representations. Welcome to the world of FRP library implementation -- I suspect your internal representation will fluctuate many times during this process. :-)
I'm confused about your confusion. The way I see is that Stepper will "set" the behavior to a new value whenever the event occurs. So, what happens is the following:
The instant in which the event mouseB occurs, the value of the slider behavior will be read (snapshot). This value will be "set" into the behavior stepper.
So, it is true that the Stepper will "remember" values from the past; the point is that it only remembers the latest value from the past, not everything.
Semantically, it is best to model Stepper as a function like luqui proposes.

Tutorial OpenCl event handling

In my last question, OpenCl cleanup causes segfault. , somebody hinted that missing event handling, i.e. not waiting for code to finish, could cause the seg faults. Since then I looked again into the tutorials I used, but they don't pay attention to events (Matrix Multiplication 1 (OpenCL) and NVIDIA_OpenCL_GettingStartedLinux.pdf) or talk about it in detail and (for me) understandable.
Do you know a tutorial on where and how to wait in OpenCL?
Merci!
I don't have a tutorial on events in OpenCL, and I'm by no means an expert, but since no one else is responding...
As a rule of thumb, you'll need to wait for any function named clEnqueue*. Those functions return immediately before the job is done. The easiest way to make sure your queue is finished is to call clFinish(). It won't return until the entire queue has completed.
If you want to get a little fancier, most of the clEnqueue* functions have an optional cl_event parameter that you can pass in. You can check on a particular event with clGetEventInfo(), and you can wait for a particular set of events to finish with clWaitForEvents().