示例#1
0
        private Task SaveStateAsync(SaveStateIntent intent, CancellationToken ct)
        {
            if (intent.ServiceState != null)
            {
                var serviceStateRecord = GetOrCreateServiceStateRecord(intent.ServiceId);
                serviceStateRecord.State = Serializer.SerializeToString(intent.ServiceState);
            }

            if (intent.RoutineState != null || intent.RoutineResult != null)
            {
                var    routineRecord = DataStore.GetRoutineRecord(intent.Routine.RoutineId);
                string stateData     = null;
                string resultData    = null;
                if (intent.RoutineState != null)
                {
                    stateData = Serializer.SerializeToString(intent.RoutineState);
                }
                if (intent.RoutineResult != null)
                {
                    resultData = Serializer.SerializeToString(intent.RoutineResult);
                }

                lock (routineRecord)
                {
                    if (!string.IsNullOrEmpty(intent.Routine.ETag) &&
                        intent.Routine.ETag != routineRecord.ETag)
                    {
                        throw new ConcurrentRoutineExecutionException(
                                  new ETagMismatchException());
                    }

                    routineRecord.ETag   = DateTime.UtcNow.Ticks.ToString("X16");
                    routineRecord.State  = stateData;
                    routineRecord.Result = resultData;
                }

                if (intent.RoutineResult != null)
                {
                    routineRecord.Completion.SetResult(resultData);
                }
            }

            return(Task.FromResult(true));
        }
示例#2
0
            public Task SaveStateAsync(SaveStateIntent intent, CancellationToken ct)
            {
                //if (intent.ServiceState != null)
                //{
                //    throw new NotImplementedException("Service state is not implemented yet due to non-finalized design.");
                //}

                if (intent.RoutineState != null || intent.RoutineResult != null)
                {
                    UpsertRoutineData(intent.Routine.RoutineId, intent.Routine.ETag,
                                      routineDataEnvelope =>
                    {
                        routineDataEnvelope.ServiceId = intent.ServiceId;

                        if (_routineEventData.Caller != null)
                        {
                            routineDataEnvelope.Caller = _routineEventData.Caller;
                        }

                        if (intent.RoutineResult != null)
                        {
                            routineDataEnvelope.Status = RoutineStatus.Complete;
                            routineDataEnvelope.Result = _fabric.Serializer.SerializeToString(intent.RoutineResult);
                        }
                        else
                        {
                            routineDataEnvelope.Status = RoutineStatus.Awaiting;
                            routineDataEnvelope.State  = _fabric.Serializer.SerializeToString(intent.RoutineState);

                            if (_routineEventData.Continuation != null)
                            {
                                routineDataEnvelope.Continuation = _routineEventData.Continuation;
                            }
                        }
                    });
                }

                return(Task.FromResult(true));
            }
        public async Task SaveStateAsync(SaveStateIntent intent, CancellationToken ct)
        {
            var serviceId = await GetServiceIdAsync(ct);

            if (intent.ServiceState != null)
            {
#warning Save Service state
                //var serviceStateRecord = GetOrCreateServiceStateRecord(intent.ServiceId);
                //serviceStateRecord.StateJson = _serializer.Serialize(intent.ServiceState);
                throw new NotImplementedException("Service state is not implemented yet due to non-finalized design.");
            }

            if (intent.RoutineState != null || intent.RoutineResult != null)
            {
                var transitionDescriptor = await GetTransitionDescriptorAsync(ct);

                var routineDescriptor = await GetRoutineDescriptorAsync(ct);

                RoutineRecord routineRecord;
                if (transitionDescriptor.Type == TransitionType.InvokeRoutine)
                {
                    routineRecord = new RoutineRecord
                    {
                        PartitionKey = serviceId.ServiceName,
                        RowKey       = routineDescriptor.RoutineId
                    };
                }
                else
                {
                    routineRecord = await TryLoadRoutineRecordAsync(ct);

                    if (routineRecord == null)
                    {
                        throw new InvalidOperationException("missing routine record");
                    }
                }

                if (intent.RoutineResult != null)
                {
                    routineRecord.State        = null;
                    routineRecord.Continuation = null;
                    routineRecord.Result       = _serializer.SerializeToString(intent.RoutineResult);
                    routineRecord.Status       = (int)RoutineStatus.Complete;
                }
                else if (intent.AwaitedRoutine != null)
                {
                    routineRecord.Status        = (int)RoutineStatus.Awaiting;
                    routineRecord.AwaitService  = intent.AwaitedRoutine.ServiceId?.ServiceName;
                    routineRecord.AwaitMethod   = intent.AwaitedRoutine.MethodId?.MethodName;
                    routineRecord.AwaitIntentId = intent.AwaitedRoutine.Id;
                }
                else
                {
                    routineRecord.Status = (int)RoutineStatus.Scheduled;
                }

                if (routineRecord.Status != (int)RoutineStatus.Complete && intent.RoutineState != null)
                {
                    routineRecord.State = _serializer.SerializeToString(intent.RoutineState);
                }

                // Copy over the continuation from the message to the routine record
                //  on first transition, unless routine is already completed.
                if (routineRecord.Status != (int)RoutineStatus.Complete &&
                    string.IsNullOrEmpty(routineRecord.Continuation) && EventData.Continuation != null)
                {
                    routineRecord.Continuation = JsonConvert.SerializeObject(
                        EventData.Continuation, CloudEventsSerialization.JsonSerializerSettings);
                }

                routineRecord.Method = intent.Routine?.MethodId?.MethodName;

                if (EventData.Caller != null)
                {
                    routineRecord.CallerService   = EventData.Caller.ServiceId?.ServiceName;
                    routineRecord.CallerMethod    = EventData.Caller.Routine?.MethodId?.MethodName;
                    routineRecord.CallerRoutineId = EventData.Caller.Routine?.RoutineId;
                }

                while (true)
                {
                    try
                    {
                        if (string.IsNullOrEmpty(routineRecord.ETag))
                        {
                            try
                            {
                                await _routinesTable.InsertAsync(routineRecord, ct);
                            }
                            catch (TableRowAlreadyExistsException)
                            {
                                throw new ConcurrentTransitionException();
                            }
                        }
                        else
                        {
                            try
                            {
                                await _routinesTable.ReplaceAsync(routineRecord, ct);
                            }
                            catch (TableRowETagMismatchException)
                            {
                                throw new ConcurrentTransitionException();
                            }
                        }
                        break;
                    }
                    catch (TableDoesNotExistException)
                    {
                        await _routinesTable.CreateAsync(ct);
                    }
                }
            }
        }
示例#4
0
 public Task SaveStateAsync(SaveStateIntent intent, CancellationToken ct)
 => _fabric.SaveStateAsync(intent, ct);