Why do I need to dispose of subscriptions after completion? - system.reactive

The Intro To RX book describes the return value on OnSubscribe as IDisposible and notes that subscriptions should be disposed of when OnError and OnCompleted are called.
An interesting thing to consider is that when a sequence completes or
errors, you should still dispose of your subscription.
From Intro to RX: Lifetime Management, OnError and OnCompleted
Why is this?
For reference, this is the class I'm currently working on. I'm probably going to submit it to code review at some point.
using System;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;
/// <summary>
/// Provides a timeout mechanism that will not timeout if it is signalled often enough
/// </summary>
internal class TrafficTimeout
{
private readonly Action onTimeout;
private object signalLock = new object();
private IObserver<Unit> signals;
/// <summary>
/// Initialises a new instance of the <see cref="TrafficTimeout"/> class.
/// </summary>
/// <param name="timeout">The duration to wait after receiving signals before timing out.</param>
/// <param name="onTimeout">The <see cref="Action"/> to perform when the the timeout duration expires.</param>
public TrafficTimeout(TimeSpan timeout, Action onTimeout)
{
// Subscribe to a throttled observable to trigger the expirey
var messageQueue = new BehaviorSubject<Unit>(Unit.Default);
IDisposable subscription = null;
subscription = messageQueue.Throttle(timeout).Subscribe(
p =>
{
messageQueue.OnCompleted();
messageQueue.Dispose();
});
this.signals = messageQueue.AsObserver();
this.onTimeout = onTimeout;
}
/// <summary>
/// Signals that traffic has been received.
/// </summary>
public void Signal()
{
lock (this.signalLock)
{
this.signals.OnNext(Unit.Default);
}
}
}

The disposable returned by the Subscribe extension methods is returned solely to allow you to manually unsubscribe from the observable before the observable naturally ends.
If the observable completes - with either OnCompleted or OnError - then the subscription is already disposed for you.
Try this code:
var xs = Observable.Create<int>(o =>
{
var d = Observable.Return(1).Subscribe(o);
return Disposable.Create(() =>
{
Console.WriteLine("Disposed!");
d.Dispose();
});
});
var subscription = xs.Subscribe(x => Console.WriteLine(x));
If you run the above you'll see that "Disposed!" is written to the console when the observable completes without you needing call .Dispose() on the subscription.
One important thing to note: the garbage collector never calls .Dispose() on observable subscriptions, so you must dispose of your subscriptions if they have not (or may not have) naturally ended before your subscription goes out of scope.
Take this, for example:
var wc = new WebClient();
var ds = Observable
.FromEventPattern<
DownloadStringCompletedEventHandler,
DownloadStringCompletedEventArgs>(
h => wc.DownloadStringCompleted += h,
h => wc.DownloadStringCompleted -= h);
var subscription =
ds.Subscribe(d =>
Console.WriteLine(d.EventArgs.Result));
The ds observable will only attach to the event handler when it has a subscription and will only detach when the observable completes or the subscription is disposed of. Since it is an event handler the observable will never complete because it is waiting for more events, and hence disposing is the only way to detach from the event (for the above example).
When you have a FromEventPattern observable that you know will only ever return one value then it is wise to add the .Take(1) extension method before subscribing to allow the event handler to automatically detach and then you don't need to manually dispose of the subscription.
Like so:
var ds = Observable
.FromEventPattern<
DownloadStringCompletedEventHandler,
DownloadStringCompletedEventArgs>(
h => wc.DownloadStringCompleted += h,
h => wc.DownloadStringCompleted -= h)
.Take(1);
I hope this helps.

Firstly, here's an example of the trouble you can run into:
void Main()
{
Console.WriteLine(GC.GetTotalMemory(true));
for (int i = 0; i < 1000; i++)
{
DumbSubscription();
Console.WriteLine(GC.GetTotalMemory(true));
}
Console.WriteLine(GC.GetTotalMemory(true));
}
public void DumbSubscription()
{
Observable.Interval(TimeSpan.FromMilliseconds(50))
.Subscribe(i => {});
}
You will see your memory usage go up forever. Active Rx subscriptions do not get garbage collected and this observable is infinite. Therefore, if you increase the loop limit, or add a delay, and you'll simply have more wasted memory: Nothing will help you except for disposing of those subscriptions.
However, let's say we change the definition of DumbSubscription to this:
public void DumbSubscription()
{
Observable.Interval(TimeSpan.FromMilliseconds(50))
.Take(1)
.Subscribe(i => {});
}
The .Take(1) addition means that the observable will complete after one interval, so it's no longer infinite. You'll see that your memory usage stabilizes: Subscriptions tend to properly dispose of themselves upon completion or exception.
However, that doesn't change the fact that, like any other IDisposable, it's a best practice to call Dispose (either manually or via using) to make sure resources are properly disposed of. Additionally, if you tweak your observable, you can easily run into the memory leak problem pointed out at the beginning.

