/// <summary> /// Initializes a new instance of the <see cref="ExtensionState{TSender}"/> class. /// </summary> /// <param name="sender">The sender.</param> public ExtensionState(TSender sender) { _sender = sender; _changingSubject = new Subject <IReactivePropertyChangedEventArgs <TSender> >(); _changedSubject = new Subject <IReactivePropertyChangedEventArgs <TSender> >(); _startDelayNotifications = new Subject <Unit>(); _thrownExceptions = new ScheduledSubject <Exception>(Scheduler.Immediate, RxApp.DefaultExceptionHandler); _changedObservable = _changedSubject .Buffer( Observable.Merge( _changedSubject.Where(_ => !AreChangeNotificationsDelayed()).Select(_ => Unit.Default), _startDelayNotifications)) .SelectMany(Dedup) .Publish() .RefCount(); _changingObservable = _changingSubject .Buffer( Observable.Merge( _changingSubject.Where(_ => !AreChangeNotificationsDelayed()).Select(_ => Unit.Default), _startDelayNotifications)) .SelectMany(Dedup) .Publish() .RefCount(); }
/// <summary> /// Initializes a new instance of the <see cref="ExtensionState{TSender}"/> class. /// </summary> public ExtensionState(TSender sender) { this.sender = sender; this.changingSubject = new Subject <IReactivePropertyChangedEventArgs <TSender> >(); this.changedSubject = new Subject <IReactivePropertyChangedEventArgs <TSender> >(); this.startDelayNotifications = new Subject <Unit>(); this.thrownExceptions = new ScheduledSubject <Exception>(Scheduler.Immediate, ExceptionHandler.Default); this.changedObservable = changedSubject .Buffer( Observable.Merge( changedSubject.Where(_ => !areChangeNotificationsDelayed()).Select(_ => Unit.Default), startDelayNotifications) ) .SelectMany(batch => dedup(batch)) .Publish() .RefCount(); this.changingObservable = changingSubject .Buffer( Observable.Merge( changingSubject.Where(_ => !areChangeNotificationsDelayed()).Select(_ => Unit.Default), startDelayNotifications) ) .SelectMany(batch => dedup(batch)) .Publish() .RefCount(); }
public BufferedLineProtocolClient(LineProtocolClient lineProtocolClient, int maximumMeasurementPoints, TimeSpan maximumElapsedTime) { _lineProtocolClient = lineProtocolClient; Subject <LineProtocolPoint> subject = new Subject <LineProtocolPoint>(); _syncedSubject = Subject.Synchronize(subject); _subscription = _syncedSubject .Buffer(maximumElapsedTime, maximumMeasurementPoints) .Subscribe(onNext: async(pointsList) => await WriteToInflux(pointsList)); }
public async Task RunSimulationAsync(string scenario, CancellationToken token) { //TODO: we need to find a friendlier way to show this. if (!_devices.Any()) { throw new InvalidOperationException("No devices found. Please execute device provisioning first."); } ScenarioSimulatorEventSource.Log.SimulationStarted(_hostName, scenario); var produceEventsForScenario = SimulationScenarios.GetScenarioByName(scenario); var simulationTasks = new List <Task>(); var warmup = _simulatorConfiguration.WarmupDuration; var warmupPerDevice = warmup.Ticks; _observableTotalCount .Sum() .Subscribe(total => ScenarioSimulatorEventSource.Log.FinalEventCountForAllDevices(total)); _observableTotalCount .Buffer(TimeSpan.FromMinutes(5)) .Scan(0, (total, next) => total + next.Sum()) .Subscribe(total => ScenarioSimulatorEventSource.Log.CurrentEventCountForAllDevices(total)); foreach (var device in _devices) { var eventSender = new EventSender( device: device, config: _simulatorConfiguration, serializer: Serializer.ToJsonUTF8 ); var deviceTask = SimulateDeviceAsync( device: device, produceEventsForScenario: produceEventsForScenario, sendEventsAsync: eventSender.SendAsync, waitBeforeStarting: TimeSpan.FromTicks(warmupPerDevice * device.StartupOrder), totalCount: _observableTotalCount, token: token ); simulationTasks.Add(deviceTask); } await Task.WhenAll(simulationTasks.ToArray()).ConfigureAwait(false); _observableTotalCount.OnCompleted(); ScenarioSimulatorEventSource.Log.SimulationEnded(_hostName); }
public SlowMessagePublisher() { _listenerSubject = new Subject <Message>(); // ensure off-request message transport is obsered onto a different thread _listenerSubject.Buffer(TimeSpan.FromMilliseconds(100)).Subscribe( x => { // QUESTION: Is there a way to only let the buffer go if it has something to publish? if (x.Any()) { Observable.Start(async() => await Publish(x), TaskPoolScheduler.Default); } }); }
protected RemoteMapDataProvider(IFileSystemService fileSystemService, INetworkService networkService, ITrace trace) { _fileSystemService = fileSystemService; _networkService = networkService; _trace = trace; // TODO is thread-safe to work with queue like that here? var queue = new Queue <Tile>(); _requestBuffer = new Subject <Tile>(); _requestBuffer .Buffer(_limitThreshold) .SubscribeOn(Scheduler.ThreadPool) .Subscribe(tiles => MakeTileRequest(queue, tiles)); }
/// <summary> /// InfluxClient Constructor. The constructor expects LineProtocolConnectionParameters in params. It does initialization of HTTP Client and HTTP Client Handler. /// It also does initialization of worker buffer and failure handler buffer. /// </summary> /// <param name="paramsObj">The reference of Line Protocol Connection parameters.</param> /// <returns>returns instance of InfluxClient</returns> public InfluxClient(LineProtocolConnectionParameters paramsObj) { //1. populate necessary fields for Influx Connection //create HTTP Client for connection to Influx _httpClientHandler = new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }; _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = paramsObj.Address }; //Create Influx POST request URL _requestUri = $"write?db={Uri.EscapeDataString(paramsObj.DBName)}"; if (!string.IsNullOrEmpty(paramsObj.User)) { _requestUri += $"&u={Uri.EscapeDataString(paramsObj.User)}&p={Uri.EscapeDataString(paramsObj.Password)}"; } //2. populate necessary fields for buffer ( Using reactive Programming Rx ) //Create Subject for first buffer (worker buffer) Subject <string> subject = new Subject <string>(); _synSubject = Subject.Synchronize(subject); //Create first buffer ( worker buffer) with provided buffer flush time or buffer item limit for flush _subscription = _synSubject .Buffer(TimeSpan.FromSeconds(paramsObj.FlushBufferSeconds), paramsObj.FlushBufferItemsSize) .Subscribe(onNext: async(pointsList) => await SendToInflux(pointsList, true)); //Second buffer in case first fails. If requests fail in first buffer it will queue in 2nd buffer //Create Subject for second buffer (failure handler buffer) Subject <string> subjectSecondQueue = new Subject <string>(); _synSubjectSecondQueue = Subject.Synchronize(subjectSecondQueue); //Create second buffer ( failure handler buffer) with provided buffer flush time or buffer item limit for flush _subscriptionSecondQueue = _synSubjectSecondQueue .Buffer(TimeSpan.FromSeconds(paramsObj.FlushSecondBufferSeconds), paramsObj.FlushSecondBufferItemsSize) .Subscribe(onNext: async(pointsListSecondQueue) => await SendToInflux(pointsListSecondQueue, false)); }
public HttpMessagePublisher(IResourceOptionsProvider resourceOptionsProvider) { _resourceOptionsProvider = resourceOptionsProvider; _listenerSubject = new Subject<IMessage>(); _httpHandler = new HttpClientHandler(); _httpClient = new HttpClient(_httpHandler); // ensure off-request message transport is obsered onto a different thread _listenerSubject.Buffer(TimeSpan.FromMilliseconds(100)).Subscribe(x => { // TODO: would be nice if the buffer only triggered when it had values if (x.Any()) { Observable.Start(async () => await Process(x), TaskPoolScheduler.Default); } }); }
public HttpMessagePublisher(IResourceOptionsProvider resourceOptionsProvider) { _resourceOptionsProvider = resourceOptionsProvider; _listenerSubject = new Subject <IMessage>(); _httpHandler = new HttpClientHandler(); _httpClient = new HttpClient(_httpHandler); // ensure off-request message transport is obsered onto a different thread _listenerSubject.Buffer(TimeSpan.FromMilliseconds(100)).Subscribe(x => { // TODO: would be nice if the buffer only triggered when it had values if (x.Any()) { Observable.Start(async() => await Process(x), TaskPoolScheduler.Default); } }); }
/// <summary> /// Initializes a new instance of the <see cref="ExtensionState{TSender}"/> class. /// </summary> public ExtensionState(IReactiveDbObject sender) { this.sender = sender; this.addingSubject = new Subject <IReactiveDbObjectEventArgs>(); this.addedSubject = new Subject <IReactiveDbObjectEventArgs>(); this.updatingSubject = new Subject <IReactiveDbObjectEventArgs>(); this.updatedSubject = new Subject <IReactiveDbObjectEventArgs>(); this.deletingSubject = new Subject <IReactiveDbObjectEventArgs>(); this.deletedSubject = new Subject <IReactiveDbObjectEventArgs>(); this.errorSubject = new Subject <IReactiveDbObjectEventArgs>(); this.validationErrorSubject = new Subject <ValidationEntityEventArg>(); this.startDelayNotifications = new Subject <Unit>(); this.thrownExceptions = new ScheduledSubject <Exception>(Scheduler.Immediate, ExceptionHandler.Default); /* this.addedObservable = createObservable(ref addedSubject); * this.addingObservable = createObservable(ref addingSubject); * this.updatedObservable = createObservable(ref updatedSubject); * this.updatingObservable = createObservable(ref updatingSubject); * this.deletedObservable = createObservable(ref deletedSubject); * this.deletingObservable = createObservable(ref deletingSubject);*/ this.addedObservable = addedSubject .Buffer( Observable.Merge( addedSubject.Where(_ => !areChangeNotificationsDelayed()).Select(_ => Unit.Default), startDelayNotifications) ) .SelectMany(batch => dedup(batch)) .Publish() .RefCount(); this.addingObservable = addingSubject .Buffer( Observable.Merge( addingSubject.Where(_ => !areChangeNotificationsDelayed()).Select(_ => Unit.Default), startDelayNotifications) ) .SelectMany(batch => dedup(batch)) .Publish() .RefCount(); this.updatedObservable = updatedSubject .Buffer( Observable.Merge( updatedSubject.Where(_ => !areChangeNotificationsDelayed()).Select(_ => Unit.Default), startDelayNotifications) ) .SelectMany(batch => dedup(batch)) .Publish() .RefCount(); this.updatingObservable = updatingSubject .Buffer( Observable.Merge( updatingSubject.Where(_ => !areChangeNotificationsDelayed()).Select(_ => Unit.Default), startDelayNotifications) ) .SelectMany(batch => dedup(batch)) .Publish() .RefCount(); this.deletedObservable = deletedSubject .Buffer( Observable.Merge( deletedSubject.Where(_ => !areChangeNotificationsDelayed()).Select(_ => Unit.Default), startDelayNotifications) ) .SelectMany(batch => dedup(batch)) .Publish() .RefCount(); this.deletingObservable = deletingSubject .Buffer( Observable.Merge( deletingSubject.Where(_ => !areChangeNotificationsDelayed()).Select(_ => Unit.Default), startDelayNotifications) ) .SelectMany(batch => dedup(batch)) .Publish() .RefCount(); this.errorObservable = errorSubject .Buffer( Observable.Merge( errorSubject.Where(_ => !areChangeNotificationsDelayed()).Select(_ => Unit.Default), startDelayNotifications) ) .SelectMany(batch => dedup(batch)) .Publish() .RefCount(); this.errorCountable = new Countable(); this.errorObservable = this.errorCountable.GetCountable(this.errorObservable); this.validationErrorObservable = validationErrorSubject .Publish() .RefCount(); this.validationErrorCountable = new Countable(); this.validationErrorObservable = this.validationErrorCountable.GetCountable(this.validationErrorObservable); }
public async Task RunEmulationAsync(string scenario, CancellationToken token) { Logger.SimulationStarted(_hostName, scenario); var produceMessagesForScenario = SimulationScenarios.GetScenarioByName(scenario); var emulationTasks = new List <Task>(); var warmup = _simulatorConfiguration.WarmupDuration; var warmupPerCar = warmup.Ticks / _carsPerInstance; var messagingFactories = Enumerable.Range(0, _simulatorConfiguration.SenderCountPerInstance) .Select(i => MessagingFactory.CreateFromConnectionString(_simulatorConfiguration.EventHubConnectionString)) .ToArray(); _observableTotalCount .Sum() .Subscribe(total => Logger.Info("Final total count for all cars is {0}", total)); _observableTotalCount .Buffer(TimeSpan.FromMinutes(5)) .Scan(0, (total, next) => total + next.Sum()) .Subscribe(total => Logger.Info("Current count for all cars is {0}", total)); try { for (int i = 0; i < _carsPerInstance; i++) { // Use the short form of the host or instance name to generate the vehicle ID var carId = String.Format("{0}-{1}", ConfigurationHelper.InstanceName, i); var messageSender = new MessageSender( messagingFactory: messagingFactories[i % messagingFactories.Length], config: _simulatorConfiguration, serializer: Serializer.ToJsonUTF8, telemetryPublisher: _instrumentationPublisher ); var carTask = SimulateCarAsync( deviceId: carId, produceMessagesForScenario: produceMessagesForScenario, sendMessageAsync: messageSender.SendAsync, waitBeforeStarting: TimeSpan.FromTicks(warmupPerCar * i), totalCount: _observableTotalCount, token: token ); emulationTasks.Add(carTask); } await Task.WhenAll(emulationTasks.ToArray()); _observableTotalCount.OnCompleted(); } finally { // cannot await on a finally block to do CloseAsync foreach (var factory in messagingFactories) { factory.Close(); } } Logger.SimulationEnded(_hostName); }
public SlowMessagePublisher() { _listenerSubject = new Subject<Message>(); // ensure off-request message transport is obsered onto a different thread _listenerSubject.Buffer(TimeSpan.FromMilliseconds(100)).Subscribe( x => { // QUESTION: Is there a way to only let the buffer go if it has something to publish? if (x.Any()) { Observable.Start(async () => await Publish(x), TaskPoolScheduler.Default); } }); }
public LogglyProcessor(ILogglyClient client) { _client = client ?? throw new ArgumentNullException(nameof(client)); _subscription = _messageSubject.Buffer(TimeSpan.FromMilliseconds(50)).Subscribe(ProcessLogQueue); }