public bool ShouldReceive(IStreamIdentity stream, object filterData, object item)
 {
     if (predicateFunc == null)
     {
         predicateFunc = RehydrateStaticFuncion(className, methodName);
     }
     return predicateFunc(stream, filterData, item);
 }
        protected FilterPredicateWrapperData(SerializationInfo info, StreamingContext context)
        {
            FilterData = info.GetValue(SER_FIELD_DATA, typeof(object));
            methodName = info.GetString(SER_FIELD_METHOD);
            className  = info.GetString(SER_FIELD_CLASS);

            predicateFunc = RehydrateStaticFuncion(className, methodName);
        }
        internal FilterPredicateWrapperData(object filterData, StreamFilterPredicate pred)
        {
            CheckFilterPredicateFunc(pred); // Assert expected pre-conditions are always true.

            FilterData = filterData;
            predicateFunc = pred;

            DehydrateStaticFunc(pred);
        }
Esempio n. 4
0
        private void DehydrateStaticFunc(StreamFilterPredicate pred)
        {
#if DEBUG
            CheckFilterPredicateFunc(pred); // Assert expected pre-conditions are always true.
#endif
            MethodInfo method = pred.GetMethodInfo();
            className  = method.DeclaringType.FullName;
            methodName = method.Name;
        }
        private void DehydrateStaticFunc(StreamFilterPredicate pred)
        {
#if DEBUG
            CheckFilterPredicateFunc(pred); // Assert expected pre-conditions are always true.
#endif
            MethodInfo method = pred.GetMethodInfo();
            className = method.DeclaringType.FullName;
            methodName = method.Name;
        }
Esempio n. 6
0
        internal FilterPredicateWrapperData(object filterData, StreamFilterPredicate pred)
        {
            CheckFilterPredicateFunc(pred); // Assert expected pre-conditions are always true.

            FilterData    = filterData;
            predicateFunc = pred;

            DehydrateStaticFunc(pred);
        }
Esempio n. 7
0
 public bool ShouldDeliver(IStreamIdentity stream, object filterData, StreamFilterPredicate shouldReceiveFunc)
 {
     foreach (object item in events)
     {
         if (shouldReceiveFunc(stream, filterData, item))
             return true; // There is something in this batch that the consumer is intereted in, so we should send it.
     }
     return false; // Consumer is not interested in any of these events, so don't send.
 }
Esempio n. 8
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.
 /// </summary>
 /// <typeparam name="T">The type of object produced by the observable.</typeparam>
 /// <param name="obs">The Observable object.</param>
 /// <param name="onNextAsync">Delegte that is called for IAsyncObserver.OnNextAsync.</param>
 /// <param name="onCompletedAsync">Delegte 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 paramaters 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 explicitely 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 <object> > SubscribeAsync <T>(this IAsyncObservable <object> obs,
                                                                            Func <T, StreamSequenceToken, Task> onNextAsync,
                                                                            Func <Task> onCompletedAsync,
                                                                            StreamSequenceToken token,
                                                                            StreamFilterPredicate filterFunc = null,
                                                                            object filterData = null)
 {
     return(obs.SubscribeAsync(onNextAsync, DefaultOnError, onCompletedAsync, token, filterFunc, filterData));
 }
        private static StreamFilterPredicate RehydrateStaticFuncion(string funcClassName, string funcMethodName)
        {
            Type                  funcClassType = TypeResolver.ResolveType(funcClassName);
            MethodInfo            method        = funcClassType.GetMethod(funcMethodName);
            StreamFilterPredicate pred          = (StreamFilterPredicate)method.CreateDelegate(typeof(StreamFilterPredicate));

#if DEBUG
            CheckFilterPredicateFunc(pred); // Assert expected pre-conditions are always true.
#endif
            return(pred);
        }
Esempio n. 10
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.
        /// </summary>
        /// <typeparam name="T">The type of object produced by the observable.</typeparam>
        /// <param name="obs">The Observable object.</param>
        /// <param name="onNextAsync">Delegte that is called for IAsyncObserver.OnNextAsync.</param>
        /// <param name="onErrorAsync">Delegte that is called for IAsyncObserver.OnErrorAsync.</param>
        /// <param name="onCompletedAsync">Delegte 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 paramaters 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 explicitely 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 <object> > SubscribeAsync <T>(this IAsyncObservable <object> obs,
                                                                                   Func <T, StreamSequenceToken, Task> onNextAsync,
                                                                                   Func <Exception, Task> onErrorAsync,
                                                                                   Func <Task> onCompletedAsync,
                                                                                   StreamSequenceToken token,
                                                                                   StreamFilterPredicate filterFunc = null,
                                                                                   object filterData = null)
        {
            var genericObserver = new DelegateAsyncObserver <T>(onNextAsync, onErrorAsync, onCompletedAsync);

            return(obs.SubscribeAsync(genericObserver, token, filterFunc, filterData));
        }
