Exemple #1
0
        private Task <long> ExecMultiAddRemove(int db, RedisLiteral command, string key, byte[][] values, bool queueJump)
        {
            RedisFeatures features;

            if (values.Length > 1 && ((features = Features) == null || !features.SetVaradicAddRemove))
            {
                RedisTransaction tran    = this as RedisTransaction;
                bool             execute = false;
                if (tran == null)
                {
                    tran    = CreateTransaction();
                    execute = true;
                }
                Task <bool>[] tasks = new Task <bool> [values.Length];

                for (int i = 0; i < values.Length; i++)
                {
                    tasks[i] = ExecuteBoolean(RedisMessage.Create(db, command, key, values[i]), queueJump);
                }
                TaskCompletionSource <long> final = new TaskCompletionSource <long>();
                tasks[values.Length - 1].ContinueWith(t =>
                {
                    try
                    {
                        if (t.ShouldSetResult(final))
                        {
                            long count = 0;
                            for (int i = 0; i < tasks.Length; i++)
                            {
                                if (tran.Wait(tasks[i]))
                                {
                                    count++;
                                }
                            }
                            final.TrySetResult(count);
                        }
                    }
                    catch (Exception ex)
                    {
                        final.SafeSetException(ex);
                    }
                });
                if (execute)
                {
                    tran.Execute(queueJump);
                }
                return(final.Task);
            }
            else
            {
                var args = new RedisMessage.RedisParameter[values.Length + 1];
                args[0] = key;
                for (int i = 0; i < values.Length; i++)
                {
                    args[i + 1] = values[i];
                }
                return(ExecuteInt64(RedisMessage.Create(db, command, args), queueJump));
            }
        }
        Task <long> IHashCommands.Remove(int db, string key, string[] fields, bool queueJump)
        {
            RedisFeatures features;

            if (fields.Length > 1 && ((features = Features) == null || !features.HashVaradicDelete))
            {
                RedisTransaction tran    = this as RedisTransaction;
                bool             execute = false;
                if (tran == null)
                {
                    tran    = CreateTransaction();
                    execute = true;
                }
                Task <bool>[] tasks = new Task <bool> [fields.Length];

                var hashes = tran.Hashes;
                for (int i = 0; i < fields.Length; i++)
                {
                    tasks[i] = hashes.Remove(db, key, fields[i], queueJump);
                }
                TaskCompletionSource <long> final = new TaskCompletionSource <long>();
                tasks[fields.Length - 1].ContinueWith(t =>
                {
                    try
                    {
                        if (t.ShouldSetResult(final))
                        {
                            long count = 0;
                            for (int i = 0; i < tasks.Length; i++)
                            {
                                if (tran.Wait(tasks[i]))
                                {
                                    count++;
                                }
                            }
                            final.TrySetResult(count);
                        }
                    }
                    catch (Exception ex)
                    {
                        final.SafeSetException(ex);
                    }
                });
                if (execute)
                {
                    tran.Execute(queueJump);
                }
                return(final.Task);
            }
            else
            {
                return(ExecuteInt64(RedisMessage.Create(db, RedisLiteral.HDEL, key, fields), queueJump));
            }
        }
        // minimise delegate creations via a single static delegate instance

        Task <bool> IStringCommands.TakeLock(int db, string key, string value, int expirySeconds, bool queueJump)
        {
            var result = new TaskCompletionSource <bool>();

            using (RedisTransaction tran = CreateTransaction())
            {
                tran.AddCondition(Condition.KeyNotExists(db, key));
                tran.Strings.Set(db, key, value, expirySeconds);
                tran.Execute(queueJump, state: result).ContinueWith(takeLockContinuation);
            }
            return(result.Task);
        }
Exemple #4
0
 private void OnTransactionCompleting(RedisTransaction transaction, Task<bool> transactionTask, IList<Message> messages, TaskCompletionSource<object> tcs)
 {
     if (transactionTask.IsCompleted)
     {
         try
         {
             OnTransactionComplete(transaction, transactionTask.Result, messages, tcs);
         }
         catch (OperationCanceledException)
         {
             tcs.TrySetCanceled();
         }
         catch (Exception ex)
         {
             tcs.TrySetException(ex);
         }
     }
     else
     {
         transactionTask.Then(result => OnTransactionComplete(transaction, result, messages, tcs))
                        .ContinueWithNotComplete(tcs);
     }
 }
Exemple #5
0
        private void OnTransactionComplete(RedisTransaction transaction, bool success, IList<Message> messages, TaskCompletionSource<object> tcs)
        {
            if (success)
            {
                _trace.TraceVerbose("Transaction completed successfully");

                tcs.TrySetResult(null);
            }
            else
            {
                _trace.TraceVerbose("Transaction failed. Retrying...");

                _trace.TraceVerbose("Transaction disposed");

                // Dispose the transaction
                transaction.Dispose();

                SendImpl(messages, tcs);
            }
        }
Exemple #6
0
        private Task<bool> ExecuteTransaction(RedisTransaction transaction, long? oldId, IList<Message> messages)
        {
            _trace.TraceVerbose("ExecuteTransaction({0})", oldId);

            // New target id
            long newId = (oldId ?? 0) + 1;

            // TODO: Don't do this everytime
            byte[] data = RedisMessage.ToBytes(newId, messages);

            // These don't need to be observed
            transaction.AddCondition(Condition.KeyEquals(_db, _key, oldId));
            transaction.Strings.Increment(_db, _key);
            transaction.Publish(_key, data);

            // Execute the transaction
            return transaction.Execute();
        }