Pattern for 'routing' events through several subscribers? - c#

I have a group of classes with the following interface:
public interface RoutedEventReceiver<T>
{
IDisposable Apply(IObservable<T> stream);
bool ShouldForwardEvent(T anEvent);
}
What I would like to do is to maintain a stack of these classes, with each event being filtered through the ShouldForwardEvent(T) predicate, and the resulting IObservable<T> passed to the next receiver. I also want to be able to push and pop new receivers while my program is running (at some point I may want to move from a stack to some other collection but for now a stack is sufficient).
What I have currently does work, but I don't feel like it is very "Rx". I am sure there must be a way to do what I want without all this imperative logic:
private void Refresh()
{
// _subscriptions is a list of previous subscriptions
foreach (var subscription in _subscriptions)
subscription.Dispose();
_subscriptions.Clear();
// _stream is my stream of incoming events
if (_stream != null)
{
var stream = _stream;
foreach (var eventReceiver in _eventReceivers)
{
// add the subscription so it can be disposed next Refresh()
_subscriptions.Add(eventReceiver.Apply(stream));
// filter the stream for the next event receiver
stream = stream.Where(eventReceiver.ShouldForwardEvent);
}
}
}
The above method is called whenever I Push or Pop on the stack.
Is there a cleaner, more functional way to express the above intent? I have tried .Publish() but with little success - perhaps I don't know it well enough.

I have managed to make the Publish approach work, but it doesn't afford me much other than getting rid of the need to keep a list of IDisposables:
private void Refresh()
{
_published.DisposeIfNotNull();
if (_stream != null)
{
var connectable = _stream.Publish();
_published = connectable.Connect();
var stream = connectable.AsObservable();
foreach (var eventReceiver in _eventReceivers)
{
eventReceiver.Apply(stream);
stream = stream.Where(eventReceiver.ShouldForwardEvent);
}
}
}

The class below (named CORStack for Chain Of Responsibility* Stack), tries to do what you're after. Internally it adds an ShouldHandle bool to the stream and uses this to determine whether to process. It exposes the standard Push, Pop, and Peek methods.
public sealed class CORStack<T>
{
Stack<StackFrame> _handlers;
public CORStack(IObservable<T> source)
{
_handlers = new Stack<StackFrame>();
_handlers.Push(new StackFrame(
source.Select(t => new ShouldHandleWrapper(t, true)),
new Handler<T>(new Action<T>(t => { }), true)));
}
public void Push(Handler<T> handler)
{
_handlers.Push(new StackFrame(_handlers.Peek().Observable, handler));
}
public Handler<T> Peek()
{
return _handlers.Peek().Handler;
}
public Handler<T> Pop()
{
var frame = _handlers.Pop();
frame.Dispose();
return frame.Handler;
}
class StackFrame : IDisposable
{
IDisposable _unsub;
public IObservable<ShouldHandleWrapper> Observable { get; private set; }
public Handler<T> Handler { get; private set; }
public StackFrame(IObservable<ShouldHandleWrapper> topOfStack, Handler<T> handler)
{
_unsub = topOfStack.Subscribe(shouldHandle =>
{
if (shouldHandle.ShouldHandle)
handler.Action.Invoke(shouldHandle.Value);
});
Observable = topOfStack.Select(shouldHandle =>
new ShouldHandleWrapper(shouldHandle.Value, shouldHandle.ShouldHandle && handler.Forward));
Handler = handler;
}
public void Dispose()
{
_unsub.Dispose();
}
}
class ShouldHandleWrapper
{
public readonly T Value;
public readonly bool ShouldHandle;
public ShouldHandleWrapper(T value, bool shouldHandle)
{
Value = value;
ShouldHandle = shouldHandle;
}
}
}
public class Handler<T>
{
public Action<T> Action { get; set; }
public bool Forward { get; set; }
public Handler(Action<T> action, bool forward)
{
Action = action;
Forward = forward;
}
}
*I realised that it's not a chain of responsibility, but can't think of a better name atm.