Related

does garbage collector closes the streamController when reference is lost?

I am very confused about how actually the StreamController is implemented in dart.
So tell me if this code cause any memory leaks.
class Backend{
final streams = <int,StreamController>{};
final ws;
StreamHandler(this.ws){
listenToWebSocket();
}
listenToWebSocket(){
ws.listen((e){
streams[e['index']].add(e['data']);
});
}
getStream(int index){
var s = StreamController();
streams[index] = s;
return s.stream;
}
}
Backend listens to the websocket and passes its data to the stream appropriate index.
class StreamListenerHandler{
Map<int,StreamListener> listeners = {};
addListener(int index){
map[index] = listeners;
}
}
class StreamListener{
final int index;
StreamListener(this.index){
startListening();
}
startListening(){
getIt<Backend>().getStream().listen((data){
//do stuff
});
}
}
StreamListener wants the websocket data. StreamListenerHandler stores the listeners.
(for those who don't know getIt package just accesses the global singleton type thing.)
so what happens if...
void main(){
var handler = StreamListenerHandler();
handler.addListener(5);
// after some time...
handler.addListener(5);
}
here on the first call of addListener a StreamListener is created and it recieves a fresh stream from the Backend.
here is my expectation about the second call...
the StreamListenerHandler replaces the current StreamListener with a new one. Then the new StreamListener calls Backend and gets a fresh stream. The old streamController has no references so it's disposed. For the old StreamListener, the reference in the StreamListenerHandler is lost and also as the old streamController is gone the listen callback is also worthless, so it will be disposed.
So I am closing nothing just removing the references. Will this cause memory wastage?
does the garbage collector calls close on the controller or just disposing the object is enough?
(I am asking all this because all over the internet people are saying you should close the streams. I don't like the "should". I want to do it only if it "required")

How to create a multicast observable that activates on subscribe?

I want to fuse the inputs of several Android sensors and expose the output as an observable (or at least something that can be subscribed to) that supports multiple simultaneous observers. What's the idiomatic way to approach this? Is there a class in the standard library that would make a good starting point?
I was thinking of wrapping a PublishSubject in an object with delegates for one or more subscribe methods that test hasObservers to activate the sensors, and wrap the returned Disposable in a proxy that tests hasObservers to deactivate them. Something like this, although this already has some obvious problems:
public class SensorSubject<T> {
private final PublishSubject<T> mSubject = PublishSubject.create();
public Disposable subscribe(final Consumer<? super T> consumer) {
final Disposable d = mSubject.subscribe(consumer);
if(mSubject.hasObservers()) {
// activate sensors
}
return new Disposable() {
#Override
public void dispose() {
// possible race conditions!
if(!isDisposed()) {
d.dispose();
if(!mSubject.hasObservers()) {
// deactivate sensors
}
}
}
#Override
public boolean isDisposed() {
return d.isDisposed();
}
};
}
}
The idiomatic way to do that in RxJava would be to use hot observable.
Cold observables do some action when someone subscribes to them and emit all items to that subscriber. So it's 1 to 1 relation.
Hot observable do some action and emits items independently on individual subscription. So if you subscribe too late, you might not get some values that were emitted earlier. This is 1 to many relation, aka multicast - which is what you want.
Usual way to do it is Flowable.publish() which makes Flowable multicast, but requires calling connect() method to start emitting values.
In your case you can also call refCount() which adds your desired functionality - it subscribes to source Flowable when there is at least one subscription and unsubscribes when everyone unsubsribed.
Because publish().refCount() is pretty popular combination, there is a shortcut for them - share(). And as far as I understand this is exactly what you want.
Edit by asker: This code incorporates this answer and David Karnok's comment in the form of a Dagger 2 provider method. SimpleMatrix is from EJML. This seems to be doing what I asked for.
#Provides
#Singleton
#Named(MAGNETOMETER)
public Observable<SimpleMatrix> magnetometer(final SensorManager sensorManager) {
final PublishSubject<SimpleMatrix> ps = PublishSubject.create();
final Sensor sensor = sensorManager.getDefaultSensor(TYPE_MAGNETIC_FIELD);
final SensorEventListener listener = new SensorEventAdapter() {
#Override
public void onSensorChanged(final SensorEvent event) {
ps.onNext(new SimpleMatrix(1, 3, true, event.values));
}
};
return ps.doOnSubscribe(s -> {
sensorManager.registerListener(listener, sensor, SENSOR_DELAY_NORMAL);
}).doOnDispose(() -> {
sensorManager.unregisterListener(listener);
}).share();
}

How do I warm up an actor's state from database when starting up?

My requirement is to start a long running process to tag all the products that are expired. This is run every night at 1:00 AM. The customers may be accessing some of the products on the website, so they have instances around the time when the job is run. The others are in the persistent media, not yet having instances because the customers are not accessing them.
Where should I hook up the logic to read the latest state of an actor from a persistent media and create a brand new actor? Should I have that call in the Prestart override method? If so, how can I tell the ProductActor that a new actor being created.
Or should I send a message to the ProductActor like LoadMeFromAzureTable which will load the state from the persistent media after an actor being created?
There are different ways to do it depending on what you need, as opposed to there being precisely one "right" answer.
You could use a Persistent Actor to recover state from a durable store automatically on startup (or in case of crash, to recover). Or, if you don't want to use that module (still in beta as of July 2015), you could do it yourself one of two ways:
1) You could load your state in PreStart, but I'd only go with this if you can make the operation async via your database client and use the PipeTo pattern to send the results back to yourself incrementally. But if you need to have ALL the state resident in memory before you start doing work, then you need to...
2) Make a finite state machine using behavior switching. Start in a gated state, send yourself a message to load your data, and stash everything that comes in. Then switch to a receiving state and unstash all messages when your state is done loading. This is the approach I prefer.
Example (just mocking the DB load with a Task):
public class ProductActor : ReceiveActor, IWithUnboundedStash
{
public IStash Stash { get; set; }
public ProductActor()
{
// begin in gated state
BecomeLoading();
}
private void BecomeLoading()
{
Become(Loading);
LoadInitialState();
}
private void Loading()
{
Receive<DoneLoading>(done =>
{
BecomeReady();
});
// stash any messages that come in until we're done loading
ReceiveAny(o =>
{
Stash.Stash();
});
}
private void LoadInitialState()
{
// load your state here async & send back to self via PipeTo
Task.Run(() =>
{
// database loading task here
return new Object();
}).ContinueWith(tr =>
{
// do whatever (e.g. error handling)
return new DoneLoading();
}).PipeTo(Self);
}
private void BecomeReady()
{
Become(Ready);
// our state is ready! put all those stashed messages back in the mailbox
Stash.UnstashAll();
}
private void Ready()
{
// handle those unstashed + new messages...
ReceiveAny(o =>
{
// do whatever you need to do...
});
}
}
/// <summary>
/// Marker interface.
/// </summary>
public class DoneLoading {}

