//public IFeedSession BeginFeed(TypeDescriptionConfig typeDescription, int packetSize, bool excludeFromEviction)
        //{
        //    //RegisterTypeIfNeeded()


        //    //return new FeedSession<TItem>(packetSize, excludeFromEviction);

        //    throw new NotImplementedException();
        //}

        /// <summary>
        ///     As an alternative to <see cref="FeedMany{T}(IEnumerable{T},bool,int)" /> you can use
        ///     <see cref="BeginFeed{TItem}" /> <see cref="Add{TItem}" /> <see cref="EndFeed{TItem}" />
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <param name="session"></param>
        /// <param name="item"></param>
        public void Add <TItem>(IFeedSession session, TItem item) where TItem : class
        {
            var sessionImplementation = (FeedSession <TItem>)session;

            if (sessionImplementation.IsClosed)
            {
                throw new CacheException("The feed session is closed");
            }

            var description = RegisterTypeIfNeeded(typeof(TItem));

            var packedItem = CachedObject.Pack(item, description);

            sessionImplementation.Request.Items.Add(packedItem);

            if (sessionImplementation.Request.Items.Count == sessionImplementation.PacketSize)
            {
                var request = sessionImplementation.Request;
                sessionImplementation.Request = null;

                // only one packet at a time is fed asynchronously. If the previous send is still pending wait fot it to finish
                sessionImplementation.WaitForAsyncCompletion();


                ThreadPool.QueueUserWorkItem(state =>
                {
                    try
                    {
                        var rq = (Request)state;

                        sessionImplementation.StartAsync();

                        var response = Channel.SendRequest(rq);
                        if (response is ExceptionResponse exResponse)
                        {
                            sessionImplementation.EndAsync(
                                new CacheException(
                                    "Error while writing an object to the cache",
                                    exResponse.Message, exResponse.CallStack));
                        }
                        else
                        {
                            sessionImplementation.EndAsync(null);
                        }
                    }
                    catch (Exception e)
                    {
                        sessionImplementation.EndAsync(e);
                    }
                }, request);


                // prepare a new empty put request that will receive new items
                sessionImplementation.Request = new PutRequest(typeof(TItem));
            }
        }
Exemple #2
0
        /// <summary>
        ///     Close a feed session. Send all the remaining data and wait for all asynchronous operations to finish
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <param name="session"></param>
        public void EndFeed <TItem>(IFeedSession session) where TItem : class
        {
            var sessionImplementation = (ParallelFeedSession <TItem>)session;

            if (sessionImplementation.IsClosed)
            {
                throw new CacheException("The feed session is closed");
            }


            //send the last packet left for each node
            for (var node = 0; node < CacheClients.Count; node++)
            {
                var request = sessionImplementation.Requests[node];

                if (request != null && request.Items.Count > 0)
                {
                    var n    = node; // copy to avoid modified closure
                    var task = Task.Factory.StartNew(re =>
                    {
                        var response = CacheClients[n].Channel.SendRequest((Request)re);
                        if (response is ExceptionResponse exResponse)
                        {
                            throw new CacheException(
                                "Error while writing an object to the cache",
                                exResponse.Message, exResponse.CallStack);
                        }
                    }, request);

                    sessionImplementation.AddTask(task);
                }
            }

            try
            {
                sessionImplementation.WaitForAll();
            }
            catch (AggregateException e)
            {
                if (e.InnerException != null)
                {
                    throw e.InnerException;
                }
            }


            sessionImplementation.IsClosed = true;
        }
        /// <summary>
        ///     As an alternative to <see cref="FeedMany{T}(IEnumerable{T},bool,int)" /> you can use
        ///     <see cref="BeginFeed{TItem}" /> <see cref="Add{TItem}" /> <see cref="EndFeed{TItem}" />
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <param name="session"></param>
        public void EndFeed <TItem>(IFeedSession session) where TItem : class
        {
            var feedSession = (FeedSession <TItem>)session;

            feedSession.WaitForAsyncCompletion();

            // the last block is always send synchronously.
            if (feedSession.Request.Items.Count > 0)
            {
                var response = Channel.SendRequest(feedSession.Request);
                if (response is ExceptionResponse exResponse)
                {
                    throw new CacheException("Error while writing an object to the cache", exResponse.Message,
                                             exResponse.CallStack);
                }
            }

            feedSession.IsClosed = true;
        }
Exemple #4
0
        /// <summary>
        ///     Add an element to the cache during a fill session. Items are effectively send to the server in fixed size packets
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <param name="session"></param>
        /// <param name="item"></param>
        public void Add <TItem>(IFeedSession session, TItem item) where TItem : class
        {
            var sessionImplementation = (ParallelFeedSession <TItem>)session;

            if (sessionImplementation.IsClosed)
            {
                throw new CacheException("The feed session is closed");
            }

            var description = RegisterTypeIfNeeded(typeof(TItem));

            var packedItem = CachedObject.Pack(item, description);

            var node = WhichNode(packedItem);

            var request = sessionImplementation.Requests[node];

            request.Items.Add(packedItem);

            // for each node fill a packet of fixed size and send it to the server only when completed
            if (request.Items.Count == sessionImplementation.PacketSize)
            {
                // create a new empty one for the future objects
                sessionImplementation.Requests[node] = new PutRequest(typeof(TItem));

                var task = Task.Factory.StartNew(re =>
                {
                    var response = CacheClients[node].Channel.SendRequest((Request)re);
                    if (response is ExceptionResponse exResponse)
                    {
                        throw new CacheException(
                            "Error while writing an object to the cache",
                            exResponse.Message, exResponse.CallStack);
                    }
                }, request);

                sessionImplementation.AddTask(task);
            }
        }