This is a case where I'd actually use Subjects. Create a subject for each handler, then subscribe to the stream and loop through the handlers passing the event as required. This avoids continually unsubscribing/resubscribing to the stream (and thus the Refresh method), which is not always appropriate. We use lock to guard against a new receiver being added or removed at the same moment as a new value is coming through the stream. If you can guarantee that cannot happen, then you can remove the lock statements.
public class YourClass<T> : IDisposable
{
private readonly Stack<Tuple<Subject<T>, RoutedEventReceiver<T>, IDisposable> _handlers;
private readonly IObservable<T> _stream;
private readonly IDisposable _streamSubscription;
public YourClass(IObservable<T> stream)
{
_handlers = new Stack<Tuple<Subject<T>, RoutedEventReceiver<T>, IDisposable>();
_stream = stream;
_streamSubscription = stream.Subscribe(OnNext, OnError, OnCompleted);
}
public void Dispose()
{
_streamSubscription.Dispose();
lock (_handlers)
{
foreach (var h in _handlers)
{
h.Item3.Dispose();
h.Item1.Dispose();
}
_handlers.Clear();
}
}
private void OnNext(T value)
{
lock (_handlers)
{
for (var h in _handlers)
{
h.Item1.OnNext(value);
if (!h.Item2.ShouldForwardEvent(value)) break;
}
}
}
private void OnError(Exception e)
{
lock (_handlers)
{
for (var h in _handlers) { h.Item1.OnError(e); }
}
}
private void OnCompleted()
{
lock (_handlers)
{
for (var h in _handlers) { h.Item1.OnCompleted(); }
}
}
public void Push(RoutedEventReceiver<T> handler)
{
lock (_handlers)
{
var subject = new Subject<T>;
_handlers.Push(Tuple.Create(subject, handler, handler.Apply(subject)));
}
}
public RoutedEventReceiver<T> Pop()
{
lock (_handlers)
{
var handler = _handlers.Pop();
handler.Item3.Dispose();
handler.Item1.Dispose();
return handler.Item2;
}
}
}

Related

Implement extensibility on callback?

