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 <OrchestrationRuntimeState> GetOrchestrationRuntimeState(string orchestrationId)
        {
            IDatabase redisDatabase             = this.redisConnection.GetDatabase();
            string    orchestrationRuntimeState = RedisKeyNameResolver.GetOrchestrationRuntimeStateHashKey(this.taskHub, this.partition);
            string    eventListJson             = await redisDatabase.HashGetAsync(orchestrationRuntimeState, orchestrationId);

            return(RedisSerializer.DeserializeRuntimeState(eventListJson));
        }
コード例 #3
0
        public RedisTransactionBuilder SetOrchestrationRuntimeState(string orchestrationId, OrchestrationRuntimeState state)
        {
            if (this.partition == null)
            {
                throw new ArgumentNullException($"Cannot call {nameof(SetOrchestrationRuntimeState)} without a partition set.");
            }
            string orchestrationStateKey = RedisKeyNameResolver.GetOrchestrationRuntimeStateHashKey(this.taskHub, this.partition);

            // Do not want to serialize new events;
            state.NewEvents.Clear();
            string stateJson = RedisSerializer.SerializeObject(state.Events);

            transaction.HashSetAsync(orchestrationStateKey, orchestrationId, stateJson);
            return(this);
        }
        private async Task RestoreLocks()
        {
            IDatabase redisDatabase    = this.redisConnection.GetDatabase();
            string    runtimeEventsKey = RedisKeyNameResolver.GetOrchestrationRuntimeStateHashKey(this.taskHub, this.partition);

            HashEntry[] runtimeEvents = await redisDatabase.HashGetAllAsync(runtimeEventsKey);

            foreach (var hashEntry in runtimeEvents)
            {
                OrchestrationRuntimeState state = RedisSerializer.DeserializeRuntimeState(hashEntry.Value);
                if (state.OrchestrationStatus == OrchestrationStatus.Pending ||
                    state.OrchestrationStatus == OrchestrationStatus.ContinuedAsNew ||
                    state.OrchestrationStatus == OrchestrationStatus.Running)
                {
                    // Still running, so add lock
                    this.activeOrchestrationLocks[hashEntry.Name] = new SemaphoreSlim(1);
                }
            }
        }