private async Task ProcessQueueItemsAsync()
        {
            await this.controlQueueLock.WaitAsync();

            IDatabase database = this.redisConnection.GetDatabase();

            RedisValue[] messagesJson = await database.ListRangeAsync(this.partitionControlQueueKey);

            foreach (string messageJson in messagesJson)
            {
                TaskMessage taskMessage = RedisSerializer.DeserializeObject <TaskMessage>(messageJson);
                string      instanceId  = taskMessage.OrchestrationInstance.InstanceId;

                string orchestrationStateKey         = RedisKeyNameResolver.GetOrchestrationRuntimeStateHashKey(this.taskHub, this.partition);
                string orchestrationInstanceQueueKey = RedisKeyNameResolver.GetOrchestrationQueueKey(this.taskHub, this.partition, instanceId);

                // Enter empty runtime state if it is an execution start event
                if (taskMessage.Event is ExecutionStartedEvent startedEvent)
                {
                    OrchestrationRuntimeState emptyState = GetEmptyState(taskMessage);
                    await database.HashSetAsync(orchestrationStateKey, instanceId, RedisSerializer.SerializeObject(emptyState.Events), When.NotExists);
                }

                await database.ListRightPopLeftPushAsync(this.partitionControlQueueKey, orchestrationInstanceQueueKey);

                this.activeOrchestrationLocks.TryAdd(instanceId, new SemaphoreSlim(1, 1));
            }

            //Release lock so another notification can be handled
            this.controlQueueLock.Release();
        }
        private async Task <List <TaskMessage> > GetOrchestrationControlQueueMessages(string orchestrationId)
        {
            IDatabase redisDatabase = this.redisConnection.GetDatabase();
            string    orchestrationControlQueueKey = RedisKeyNameResolver.GetOrchestrationQueueKey(this.taskHub, this.partition, orchestrationId);

            return((await redisDatabase.ListRangeAsync(orchestrationControlQueueKey))
                   .Select(json => RedisSerializer.DeserializeObject <TaskMessage>(json))
                   .ToList());
        }
        public RedisTransactionBuilder RemoveItemsFromOrchestrationQueue(string orchestrationId, int numberOfItemsToRemove)
        {
            if (this.partition == null)
            {
                throw new ArgumentNullException($"Cannot call {nameof(RemoveItemsFromOrchestrationQueue)} without a partition set.");
            }
            string orchestrationQueueKey = RedisKeyNameResolver.GetOrchestrationQueueKey(this.taskHub, this.partition, orchestrationId);

            for (int i = 0; i < numberOfItemsToRemove; i++)
            {
                transaction.ListRightPopAsync(orchestrationQueueKey);
            }

            return(this);
        }