Currently, I am working on an API, and developers can subscribe to it to know the updates.
So right now I am implementing an interface IResult , so that I can send different parameters in the callback result. The problem right now is if in the future, I want to add a new callback, I have to add an argument in the method, and developers also need to change their method call. Is there a good solution for this?
public interface IResult
{
int i { get; set; }
}
public class ConcreteResult : IResult
{
public int i
{
get;set;
}
}
public class MyAPI
{
public delegate void MyAPIDelegate(IResult result);
public void StartService(MyAPIDelegate callback, MyAPIDelegate callback2)
{
//step 1
int i = 0;
ConcreteResult result1 = new ConcreteResult();
result1.i = i;
callback(result1);
//step 2
i += 1;
ConcreteResult result2 = new ConcreteResult();
result2.i = i;
callback2(result2);
//potentially added in the future
//i += 1;
//callback3();
}
public void main()
{
//developers use my API
StartService(developerCallback, developerCallback2);
}
private void developerCallback(IResult result)
{
Console.WriteLine(result.i);
}
private void developerCallback2(IResult result)
{
Console.WriteLine(result.i);
}
}
Oddly everyone is recommending events, but nobody is showing an example. I'll bite.
Judging by the naming conventions I'm guessing you come from Java land. (C# methods are generally PascalCase). C# has events, which make things like this much simpler. I recommend you study them up, as they're quite common in C# code.
All you have to do is define a public event on your class, and have that class invoke the event where necessary. (do ?. because an unsubscribed event is weirdly null).
Then from the consuming class, you subscribe handlers for it using +=.
This allows you to add new events in the future without your consumers having to worry about it.
public class MyAPI
{
public event Action<IResult> Callback1;
public event Action<IResult> Callback2;
public void StartService()
{
//step 1
int i = 0;
ConcreteResult result1 = new ConcreteResult();
result1.i = i;
Callback1?.Invoke(result1);
//step 2
i += 1;
ConcreteResult result2 = new ConcreteResult();
result2.i = i;
Callback2?.Invoke(result2);
//potentially added in the future
//i += 1;
//callback3();
}
}
public static class Program {
public static void Main()
{
//developers use my API
var api = new MyAPI();
api.Callback1 += DeveloperCallback;
api.Callback2 += DeveloperCallback2;
api.StartService();
}
private static void DeveloperCallback(IResult result)
{
Console.WriteLine(result.i);
}
private static void DeveloperCallback2(IResult result)
{
Console.WriteLine(result.i);
}
}
Also for simple event handlers, you can subscribe inline:
api.Callback1 += result =>
{
Console.WriteLine(result.i);
};
Or even simpler for one-liners:
api.Callback1 += result => Console.WriteLine(result.i);
Since you asked, another option a bit more heavier than simple events, but eventually more powerful is Reactive Extensions. If you want to use these, then you can write code like this:
using System.Reactive.Subjects;
public class MyAPI
{
private readonly Subject<IResult> callback1 = new Subject<IResult>();
private readonly Subject<IResult> callback2 = new Subject<IResult>();
public void StartService()
{
//step 1
int i = 0;
ConcreteResult result1 = new ConcreteResult();
result1.i = i;
callback1.OnNext(result1);
//step 2
i += 1;
ConcreteResult result2 = new ConcreteResult();
result2.i = i;
callback2.OnNext(result2);
}
public IObservable<IResult> Callback1 => this.callback1;
public IObservable<IResult> Callback2 => this.callback2;
}
public static class Program
{
public static void Main()
{
var api = new MyAPI();
// Subscribing returns a disposable subscription, and disposing it unsubscribes.
// That means you can use lambda syntax and still unsubscribe later
IDisposable subscription =
api.Callback1.Subscribe(result => Console.WriteLine(result.i));
api.StartService(); // Writes result.
// Once disposed, event is no longer called
subscription.Dispose();
api.StartService(); // Doesn't write result.
// Since IDisposable is a special thing that can be scoped to using blocks in C#, you can do the following:
using (api.Callback1.Subscribe(result => Console.WriteLine(result.i)))
{
api.StartService(); // Writes result
}
api.StartService(); // Doesn't write result
}
}
I strongly recommend using events, like #Vikhram suggested, but here is your example, modified to use a class as you requested.
Notice that I did not specify a Callback3 when calling the function. The API uses .? when calling them, instead of just ., so that it doesn't cause a NullReferenceException if the developer doesn't pass one in.
When you add more callbacks, just add additional properties to MyCallbackInfo, and invoke them the same as the existing ones.
public interface IResult {... }
public class ConcreteResult : IResult {...}
public class MyStartServiceCallbackInfo
{
public MyAPI.MyAPIDelegate Callback1 { get; set; }
public MyAPI.MyAPIDelegate Callback2 { get; set; }
public MyAPI.MyAPIDelegate Callback3 { get; set; }
}
public class MyAPI
{
public delegate void MyAPIDelegate(IResult result);
public void StartService(MyStartServiceCallbackInfo callbacks)
{
...
callbacks?.Callback1(result1);
...
callbacks?.Callback2(result2);
...
callbacks?.Callback3(result3);
}
public void main()
{
StartService(new MyCallbackInfo()
{
Callback1 = developerCallback,
Callback2 = developerCallback2,
});
}
private void developerCallback(IResult result)
{
Console.WriteLine(result.i);
}
private void developerCallback2(IResult result)
{
Console.WriteLine(result.i);
}
}

Making asynchronous API synchronous