Subscribing to a future observable

I have na event-based API (Geolocator) that I want to convert to Rx.
The problem is that some operations require that all events are unsubscribed and I don't want to pass that burdon to the user of the Rx API.
So, the user will subscribe to a few observables and when the events are subscribed they are published to those observables.
What's the best way to do this?
I thought of creating a subject that the users subscribe to and then have the events published to those through another set of observables.
Is this the best way? If so, how?
The key problem is to find a way to keep an Observer subscribed to a stream whilst tearing down and replacing an underlying source. Let's just focus on a single event source - you should be able to extrapolate from that.
First of all, here is an example class we can use that has a single event SomeEvent that follows the standard .NET pattern using an EventHandler<StringEventArgs> delegate. We will use this to create sources of events.
Note I have intercepted the event add/remove handlers in order to show you when Rx subscribes and unsubscribes from the events, and given the class a name property to let us track different instances:
public class EventSource
{
private string _sourceName;
public EventSource(string sourceName)
{
_sourceName = sourceName;
}
private event EventHandler<MessageEventArgs> _someEvent;
public event EventHandler<MessageEventArgs> SomeEvent
{
add
{
_someEvent = (EventHandler<MessageEventArgs>)
Delegate.Combine(_someEvent, value);
Console.WriteLine("Subscribed to SomeEvent: " + _sourceName);
}
remove
{
_someEvent = (EventHandler<MessageEventArgs>)
Delegate.Remove(_someEvent, value);
Console.WriteLine("Unsubscribed to SomeEvent: " + _sourceName);
}
}
public void RaiseSomeEvent(string message)
{
var temp = _someEvent;
if(temp != null)
temp(this, new MessageEventArgs(message));
}
}
public class MessageEventArgs : EventArgs
{
public MessageEventArgs(string message)
{
Message = message;
}
public string Message { get; set; }
public override string ToString()
{
return Message;
}
}
Solution Key Idea - StreamSwitcher
Now, here is the heart of the solution. We will use a Subject<IObservable<T>> to create a stream of streams. We can use the Observable.Switch() operator to return only the most recent stream to Observers. Here's the implementation, and an example of usage will follow:
public class StreamSwitcher<T> : IObservable<T>
{
private Subject<IObservable<T>> _publisher;
private IObservable<T> _stream;
public StreamSwitcher()
{
_publisher = new Subject<IObservable<T>>();
_stream = _publisher.Switch();
}
public IDisposable Subscribe(IObserver<T> observer)
{
return _stream.Subscribe(observer);
}
public void Switch(IObservable<T> newStream)
{
_publisher.OnNext(newStream);
}
public void Suspend()
{
_publisher.OnNext(Observable.Never<T>());
}
public void Stop()
{
_publisher.OnNext(Observable.Empty<T>());
_publisher.OnCompleted();
}
}
Usage
With this class you can hook up a new stream on each occasion you want to start events flowing by using the Switch method - which just sends the new event stream to the Subject.
You can unhook events using the Suspend method, which sends an Observable.Never<T>() to the Subject effectively pausing the flow of events.
Finally you can stop altogether by called to Stop to push an Observable.Empty<T>() andOnComplete()` the subject.
The best part is that this technique will cause Rx to do the right thing and properly unsubscribe from the underlying event sources each time you Switch, Suspend or Stop. Note also, that once Stopped no more events will flow, even if you Switch again.
Here's an example program:
static void Main()
{
// create the switch to operate on
// an event type of EventHandler<MessageEventArgs>()
var switcher = new StreamSwitcher<EventPattern<MessageEventArgs>>();
// You can expose switcher using Observable.AsObservable() [see MSDN]
// to hide the implementation but here I just subscribe directly to
// the OnNext and OnCompleted events.
// This is how the end user gets their uninterrupted stream:
switcher.Subscribe(
Console.WriteLine,
() => Console.WriteLine("Done!"));
// Now I'll use the example event source to wire up the underlying
// event for the first time
var source = new EventSource("A");
var sourceObservable = Observable.FromEventPattern<MessageEventArgs>(
h => source.SomeEvent += h,
h => source.SomeEvent -= h);
// And we expose it to our observer with a call to Switch
Console.WriteLine("Subscribing");
switcher.Switch(sourceObservable);
// Raise some events
source.RaiseSomeEvent("1");
source.RaiseSomeEvent("2");
// When we call Suspend, the underlying event is unwired
switcher.Suspend();
Console.WriteLine("Unsubscribed");
// Just to prove it, this is not received by the observer
source.RaiseSomeEvent("3");
// Now pretend we want to start events again
// Just for kicks, we'll use an entirely new source of events
// ... but we don't have to, you could just call Switch(sourceObservable)
// with the previous instance.
source = new EventSource("B");
sourceObservable = Observable.FromEventPattern<MessageEventArgs>(
h => source.SomeEvent += h,
h => source.SomeEvent -= h);
// Switch to the new event stream
Console.WriteLine("Subscribing");
switcher.Switch(sourceObservable);
// Prove it works
source.RaiseSomeEvent("3");
source.RaiseSomeEvent("4");
// Finally unsubscribe
switcher.Stop();
}
This gives output like this:
Subscribing
Subscribed to SomeEvent: A
1
2
Unsubscribed to SomeEvent: A
Unsubscribed
Subscribing
Subscribed to SomeEvent: B
3
4
Unsubscribed to SomeEvent: B
Done!
Note it doesn't matter when the end user subscribes - I did it up front, but they can Subscribe any time and they'll start getting events at that point.
Hope that helps! Of course you'll need to pull together the various event types of the Geolocator API into a single convenient wrapper - but this should enable you to get there.
If you have several events you want to combine into a single stream using this technique, look at operators like Merge, which requires you to project the source streams into a common type, with Select maybe, or something like CombineLatest - this part of the problem shouldn't be too tricky.
This is what I came up with.
I have created two subjects for the clients of my API to subscribe:
private readonly Subject<Geoposition> positionSubject = new Subject<Geoposition>();
private readonly Subject<PositionStatus> statusSubject = new Subject<PositionStatus>();
And observables for the events my API is subscribing to:
private IDisposable positionObservable;
private IDisposable statusObservable;
When I want to subscribe to the events, I just subscribe them into the subjects:
this.positionObservable = Observable
.FromEvent<TypedEventHandler<Geolocator, PositionChangedEventArgs>, PositionChangedEventArgs>(
conversion: handler => (s, e) => handler(e),
addHandler: handler => this.geolocator.PositionChanged += handler,
removeHandler: handler => this.geolocator.PositionChanged -= handler)
.Select(e => e.Position)
.Subscribe(
onNext: this.positionSubject.OnNext,
onError: this.positionSubject.OnError);
this.statusObservable = Observable
.FromEvent<TypedEventHandler<Geolocator, StatusChangedEventArgs>, StatusChangedEventArgs>(
conversion: handler => (s, e) => handler(e),
addHandler: handler => this.geolocator.StatusChanged += handler,
removeHandler: handler => this.geolocator.StatusChanged -= handler)
.Select(e => e.Status)
.Subscribe(
onNext: this.statusSubject.OnNext,
onError: this.statusSubject.OnError);
When I want to cancel the subscription, I just dispose of the subscriptions:
this.positionObservable.Dispose();
this.statusObservable.Dispose();

How can I schedule a child activity to execute *before* the parent is completed?

I have a WF (4.5) workflow activity that creates a child workflow (evaluating a VisualBasicValue expression). I need the result before I complete the parent workflow.
I add the expression to the metadata like this:
private VisualBasicValue<string> _expression;
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
var visualBasicValue = (VisualBasicValue<string>)(_childActivity.Text.Expression);
var expressionText = visualBasicValue.ExpressionText;
_expression = new VisualBasicValue<string>(expressionText);
metadata.AddChild(_expression);
}
I tried scheduling the activity in the Execute method like this:
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(context, _expression, OnCompleted);
Result.Set(context, _value);
}
With a callback of:
private void OnCompleted(NativeActivityContext context, ActivityInstance completedInstance, string result)
{
_value = result;
}
Unfortunately, the _expression activity is only executed after the parent's execution method returns. Adding it as an implementation child doesn't work (it cannot work as an implementation child, as it is supposed to evaluate an expression that contains variables external to the parent).
Any ideas how to overcome this and execute within the execution context?
In code, as in real life, you can't schedule something to the past (yet :).
ScheduleActivity() will place the activity within an execution queue and execute it as soon as it can. As the parent activity is still running, _expression will only execute after it. Bottom-line, it's an asynchronous call.
If you want to control when _expression is called, just use WorkflowInvoker to execute it, synchronously, whenever you want.
public class MyNativeActivity : NativeActivity
{
private readonly VisualBasicValue<string> _expression;
public MyNativeActivity()
{
// 'expression' construction logic goes here
_expression = new VisualBasicValue<string>("\"Hi!\"");
}
protected override void Execute(NativeActivityContext context)
{
var _value = WorkflowInvoker.Invoke(_expression);
Console.WriteLine("Value returned by '_expression': " + _value);
// use '_value' for something else...
}
}
Took me a few days but I managed to resolve my own issue (without breaking the normal of how WF works).
What I ended up doing is, using reflection, iterated over the child's properties and created a LinkedList of evaluation expressions (using VisualBasicValue) of each of its arguments, in the CacheMetadata method. Then in the execution phase, I scheduled the execution of the first evaluation. In its callback I iterate over the remaining evaluations, scheduling the execution of the next evaluations, adding the result to a dictionary, until its done.
Finally, if there are no more evaluations to schedule, I schedule a final activity that takes the dictionary as its argument, and can do whatever it wants with it. Upon its own, it optionally returns the final result to the container's OutArgument.
What I previously failed to understand, is that even though the scheduling occurs after the instantiating activity's execution, the callback runs before control is returned to the host workflow application, and in that space I could work.