Esempio n. 1
0
 public async Task BecomeConsumer(Guid streamId, string streamNamespace, string providerToUse)
 {
     logger.Info("BecomeConsumer");
     IStreamProvider streamProvider = GetStreamProvider(providerToUse);
     consumer = streamProvider.GetStream<int>(streamId, streamNamespace);
     consumerHandle = await consumer.SubscribeAsync(OnNextAsync, OnErrorAsync, OnActivateAsync);
 }
        /// <summary>
        /// Subscribe a consumer to this observable using delegates.
        /// This method is a helper for the IAsyncObservable.SubscribeAsync allowing the subscribing class to inline the
        /// handler methods instead of requiring an instance of IAsyncObserver.
        /// </summary>
        /// <typeparam name="T">The type of object produced by the observable.</typeparam>
        /// <param name="obs">The Observable object.</param>
        /// <param name="onNextAsync">Delegate that is called for IAsyncObserver.OnNextAsync.</param>
        /// <param name="onErrorAsync">Delegate that is called for IAsyncObserver.OnErrorAsync.</param>
        /// <param name="onCompletedAsync">Delegate that is called for IAsyncObserver.OnCompletedAsync.</param>
        /// <param name="token">The stream sequence to be used as an offset to start the subscription from.</param>
        /// <param name="filterFunc">Filter to be applied for this subscription</param>
        /// <param name="filterData">Data object that will be passed in to the filterFunc.
        /// This will usually contain any parameters required by the filterFunc to make it's filtering decision.</param>
        /// <returns>A promise for a StreamSubscriptionHandle that represents the subscription.
        /// The consumer may unsubscribe by using this handle.
        /// The subscription remains active for as long as it is not explicitly unsubscribed.
        /// </returns>
        /// <exception cref="ArgumentException">Thrown if the supplied stream filter function is not suitable.
        /// Usually this is because it is not a static method. </exception>
        public static Task <StreamSubscriptionHandle <T> > SubscribeAsync <T>(this IAsyncObservable <T> obs,
                                                                              Func <T, StreamSequenceToken, Task> onNextAsync,
                                                                              Func <Exception, Task> onErrorAsync,
                                                                              Func <Task> onCompletedAsync,
                                                                              StreamSequenceToken token,
                                                                              StreamFilterPredicate filterFunc = null,
                                                                              object filterData = null)
        {
            var genericObserver = new GenericAsyncObserver <T>(onNextAsync, onErrorAsync, onCompletedAsync);

            return(obs.SubscribeAsync(genericObserver, token, filterFunc, filterData));
        }
Esempio n. 3
0
        public static Task <IAsyncDisposable> SubscribeAsync <T>(this IAsyncObservable <T> source, Action <T> onNext)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (onNext == null)
            {
                throw new ArgumentNullException(nameof(onNext));
            }

            return(source.SubscribeAsync(new AsyncObserver <T>(x => { onNext(x); return Task.CompletedTask; }, ex => Task.FromException(ex), () => Task.CompletedTask)));
        }
        public async Task BecomeConsumer(Guid streamId, string providerToUse)
        {
            _logger.LogInformation("Consumer.BecomeConsumer");
            if (String.IsNullOrEmpty(providerToUse))
            {
                throw new ArgumentNullException("providerToUse");
            }
            IStreamProvider    streamProvider = this.GetStreamProvider(providerToUse);
            IAsyncStream <int> stream         = streamProvider.GetStream <int>(streamId, StreamNamespace);

            _consumer           = stream;
            _subscriptionHandle = await _consumer.SubscribeAsync(new AsyncObserver <int>(EventArrived));
        }
Esempio n. 5
0
        public static Task <IAsyncDisposable> SubscribeAsync <T>(this IAsyncObservable <T> source, Func <T, Task> onNextAsync)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (onNextAsync == null)
            {
                throw new ArgumentNullException(nameof(onNextAsync));
            }

            return(source.SubscribeAsync(new AsyncObserver <T>(onNextAsync, ex => Task.FromException(ex), () => Task.CompletedTask)));
        }
        public async ValueTask <IAsyncDisposable> ConnectAsync()
        {
            using (await gate.LockAsync().ConfigureAwait(false))
            {
                if (connection == null)
                {
                    var subscription = await source.SubscribeAsync(subject).ConfigureAwait(false);

                    connection = new Connection(this, subscription);
                }

                return(connection);
            }
        }