I am connecting to an API to get some data that is defined like this:
A client object ClientConnection, which allows one to send requests.
A IApi interface that needs to be passed to the ClientConnection to receive callbacks.
Schematically it looks like this:
// defined in the API dll
public class ClientConnection {
public ClientConnection(IApi api) { ... }
public void request(int reqid, string reqdetails) { ... }
}
interface IApi
{
void receiveData(int reqid, string ans);
}
Now, obviously this is a fairly standard asynchronous way of doing things: send requests through a global object, with a requestid, and receive answers tagged with that requestid.
I want to create a wrapper that is synchronous. What would be the most natural way of doing this? Is there a smart way of using async await, instead of using thread locking and stuff?
class MyWrapper : IApi
{
private ClientConnection _client;
private int _reqToken = 0;
public MyWrapper()
{
_client = new ClientConnection(this);
}
public string getData(string reqdetails)
{
_client.request(_reqToken++, reqdetails);
// what to do here?
}
public void receiveData(int reqid, string data) {
// what to do here?
}
}
Didn't test the code below, but it should give you the idea. Basically you can use ManualResetEvent to be signalled when you receive your result (and don't ever call this without proper timeout):
class MyWrapper : IApi {
private ClientConnection _client;
// here you store your requests
private Dictionary<int, PendingRequest> _pendingRequests = new Dictionary<int, PendingRequest>();
private int _reqToken = 0;
public MyWrapper() {
_client = new ClientConnection(this);
}
public string getData(string reqdetails, TimeSpan timout) {
// if this is multithreaded - lock over _pendingRequests when you add\remove requests there
// and when you increment your _reqToken, or use concurrent collection
using (var token = new PendingRequest()) {
var id = _reqToken;
// lock here
_pendingRequests.Add(id, token);
_client.request(id, reqdetails);
// and here use Interlocked.Increment
_reqToken++;
if (!token.Signal.WaitOne(timout)) {
// and here
_pendingRequests.Remove(id);
// timeout
throw new Exception("timout");
}
// if we are here - we have the result
return token.Result;
}
}
public void receiveData(int reqid, string data) {
// here you might need to lock too
if (_pendingRequests.ContainsKey(reqid)) {
var token = _pendingRequests[reqid];
_pendingRequests.Remove(reqid);
token.Complete(data);
}
}
private class PendingRequest : IDisposable {
public PendingRequest() {
Signal = new ManualResetEvent(false);
}
public ManualResetEvent Signal { get; private set; }
public string Result { get; private set; }
public void Complete(string result) {
this.Result = result;
Signal.Set();
}
public void Dispose() {
Signal.Dispose();
}
}
}

ServiceStack.Redis.RedisClient UnSubscribe function hangs

I tried to use RedisPubSubServer but that won't work with key notifications because I need to subscribe channels specified by patterns. So I created my own solution:
public class RedisKeySubscriber
{
public string Host { get; private set; }
public int Port { get; private set; }
private readonly Dictionary<string, IRedisSubscription> _subscriptions;
public RedisKeySubscriber(string host, int port)
{
Host = host;
Port = port;
_subscriptions = new Dictionary<string, IRedisSubscription>();
}
public void Subscribe(string key, Action<string, string> handler)
{
lock (_subscriptions)
{
IRedisSubscription subscription;
if (_subscriptions.TryGetValue(key, out subscription))
return;
// FIXME this might potentially create too many threads
var client = new ServiceStack.Redis.RedisClient(Host, Port);
subscription = client.CreateSubscription();
subscription.OnMessage = handler;
_subscriptions.Add(key, subscription);
new Thread(() => subscription.SubscribeToChannelsMatching(key)).Start();
}
}
public void Unsubscribe(string key)
{
lock (_subscriptions)
{
IRedisSubscription subscription;
if (!_subscriptions.TryGetValue(key, out subscription))
return;
subscription.UnSubscribeFromChannelsMatching(key);
_subscriptions.Remove(key);
}
}
public void UnsubscribeAll()
{
lock (_subscriptions)
{
foreach (var subscription in _subscriptions)
subscription.Value.UnSubscribeFromChannelsMatching(subscription.Key);
_subscriptions.Clear();
}
}
public void Dispose()
{
UnsubscribeAll();
}
}
I realized this hangs on PSUBSCRIBE command. Everything else works just fine. Any idea?
I solved this using an additional 'control' channel. So the handler is subscribed both to the channels matching 'key' and to a channel like 'CHCTRL:guid' where guid is a specific GUID created by the class instance. The unsubscribe function publish a message on CHCTRL:guid and the handler can understand it's time to unsubscribe itself because the message doesn't come from 'key'.
Alternative and suggested solution is to not use ServiceStack.Redis.

