示例#1
0
 private int WhichNode(CachedObject obj)
 {
     return(WhichNode(obj.PrimaryKey));
 }
示例#2
0
        /// <summary>
        ///     FeedMany is non transactional but it does not lock the cache. To be used for massive feeds
        ///     Can feed with business objects (they will be packed to CachedObject) or directly with CachedObject
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="items"></param>
        /// <param name="excludeFromEviction"></param>
        /// <param name="packetSize"></param>
        public void FeedMany <T>(IEnumerable <T> items, bool excludeFromEviction, int packetSize)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }

            // Lazy type registration
            var itemType = typeof(T);

            ClientSideTypeDescription description = null;
            var    needPack = itemType != typeof(CachedObject);
            string typeName = null;

            var sessionId = Guid.NewGuid().ToString();

            if (needPack)
            {
                description = RegisterTypeIfNeeded(itemType);
                typeName    = description.FullTypeName;
            }

            // initialize one request per node
            var requests = new PutRequest[CacheClients.Count];


            // Parallelize both nodes and requests (multiple requests for the same node are executed in parallel if multiple connections are available in the pool)
            var tasks = new List <Task>();

            foreach (var item in items)
            {
                if (typeName == null)
                {
                    typeName = (item as CachedObject)?.FullTypeName;
                }

                var packedItem = needPack ? CachedObject.Pack(item, description) : item as CachedObject;

                var node = WhichNode(packedItem);

                if (requests[node] == null)
                {
                    requests[node] = new PutRequest(typeName)
                    {
                        ExcludeFromEviction = excludeFromEviction,
                        SessionId           = sessionId
                    }
                }
                ;

                var request = requests[node];


                request.Items.Add(packedItem);

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


                    tasks.Add(task);
                    requests[node] = new PutRequest(typeName)
                    {
                        ExcludeFromEviction = excludeFromEviction,
                        SessionId           = sessionId
                    };
                }
            }


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


                if (request != null)
                {
                    request.EndOfSession = true;

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

                    tasks.Add(task);
                }
            }

            try
            {
                Task.WaitAll(tasks.ToArray());
                Dbg.Trace($"{tasks.Count} tasks finished");
            }
            catch (AggregateException e)
            {
                if (e.InnerException != null)
                {
                    throw e.InnerException;
                }
            }
        }
示例#3
0
        public void FeedMany <T>(IEnumerable <T> items, bool excludeFromEviction, int packetSize)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }

            var itemType = typeof(T);

            ClientSideTypeDescription description = null;
            var    needPack = itemType != typeof(CachedObject);
            string typeName = null;

            var sessionId = Guid.NewGuid().ToString();

            if (needPack)
            {
                description = RegisterTypeIfNeeded(itemType);
                typeName    = description.FullTypeName;
            }


            using (var enumerator = items.GetEnumerator())
            {
                var endLoop = false;

                while (!endLoop)
                {
                    var packet = new CachedObject[packetSize];
                    var toPack = new T[packetSize];

                    var count = 0;
                    for (var i = 0; i < packetSize; i++)
                    {
                        if (enumerator.MoveNext())
                        {
                            var item = enumerator.Current;
                            toPack[i] = item;
                            count++;
                        }
                        else
                        {
                            endLoop = true;
                            break;
                        }
                    }


                    Parallel.For(0, count, new ParallelOptions {
                        MaxDegreeOfParallelism = 10
                    }, (i, loopState) =>
                    {
                        var item       = toPack[i];
                        var packedItem = needPack ? CachedObject.Pack(item, description) : item as CachedObject;

                        if (typeName == null)
                        {
                            typeName = packedItem?.FullTypeName;
                        }

                        packet[i] = packedItem;
                    }
                                 );


                    if (typeName != null) // null only for empty collection
                    {
                        var request = new PutRequest(typeName)
                        {
                            ExcludeFromEviction = excludeFromEviction,
                            SessionId           = sessionId,
                            EndOfSession        = endLoop
                        };

                        foreach (var cachedObject in packet)
                        {
                            if (cachedObject != null)
                            {
                                request.Items.Add(cachedObject);
                            }
                        }

                        var response = Channel.SendRequest(request);
                        if (response is ExceptionResponse exResponse)
                        {
                            throw new CacheException("Error while writing an object to the cache", exResponse.Message,
                                                     exResponse.CallStack);
                        }
                    }
                }
            }
        }