Esempio n. 7
0
        public async Task BecomeConsumer(Guid streamId, string streamNamespace, string providerToUse)
        {
            logger.LogInformation("BecomeConsumer");
            IStreamProvider streamProvider = this.GetStreamProvider(providerToUse);

            consumer       = streamProvider.GetStream <int>(streamId, streamNamespace);
            consumerHandle = await consumer.SubscribeAsync(
                OnNextAsync,
                OnErrorAsync,
                () =>
            {
                Reset();
                return(Task.CompletedTask);
            });
        }
Esempio n. 8
0
        /// <summary>
        /// Adds the specified event handler, causing a subscription to the underlying source.
        /// </summary>
        /// <param name="handler">Event handler to add. The same delegate should be passed to the Remove operation in order to remove the event handler.</param>
        /// <param name="invoke">Invocation delegate to raise the event in the derived class.</param>
        /// <exception cref="ArgumentNullException"><paramref name="handler"/> or <paramref name="invoke"/> is null.</exception>
        protected void Add(Delegate handler, Action <TSender, TEventArgs> invoke)
        {
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            if (invoke == null)
            {
                throw new ArgumentNullException(nameof(invoke));
            }

            var gate    = new object();
            var isAdded = false;
            var isDone  = false;

            var remove = new Action(() =>
            {
                lock (gate)
                {
                    if (isAdded)
                    {
                        Remove(handler);
                    }
                    else
                    {
                        isDone = true;
                    }
                }
            });

            //
            // [OK] Use of unsafe SubscribeAsync: non-pretentious wrapper of an observable in an event; exceptions can occur during +=.
            //
            var d = _source.SubscribeAsync(
                x => { _invokeHandler(invoke, /*this,*/ x); return(Task.CompletedTask); },
                ex => { remove(); return(Task.FromException(ex)); },
                () => { remove(); return(Task.CompletedTask); }
                );

            lock (gate)
            {
                if (!isDone)
                {
                    Add(handler, d);
                    isAdded = true;
                }
            }
        }
        public static async ValueTask <TResult> ToTask <TSource, TResult>(this IAsyncObservable <TSource> source, ToTaskAsyncObserver <TSource, TResult> observer)
        {
            await source.SubscribeAsync(observer).ConfigureAwait(false);

            if (observer.Error != null)
            {
                throw observer.Error;
            }

            if (!observer.HasValue)
            {
                throw new InvalidOperationException("Sequence has no elements");
            }

            return(observer.Value);
        }
Esempio n. 10
0
        public static async ValueTask SubscribeAsync <T>(this IAsyncObservable <T> source, Action <T> onNext = null, Action <Exception> onError = null, Action onCompleted = null, CancellationToken token = default)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            var observer = new AnonymousAsyncObserver <T> .Sync(onNext);

            try
            {
                await source.SubscribeAsync(observer, token);

                onCompleted?.Invoke();
            }
            catch (Exception ex) when(onError != null)
            {
                onError(ex);
            }
        }
Esempio n. 11
0
        public static ValueTask <IAsyncDisposable> SubscribeAsync <T>(this IAsyncObservable <T> source, Func <T, ValueTask> onNextAsync, Func <Exception, ValueTask> onErrorAsync, Func <ValueTask> onCompletedAsync)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (onNextAsync == null)
            {
                throw new ArgumentNullException(nameof(onNextAsync));
            }
            if (onErrorAsync == null)
            {
                throw new ArgumentNullException(nameof(onErrorAsync));
            }
            if (onCompletedAsync == null)
            {
                throw new ArgumentNullException(nameof(onCompletedAsync));
            }

            return(source.SubscribeAsync(new AsyncObserver <T>(onNextAsync, onErrorAsync, onCompletedAsync)));
        }
Esempio n. 12
0
        //---------------------------------------------------------------------
        async Task _createFriendStreamConsumer(string friend_etguid)
        {
            StreamSubscriptionHandle <StreamData> consumer_handle = null;

            MapFriendConsumerHandle.TryGetValue(friend_etguid, out consumer_handle);
            if (consumer_handle != null)
            {
                return;
            }

            var             grain             = Entity.getUserData <GrainCellPlayer>();
            var             consumer_observer = new CellPlayerFriendConsumerObserver <StreamData>(this);
            IStreamProvider stream_provider   = grain.getStreamProvider();
            IAsyncObservable <StreamData> async_observable = stream_provider.GetStream <StreamData>(new Guid(friend_etguid), null);

            consumer_handle = await async_observable.SubscribeAsync(consumer_observer);

            MapFriendConsumerHandle[friend_etguid] = consumer_handle;

            // 主动查询好友信息
        }