Multithreading BlockingCollection Alternatives to GetConsumingEnumerable() Producer-Consumer

I have a situation where I have multiple producers and multiple consumers. The producers enters a job into a queue. I chose the BlockingCollection and it works great since I need the consumers to wait for a job to be found. However, if I use the GetConsumingEnumerable() feature the order of the items in the collection change... this is not what I need.
It even says in MSDN http://msdn.microsoft.com/en-us/library/dd287186.aspx
that it does not preserve the order of the items.
Does anyone know an alternative for this situation?
I see that the Take method is available but does it also provide a 'wait' condition for the consumer threads?
It says http://msdn.microsoft.com/en-us/library/dd287085.aspx
'A call to Take may block until an item is available to be removed.' Is it better to use TryTake? I really need the thread to wait and keep checking for a job.
Take blocks the thread till something comes available.
TryTake as the name implies tries to do so but returns a bool if it fails or succeeds.
Allowing for more flex using it:
while(goingOn){
if( q.TryTake(out var){
Process(var)
}
else{
DoSomething_Usefull_OrNotUseFull_OrEvenSleep();
}
}
instead of
while(goingOn){
if( var x = q.Take(){
//w'll wait till this ever will happen and then we:
Process(var)
}
}
My votes are for TryTake :-)
EXAMPLE:
public class ProducerConsumer<T> {
public struct Message {
public T Data;
}
private readonly ThreadRunner _producer;
private readonly ThreadRunner _consumer;
public ProducerConsumer(Func<T> produce, Action<T> consume) {
var q = new BlockingCollection<Message>();
_producer = new Producer(produce,q);
_consumer = new Consumer(consume,q);
}
public void Start() {
_producer.Run();
_consumer.Run();
}
public void Stop() {
_producer.Stop();
_consumer.Stop();
}
private class Producer : ThreadRunner {
public Producer(Func<T> produce, BlockingCollection<Message> q) : base(q) {
_produce = produce;
}
private readonly Func<T> _produce;
public override void Worker() {
try {
while (KeepRunning) {
var item = _produce();
MessageQ.TryAdd(new Message{Data = item});
}
}
catch (ThreadInterruptedException) {
WasInterrupted = true;
}
}
}
public abstract class ThreadRunner {
protected readonly BlockingCollection<Message> MessageQ;
protected ThreadRunner(BlockingCollection<Message> q) {
MessageQ = q;
}
protected Thread Runner;
protected bool KeepRunning = true;
public bool WasInterrupted;
public abstract void Worker();
public void Run() {
Runner = new Thread(Worker);
Runner.Start();
}
public void Stop() {
KeepRunning = false;
Runner.Interrupt();
Runner.Join();
}
}
class Consumer : ThreadRunner {
private readonly Action<T> _consume;
public Consumer(Action<T> consume,BlockingCollection<Message> q) : base(q) {
_consume = consume;
}
public override void Worker() {
try {
while (KeepRunning) {
Message message;
if (MessageQ.TryTake(out message, TimeSpan.FromMilliseconds(100))) {
_consume(message.Data);
}
else {
//There's nothing in the Q so I have some spare time...
//Excellent moment to update my statisics or update some history to logfiles
//for now we sleep:
Thread.Sleep(TimeSpan.FromMilliseconds(100));
}
}
}
catch (ThreadInterruptedException) {
WasInterrupted = true;
}
}
}
}
}
USAGE:
[Fact]
public void ConsumerShouldConsume() {
var produced = 0;
var consumed = 0;
Func<int> produce = () => {
Thread.Sleep(TimeSpan.FromMilliseconds(100));
produced++;
return new Random(2).Next(1000);
};
Action<int> consume = c => { consumed++; };
var t = new ProducerConsumer<int>(produce, consume);
t.Start();
Thread.Sleep(TimeSpan.FromSeconds(5));
t.Stop();
Assert.InRange(produced,40,60);
Assert.InRange(consumed, 40, 60);
}