Esempio n. 11
0
        private void DehydrateStaticFunc(StreamFilterPredicate pred)
        {
            var method = pred.Method;

            if (!CheckStaticFunc(method))
            {
                throw new ArgumentException("Filter function must be static and not abstract.");
            }

            className  = method.DeclaringType.FullName;
            methodName = method.Name;
        }
        public async Task SubscribeWithBadFunc(Guid streamId, string streamNamespace, string providerName)
        {
            logger.Info("SubscribeWithBadFunc StreamId={0} StreamProvider={1}Grain={2}",
                        streamId, providerName, this.AsReference <IFilteredStreamConsumerGrain>());

            InitStream(streamId, streamNamespace, providerName);

            var observer = new MyStreamObserver <int>(logger);

            StreamFilterPredicate filterFunc = BadFunc;

            // This next call should fail because func is not static
            await State.Stream.SubscribeAsync(observer, null, filterFunc);
        }
        /// <summary>
        /// Check that the user-supplied stream predicate function is valid.
        /// Stream predicate functions must be static and not abstract.
        /// </summary>
        private static void CheckFilterPredicateFunc(StreamFilterPredicate predicate)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException("predicate", "Stream Filter predicate function must not be null.");
            }

            MethodInfo method = predicate.GetMethodInfo();

            if (!method.IsStatic || method.IsAbstract)
            {
                throw new ArgumentException("Stream Filter predicate function must be static and not abstract.");
            }
        }
Esempio n. 14
0
        public async Task <StreamSubscriptionHandle <T> > SubscribeAsync(
            IAsyncObserver <T> observer,
            StreamSequenceToken token,
            StreamFilterPredicate filterFunc, object filterData)
        {
            if (token != null && !IsRewindable)
            {
                throw new ArgumentNullException("token", "Passing a non-null token to a non-rewindable IAsyncObservable.");
            }

            if (logger.IsVerbose)
            {
                logger.Verbose("Subscribe Observer={0} Token={1}", observer, token);
            }
            await BindExtensionLazy();

            IStreamFilterPredicateWrapper filterWrapper = null;

            if (filterFunc != null)
            {
                filterWrapper = new FilterPredicateWrapperData(filterData, filterFunc);
            }

            if (!connectedToRendezvous)
            {
                if (logger.IsVerbose)
                {
                    logger.Verbose("Subscribe - Connecting to Rendezvous {0} My GrainRef={1} Token={2}",
                                   pubSub, myGrainReference, token);
                }

                await pubSub.RegisterConsumer(stream.StreamId, streamProviderName, myGrainReference, token, filterWrapper);

                connectedToRendezvous = true;
            }
            else if (filterWrapper != null)
            {
                // Already connected and registered this grain, but also need to register this additional filter too.
                await pubSub.RegisterConsumer(stream.StreamId, streamProviderName, myGrainReference, token, filterWrapper);
            }

            return(myExtension.AddObserver(stream, observer, filterWrapper));
        }
Esempio n. 15
0
 public bool ShouldDeliver(IStreamIdentity stream, object filterData, StreamFilterPredicate shouldReceiveFunc)
 {
     return(_events.Any(item => shouldReceiveFunc(stream, filterData, item)));
 }
 public bool ShouldDeliver(StreamId stream, object filterData, StreamFilterPredicate shouldReceiveFunc)
 {
     throw new NotImplementedException();
 }