Esempio n. 13
0
            public async override ValueTask OnNextAsync(IAsyncObservable <T> value)
            {
                if (IsCanceled)
                {
                    return;
                }

                var inner = new InnerObserver(this);

                try
                {
                    _inner = inner;
                    await value.SubscribeAsync(inner).ConfigureAwait(false);
                }
                catch (Exception error)
                {
                    _inner = null;
                    await SignalErrorAsync(error).ConfigureAwait(false);
                }
                _inner = null;
            }
Esempio n. 14
0
        public async Task PersistentStreamingOverSingleGatewayTest()
        {
            const int streamCount = 100;

            this.fixture.Logger.Info("************************ PersistentStreamingOverSingleGatewayTest *********************************");

            // generate stream Id's
            List <Guid> streamIds = Enumerable.Range(0, streamCount)
                                    .Select(i => Guid.NewGuid())
                                    .ToList();

            // subscribe to all streams
            foreach (Guid streamId in streamIds)
            {
                IStreamProvider        streamProvider = this.fixture.Client.GetStreamProvider(Fixture.StreamProviderName);
                IAsyncObservable <int> stream         = streamProvider.GetStream <int>(streamId, null);
                await stream.SubscribeAsync(OnNextAsync);
            }

            // create producer grains
            List <ISampleStreaming_ProducerGrain> producers = streamIds
                                                              .Select(id => this.fixture.GrainFactory.GetGrain <ISampleStreaming_ProducerGrain>(id))
                                                              .ToList();

            // become producers
            await Task.WhenAll(Enumerable.Range(0, streamCount).Select(i => producers[i].BecomeProducer(streamIds[i], null, Fixture.StreamProviderName)));

            // produce some events
            await Task.WhenAll(Enumerable.Range(0, streamCount).Select(i => producers[i].StartPeriodicProducing()));

            await Task.Delay(TimeSpan.FromMilliseconds(1000));

            await Task.WhenAll(Enumerable.Range(0, streamCount).Select(i => producers[i].StopPeriodicProducing()));

            int[] counts = await Task.WhenAll(Enumerable.Range(0, streamCount).Select(i => producers[i].GetNumberProduced()));

            // make sure all went well
            await TestingUtils.WaitUntilAsync(lastTry => CheckCounters(counts.Sum(), lastTry), Timeout);
        }
Esempio n. 15
0
        public static async Task <ChannelReader <T> > AsChannelReader <T>(this IAsyncObservable <T> observable, int?maxBufferSize = null)
        {
            // This sample shows adapting an observable to a ChannelReader without
            // back pressure, if the connection is slower than the producer, memory will
            // start to increase.

            // If the channel is bounded, TryWrite will return false and effectively
            // drop items.

            // The other alternative is to use a bounded channel, and when the limit is reached
            // block on WaitToWriteAsync. This will block a thread pool thread and isn't recommended and isn't shown here.
            var channel = maxBufferSize != null?Channel.CreateBounded <T>(maxBufferSize.Value) : Channel.CreateUnbounded <T>();

            var disposable = await observable.SubscribeAsync(
                (value, sst) => Task.FromResult(channel.Writer.TryWrite(value)),
                error => Task.FromResult(channel.Writer.TryComplete(error)),
                () => Task.FromResult(channel.Writer.TryComplete()));

            // Complete the subscription on the reader completing
            channel.Reader.Completion.ContinueWith(task => disposable.UnsubscribeAsync());

            return(channel.Reader);
        }
Esempio n. 16
0
        public static async ValueTask SubscribeAsync <T>(this IAsyncObservable <T> source, Func <T, ValueTask> onNext, Func <Exception, ValueTask> onError = null, Func <ValueTask> onCompleted = null, CancellationToken token = default)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            var observer = new AnonymousAsyncObserver <T> .Async(onNext);

            try
            {
                await source.SubscribeAsync(observer, token);

                if (onCompleted != null)
                {
                    await onCompleted();
                }
            }
            catch (Exception ex) when(onError != null)
            {
                await onError(ex);
            }
        }
