Пример #1
0
        public void ProcessRequest(Request request, IClient client)
        {
            if (request is RemoveManyRequest removeManyRequest)
            {
                try
                {
                    int removed = RemoveMany(removeManyRequest.Query);

                    client?.SendResponse(new ItemsCountResponse {
                        ItemsCount = removed
                    });
                }
                catch (Exception e)
                {
                    client?.SendResponse(new ExceptionResponse(e));

                    // if client is null we are inside a transaction. The exception will be processed at a higher level
                    if (client == null)
                    {
                        throw;
                    }
                }
                return;
            }

            if (request is RemoveRequest removeRequest) // remove one item by primary key
            {
                var removed = _dataStore.RemoveByPrimaryKey(removeRequest.PrimaryKey);

                if (removed != null)
                {
                    _transactionLog?.NewTransaction(new DeleteDurableTransaction
                    {
                        ItemsToDelete = { removed }
                    });
                }

                return;
            }

            throw new NotSupportedException($"Can not process this request type:{request.GetType().Name}");
        }
Пример #2
0
        private void SaveDurableTransaction(TransactionRequest transactionRequest,
                                            SafeDictionary <string, DataStore> dataStores)
        {
            // get the items to delete from the DeleteManyRequests
            var itemsToDelete = new HashSet <PackedObject>();

            var deleteManyRequests = transactionRequest.ChildRequests.Where(r => r is RemoveManyRequest)
                                     .Cast <RemoveManyRequest>().ToList();

            foreach (var deleteManyRequest in deleteManyRequests)
            {
                var ds    = dataStores[deleteManyRequest.CollectionName];
                var items = new QueryManager(ds).ProcessQuery(deleteManyRequest.Query);

                foreach (var item in items)
                {
                    itemsToDelete.Add(item);
                }
            }

            // add items to delete explicitly
            foreach (var remove in transactionRequest.ChildRequests.Where(r => r is RemoveRequest)
                     .Cast <RemoveRequest>())
            {
                var collectionName = remove.CollectionName;

                if (dataStores[collectionName].DataByPrimaryKey.TryGetValue(remove.PrimaryKey, out var item))
                {
                    itemsToDelete.Add(item);
                }
            }

            // get items to put (conditions have already been checked)
            var itemsToPut = transactionRequest.ChildRequests.Where(r => r is PutRequest).Cast <PutRequest>()
                             .SelectMany(r => r.Items).ToList();

            Dbg.Trace($"S: begin writing delayed transaction {transactionRequest.TransactionId}");
            _transactionLog?.NewTransaction(new MixedDurableTransaction
            {
                ItemsToDelete = itemsToDelete.ToList(),
                ItemsToPut    = itemsToPut
            },
                                            true
                                            );
        }
Пример #3
0
        private int ProcessPutRequest(PutRequest putRequest)
        {
            // a feed session may contain multiple requests
            if (putRequest.SessionId != default)
            {
                SessionManager.AddToSession(putRequest.SessionId, putRequest.Items);

                if (putRequest.EndOfSession)
                {
                    var all = SessionManager.EndSession(putRequest.SessionId);

                    _transactionLog?.NewTransaction(new PutDurableTransaction {
                        Items = all
                    });

                    _dataStore.InternalPutMany(all, putRequest.ExcludeFromEviction);

                    return(all.Count);
                }

                return(0);
            }

            if (putRequest.OnlyIfNew) // conditional insert
            {
                if (putRequest.Items.Count != 1)
                {
                    throw new NotSupportedException("TryAdd can be called only with exactly one item");
                }


                var item = putRequest.Items.First();
                if (!_dataStore.DataByPrimaryKey.ContainsKey(item.PrimaryKey))
                {
                    _transactionLog?.NewTransaction(new PutDurableTransaction {
                        Items = putRequest.Items
                    });

                    _dataStore.InternalAddNew(item, putRequest.ExcludeFromEviction);

                    return(1);
                }

                return(0);
            }

            if (putRequest.Predicate != null) // conditional update
            {
                if (putRequest.Items.Count != 1)
                {
                    throw new NotSupportedException("UpdateIf can be called only with exactly one item");
                }

                var newVersion = putRequest.Items.First();

                if (!_dataStore.DataByPrimaryKey.TryGetValue(newVersion.PrimaryKey, out var oldVersion))
                {
                    throw new NotSupportedException("Item not found. Conditional update failed");
                }

                if (putRequest.Predicate.Match(oldVersion))
                {
                    _transactionLog?.NewTransaction(new PutDurableTransaction {
                        Items = putRequest.Items
                    });

                    _dataStore.InternalUpdate(newVersion);

                    return(1);
                }

                throw new CacheException("Condition not satisfied.Item not updated");
            }

            _transactionLog?.NewTransaction(new PutDurableTransaction {
                Items = putRequest.Items
            });

            _dataStore.InternalPutMany(putRequest.Items, putRequest.ExcludeFromEviction);

            return(putRequest.Items.Count);
        }