Rx Extensions: How do I make a subscription dependent on another subscription?

I have a class that takes an observable in its constructor, then subscribes to it and does some stuff, sets properties etc. The class itself is observable.
I want to subscribe to my source observable only if someone is subscribed to my class, but I can't figure out how to do it.
public MyClass : IObservable<MyResult>
{
private readonly Subject<MyResult> _subject = new Subject<MyResult>();
private readonly IConnectableObservable<MySource> _source;
public MyClass(IObservable<MySource> source)
{
_source = source
//All my logic to set properties and such
//goes here as a side effect, instead of in a subscription...
.Do(...)
//I hope that by publishing, side effects will happen only once...
.Publish();
}
public IDisposable Subscribe(IObserver<MyResult> observer)
{
return new CompositeDisposable(
_source.Subscribe(/*
don't have anything to do here,
just subscribing to make sure I'm subscribed to source...
(this can't be the right way to do it)
*/),
_subject.Subscribe(observer));
}
}
UPDATE
#Scott: I can see why implementing IObservable would be an anti-pattern. My Class needs to consume a single observable, and exposes 3 as properties (originally the most commonly used observable was going to be returned by MyClass itself, but I think that having it as a property might be better.
What I'm trying to write is an observable ICommand. I know some exist, but this is more of a way to learn Rx...
public class ObservableCommand<T> : ICommand
{
private readonly ISubject<T> _executeRequests = new Subject<T>();
private readonly ISubject<T> _canExecuteRequests = new Subject<T>();
public IObservable<bool> CanExecuteChanges { get; private set; }
public IObservable<T> CanExecuteRequests { get; private set; }
public IObservable<T> ExecuteRequests { get; private set; }
public ObservableCommand(IObservable<bool> canExecute)
{
var source = canExecute.DistinctUntilChanged()
//How do I dispose of subscription later?
//I have this fear that I'm going to have a chain of references,
//and my entire app will never get GC'd!
var subscription = source.Subscribe(
o => {
if (CanExecuteChanged != null)
CanExecuteChanged(this, EventArgs.Empty);
});
CanExecuteChanges = source;
CanExecuteRequests = _canExecuteRequests.AsObservable();
ExecuteRequests = _executeRequests.AsObservable();
}
#region ICommand Members
public bool CanExecute(object parameter)
{
_canExecuteRequests.OnNext(parameter is T ? (T)parameter : default(T));
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_executeRequests.OnNext(parameter is T ? (T)parameter : default(T));
}
#endregion
}
How about just not Doing or Publishing in the constructor, but rather in the Subscribe method?
It should be said, explicitly implementing IObservable<T> is something of an Rx anti-pattern.
You can make Subscriptions dependent on other subscribers with Defer and Create, something like
IObservable<MySource> source;
IObservable<MySource> sourceWithSubSideEffect = Observable.Defer(() =>
{
// Do something interesting on Subscription
// ....
return source;
});
I've prepared a snipped for you. MyClass implements IObservable<T> and has also methods of IObserver<T> but they are all private. With additional OnInitialize and OnSubscribe you should be able to do whatever you want on any event you want to response to.
If you want to make this snipped reusable you could define all methods as partial as they all return void. Then you could create definition to whatever you want.
public class MyClass<T> : IObservable<T>
{
private readonly IObservable<T> m_Source;
public MyClass(IObservable<T> source)
{
if (source == null) throw new ArgumentNullException("source");
m_Source = source.Do(OnNext, OnError, OnCompleted);
OnInitialize();
}
public IDisposable Subscribe(IObserver<T> observer)
{
OnSubscribe();
return m_Source.Subscribe(observer);
}
private void OnInitialize()
{
Console.WriteLine("OnInitialize");
}
private void OnSubscribe()
{
Console.WriteLine("OnSubscribe");
}
private void OnNext(T value)
{
Console.WriteLine("OnNext: {0}", value);
}
private void OnError(Exception error)
{
Console.WriteLine("OnError: {0}", error.Message);
}
private void OnCompleted()
{
Console.WriteLine("OnCompleted");
}
}

Categories