Esempio n. 17
0
        private static async Task ForEachAsyncCore <TSource>(IAsyncObservable <TSource> source, Func <TSource, int, Task> onNext, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            var tcs = new TaskCompletionSource <object>();

            var subscription = new SingleAssignmentAsyncDisposable();

            using (token.Register(() =>
            {
                tcs.TrySetCanceled(token);

                subscription.DisposeAsync().AsTask().ContinueWith(t =>
                {
                    if (t.Exception != null)
                    {
                        // TODO: Trace?
                    }
                });
            }))
            {
                var i = 0;

                var o = AsyncObserver.Create <TSource>(
                    async x =>
                {
                    try
                    {
                        await onNext(x, checked (i++)).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        try
                        {
                            tcs.TrySetException(ex);
                        }
                        finally
                        {
                            await subscription.DisposeAsync().ConfigureAwait(false);
                        }
                    }
                },
                    async ex =>
                {
                    try
                    {
                        tcs.TrySetException(ex);
                    }
                    finally
                    {
                        await subscription.DisposeAsync().ConfigureAwait(false);
                    }
                },
                    async() =>
                {
                    try
                    {
                        tcs.TrySetResult(null);
                    }
                    finally
                    {
                        await subscription.DisposeAsync().ConfigureAwait(false);
                    }
                }
                    );

                //
                // NB: If any of the lines below throw, the result will go into the Task returned from the async method.
                //     There's also no need to use SubscribeSafeAsync here; the exception will propagate just fine.
                //

                var d = await source.SubscribeAsync(o).ConfigureAwait(false);

                await subscription.AssignAsync(d).ConfigureAwait(false);
            }

            await tcs.Task.ConfigureAwait(false);
        }
 /// <summary>
 /// Subscribe a consumer to this observable using delegates.
 /// This method is a helper for the IAsyncObservable.SubscribeAsync allowing the subscribing class to inline the
 /// handler methods instead of requiring an instance of IAsyncObserver.
 /// </summary>
 /// <typeparam name="T">The type of object produced by the observable.</typeparam>
 /// <param name="obs">The Observable object.</param>
 /// <param name="onNextAsync">Delegate that is called for IAsyncObserver.OnNextAsync.</param>
 /// <returns>A promise for a StreamSubscriptionHandle that represents the subscription.
 /// The consumer may unsubscribe by using this handle.
 /// The subscription remains active for as long as it is not explicitly unsubscribed.</returns>
 public static Task <StreamSubscriptionHandle <T> > SubscribeAsync <T>(this IAsyncObservable <T> obs,
                                                                       Func <T, StreamSequenceToken, Task> onNextAsync)
 {
     return(obs.SubscribeAsync(onNextAsync, DefaultOnError, DefaultOnCompleted));
 }
Esempio n. 19
0
 /// <summary>
 /// Subscribe a consumer to this observable.
 /// </summary>
 /// <param name="observer">The asynchronous observer to subscribe.</param>
 /// <returns>A promise for a StreamSubscriptionHandle that represents the subscription.
 /// The consumer may unsubscribe by using this handle.
 /// The subscription remains active for as long as it is not explicitely unsubscribed.
 /// </returns>
 public static Task <StreamSubscriptionHandle <object> > SubscribeAsync <T>(this IAsyncObservable <object> observable,
                                                                            IAsyncObserver <T> observer)
 {
     return(observable.SubscribeAsync(new GenericAsyncObserver <T>(observer)));
 }
Esempio n. 20
0
        //
        // Summary:
        //     Subscribe a consumer to this observable using delegates. This method is a helper
        //     for the IAsyncObservable.SubscribeAsync allowing the subscribing class to inline
        //     the handler methods instead of requiring an instance of IAsyncObserver.
        //
        // Parameters:
        //   obs:
        //     The Observable object.
        //
        //   onNextAsync:
        //     Delegte that is called for IAsyncObserver.OnNextAsync.
        //
        //   onCompletedAsync:
        //     Delegte that is called for IAsyncObserver.OnCompletedAsync.
        //
        // Type parameters:
        //   T:
        //     The type of object produced by the observable.
        //
        // Returns:
        //     A promise for a StreamSubscriptionHandle that represents the subscription. The
        //     consumer may unsubscribe by using this handle. The subscription remains active
        //     for as long as it is not explicitely unsubscribed.
        public static Task <StreamSubscriptionHandle <T> > SubscribeAsync <T>(this IAsyncObservable <T> obs, Func <T, StreamSequenceToken, Task> onNextAsync, Func <Task> onCompletedAsync)
        {
            AsyncObserver <T> observer = new AsyncObserver <T>(onNextAsync, new Func <Exception, Task>(_ => TaskDone.Done), onCompletedAsync);

            return(obs.SubscribeAsync(observer));
        }