public static IObservable <T> SubscribeSafe <T>(this IObservable <T> observable, IReportStatus reporter, Action <T> onNext, Action <T, Exception> onError = null, Action <T> onDisposing = null) { IDisposable sub = null; T obj = default(T); return(Observable.Create <T>(o => { return observable.Merge(o as IObservable <T>).Subscribe(msg => { obj = msg; try { onNext(msg); } catch (Exception e) { o.OnError(e); } }, error => { reporter.OnError(error); o.OnCompleted(); if (onError != null) { onError(obj, error); } }, onCompleted: () => { try { o.OnCompleted(); if (sub != null) { sub.Dispose(); if (obj != null && onDisposing != null) { onDisposing.Invoke(obj); } } } catch (Exception e) { reporter.OnError(e); } }); })); }
/// <summary> /// Subscribes to a Channel and redirect any error messages received to the IReportStatus interface /// to stop the Channel from terminating when something abnormal occours. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="observable">The sequence to observe</param> /// <param name="reporter">The reporter to handle the error messages</param> /// <param name="onNext">The function that occours when a new message arrives</param> /// <param name="onError">The function to execute when an error occours, in addition to the automatic OnError log message produced</param> /// <returns>A safely configured observable listener</returns> public static IDisposable Subscribe <T>(this IObservable <T> observable, IReportStatus reporter, Action <T> onNext, Action <T, Exception> onError = null, Action <T> onDisposing = null) { IDisposable sub = null; T obj = default(T); sub = observable.Subscribe(msg => { obj = msg; try { onNext(msg); } catch (Exception e) { reporter.OnError(e); } }, error => { reporter.OnError(error); if (onError != null) { onError(obj, error); } }, onCompleted: () => { try { if (sub != null) { sub.Dispose(); } if (onDisposing != null) { onDisposing.Invoke(obj); } } catch (Exception e) { reporter.OnError(e); } }); return(sub); }
private void StartrxnProcessors(IReportStatus logger, IContainer container, Type[] events, IScheduler eventDelivery) { var startedProcessors = new List <dynamic>(); foreach (var @event in events) { try { //now we create an rxnProcessor of each IRxn discovered, then ask the container //for any interfaces which implement them. var processorForEvent = typeof(IRxnProcessor <>).MakeGenericType(@event); var allProcessorsForEventType = typeof(IEnumerable <>).MakeGenericType(processorForEvent); var allProcessors = ((IEnumerable <dynamic>)container.Resolve(allProcessorsForEventType)).ToArray(); Func <string, Rxns.Interfaces.IReactor <IRxn> > getReactorByName = reactorName => container.Resolve <IManageReactors>().StartReactor(reactorName).Reactor; //now register any processors found with the subscription to the events they are interested in var distinctProcessors = allProcessors.Distinct().ToArray(); foreach (var p in distinctProcessors.Except(startedProcessors)) { var reactor = RxnCreator.GetReactorFor((object)p, getReactorByName); //this method will hookup ALL process methods of a processor in one call reactor.Connect((object)p, eventDelivery); } startedProcessors.AddRange(distinctProcessors); //so we need to keep a list processors we see so we dont attach them twice } catch (Exception e) { logger.OnError(e); } } }
private void StartReactions(IReportStatus logger, IContainer container, Type[] events, IScheduler eventDelivery) { foreach (var @event in events) { try { var processorForEvent = typeof(IReactTo <>).MakeGenericType(@event); var allProcessorsForEventType = typeof(IEnumerable <>).MakeGenericType(processorForEvent); var allProcessors = (IEnumerable <dynamic>)container.Resolve(allProcessorsForEventType); Func <string, Rxns.Interfaces.IReactor <IRxn> > getReactorByName = reactorName => container.Resolve <IManageReactors>().StartReactor(reactorName).Reactor; //now attach any processors found with the subscription to the events they are interested in foreach (object reaction in allProcessors.Distinct()) { var reactor = RxnCreator.GetReactorFor(reaction, getReactorByName); reactor.Connect((IReactTo <IRxn>)reaction, eventDelivery); } } catch (Exception e) { logger.OnError(e); } } }
/// <summary> /// Reports any exceptions that occour through your reporter /// </summary> /// <param name="reporter">The person who will catch the exception</param> /// <param name="work">The work todo</param> public static void TryCatch(this IReportStatus reporter, Action work) { try { work.Invoke(); } catch (Exception e) { reporter.OnError(e); } }
/// <summary> /// Same are trycatch /// Reports any exceptions that occour through your reporter /// </summary> /// <param name="reporter">The person who will catch the exception</param> /// <param name="work">The work todo</param> public static T ReportExceptions <T>(this IReportStatus reporter, Func <T> work) { try { return(work.Invoke()); } catch (Exception e) { reporter.OnError(e); return(default(T)); } }
/// <summary> /// Same are trycatch /// Reports any exceptions that occour through your reporter /// </summary> /// <param name="reporter">The person who will catch the exception</param> /// <param name="work">The work todo</param> public static dynamic ReportExceptions(this IReportStatus reporter, Func <dynamic> work) { try { return(work.Invoke()); } catch (Exception e) { reporter.OnError(e); return(null); } }
/// <summary> /// Reports any exceptions that occour through your reporter /// </summary> /// <param name="reporter">The person who will catch the exception</param> /// <param name="work">The work todo</param> /// <param name="onException">A handler that will be called when an exception occours, after it is logged by the reporter</param> public static void ReportExceptions(this IReportStatus reporter, Action work, Action <Exception> onException = null) { try { work.Invoke(); } catch (Exception e) { reporter.OnError(e); if (onException != null) { onException.Invoke(e); } } }
/// <summary> /// Same are trycatch /// Reports any exceptions that occour through your reporter /// </summary> /// <param name="reporter">The person who will catch the exception</param> /// <param name="work">The work todo</param> /// <param name="onException">A handler that will be called when an exception occours, after it is logged by the reporter</param> public static T ReportExceptions <T>(this IReportStatus reporter, Func <T> work, Action <Exception> onException = null) { try { return(work.Invoke()); } catch (Exception e) { reporter.OnError(e); if (onException != null) { onException.Invoke(e); } return(default(T)); } }
/// <summary> /// Same are trycatch /// Reports any exceptions that occour through your reporter /// </summary> /// <param name="reporter">The person who will catch the exception</param> /// <param name="work">The work todo</param> /// <param name="onException">A handler that will be called when an exception occours, after it is logged by the reporter</param> public static dynamic ReportExceptions(this IReportStatus reporter, Func <dynamic> work, Action <Exception> onException = null) { try { return(work.Invoke()); } catch (Exception e) { reporter.OnError(e); if (onException != null) { onException.Invoke(e); } return(null); } }
public void Run(IReportStatus logger, IContainer container) { foreach (var service in container.Resolve <IEnumerable <IRxnService> >()) { try { logger.OnInformation("Starting service: {0}", service.GetType()); service.Start() .Timeout(TimeSpan.FromMinutes(5)) .Catch <CommandResult, TimeoutException>(_ => { throw new Exception("Timed out while starting {0}".FormatWith(service.GetType().Name)); }) .Until(logger.OnError); } catch (Exception e) { logger.OnError("Service: {0} failed to startup: {1}", service.GetType(), e); } } }