Esempio n. 17
0
        public async Task <StreamSubscriptionHandle <T> > SubscribeAsync(
            IAsyncObserver <T> observer,
            StreamSequenceToken token,
            StreamFilterPredicate filterFunc = null,
            object filterData = null)
        {
            if (token != null && !IsRewindable)
            {
                throw new ArgumentNullException("token", "Passing a non-null token to a non-rewindable IAsyncObservable.");
            }
            if (observer is GrainReference)
            {
                throw new ArgumentException("On-behalf subscription via grain references is not supported. Only passing of object references is allowed.", "observer");
            }

            if (logger.IsVerbose)
            {
                logger.Verbose("Subscribe Observer={0} Token={1}", observer, token);
            }
            await BindExtensionLazy();

            IStreamFilterPredicateWrapper filterWrapper = null;

            if (filterFunc != null)
            {
                filterWrapper = new FilterPredicateWrapperData(filterData, filterFunc);
            }

            if (logger.IsVerbose)
            {
                logger.Verbose("Subscribe - Connecting to Rendezvous {0} My GrainRef={1} Token={2}",
                               pubSub, myGrainReference, token);
            }

            GuidId subscriptionId = pubSub.CreateSubscriptionId(stream.StreamId, myGrainReference);

            // Optimistic Concurrency:
            // In general, we should first register the subsription with the pubsub (pubSub.RegisterConsumer)
            // and only if it succeeds store it locally (myExtension.SetObserver).
            // Basicaly, those 2 operations should be done as one atomic transaction - either both or none and isolated from concurrent reads.
            // BUT: there is a distributed race here: the first msg may arrive before the call is awaited
            // (since the pubsub notifies the producer that may immideately produce)
            // and will thus not find the subriptionHandle in the extension, basically violating "isolation".
            // Therefore, we employ Optimistic Concurrency Control here to guarantee isolation:
            // we optimisticaly store subscriptionId in the handle first before calling pubSub.RegisterConsumer
            // and undo it in the case of failure.
            // There is no problem with that we call myExtension.SetObserver too early before the handle is registered in pub sub,
            // since this subscriptionId is unique (random Guid) and no one knows it anyway, unless successfully subscribed in the pubsub.
            var subriptionHandle = myExtension.SetObserver(subscriptionId, stream, observer, token, filterWrapper);

            try
            {
                await pubSub.RegisterConsumer(subscriptionId, stream.StreamId, streamProviderName, myGrainReference, filterWrapper);

                return(subriptionHandle);
            } catch (Exception)
            {
                // Undo the previous call myExtension.SetObserver.
                myExtension.RemoveObserver(subscriptionId);
                throw;
            }
        }
Esempio n. 18
0
 public Task <StreamSubscriptionHandle <T> > SubscribeAsync(IAsyncObserver <T> observer, StreamSequenceToken token,
                                                            StreamFilterPredicate filterFunc = null,
                                                            object filterData = null) =>
 throw new NotImplementedException();
        /// <summary>
        /// Check that the user-supplied stream predicate function is valid.
        /// Stream predicate functions must be static and not abstract.
        /// </summary>
        /// <param name="func"></param>
        private static void CheckFilterPredicateFunc(StreamFilterPredicate predicate)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException("predicate", "Stream Filter predicate function must not be null.");
            }

            MethodInfo method = predicate.GetMethodInfo();

            if (!method.IsStatic || method.IsAbstract)
            {
                throw new ArgumentException("Stream Filter predicate function must be static and not abstract.");
            }
        }
Esempio n. 20
0
 public virtual Task <StreamSubscriptionHandle <object> > SubscribeAsync(IAsyncObserver <object> observer, StreamSequenceToken token, StreamFilterPredicate filterFunc = null, object filterData = null)
 {
     return(endpoint.SubscribeAsync(observer, token, filterFunc, filterData));
 }
Esempio n. 21
0
 public Task <StreamSubscriptionHandle <T> > SubscribeAsync(IAsyncObserver <T> observer, StreamSequenceToken token,
                                                            StreamFilterPredicate filterFunc = null,
                                                            object filterData = null)
 {
     return(GetConsumerInterface().SubscribeAsync(observer, token, filterFunc, filterData));
 }
Esempio n. 22
0
 internal FilterPredicateWrapperData(object filterData, StreamFilterPredicate pred)
 {
     FilterData    = filterData;
     predicateFunc = pred;
     DehydrateStaticFunc(pred);
 }
 public bool ShouldDeliver(IStreamIdentity stream, object filterData, StreamFilterPredicate shouldReceiveFunc)
 {
     // If there is something in this batch that the consumer is interested in, we should send it
     // else the consumer is not interested in any of these events, so don't send.
     return(Events.Any(item => shouldReceiveFunc(stream, filterData, item)));
 }
 public bool ShouldDeliver(IStreamIdentity stream, object filterData, StreamFilterPredicate shouldReceiveFunc)
 {
     return(true);
 }
Esempio n. 25
0
 public bool ShouldDeliver(IStreamIdentity stream, object filterData, StreamFilterPredicate shouldReceiveFunc)
 {
     // ShouldDeliver is called on a per IBatchContainer basis for each IBatchContainer that composes this BatchContainerBatch.
     // Therefore, no filtering is done on the BatchContainerBatch level.
     return(true);
 }
Esempio n. 26
0
 public Task <StreamSubscriptionHandle <T> > SubscribeAsync(
     IAsyncObserver <T> observer,
     StreamSequenceToken token,
     StreamFilterPredicate filterFunc = null,
     object filterData = null) => stream.SubscribeAsync(observer, token, filterFunc, filterData);
Esempio n. 27
0
 public bool ShouldDeliver(IStreamIdentity stream, object filterData, StreamFilterPredicate shouldReceiveFunc)
 {
     throw new NotSupportedException();
 }
Esempio n. 28
0
 public bool ShouldDeliver(IStreamIdentity stream, object filterData, StreamFilterPredicate shouldReceiveFunc)
 {
     return(EventData?.Events?.Count > 0);
 }