public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "hotelgroups/{code}/signals/{signal}")] HttpRequestMessage req,
            [OrchestrationClient] DurableOrchestrationClient context,
            string code,
            string signal,
            TraceWriter log)
        {
            string json = await req.Content.ReadAsStringAsync();

            HotelGroupActorState initialState = JsonConvert.DeserializeObject <HotelGroupActorState>(json);

            var hotelGroupActorStatus = await context.GetStatusAsync(code);

            string runningStatus = hotelGroupActorStatus == null ? "NULL" : hotelGroupActorStatus.RuntimeStatus.ToString();

            log.Info($"Instance running status: '{runningStatus}'.");

            if (hotelGroupActorStatus == null || hotelGroupActorStatus.RuntimeStatus != OrchestrationRuntimeStatus.Running)
            {
                await context.StartNewAsync("HotelGroupActor", code, initialState);

                log.Info($"Started a new hotel group actor with code = '{code}'.");
            }
            else
            {
                await context.RaiseEventAsync(code, "operation", signal);

                log.Info($"Signaled an existing hotel group actor with code '{code}' and signal '{signal}'.");
            }

            var res = context.CreateCheckStatusResponse(req, code);

            res.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromSeconds(10));
            return(res);
        }
        public static async Task <int> RefreshMemberships([ActivityTrigger] HotelGroupActorState state, TraceWriter log)
        {
            var digitalMemberships = new List <string>();

            DateTime now        = DateTime.Now;
            string   formatDate = now.ToString("MM/dd/yyyy hh:mm:ss.fff tt");

            log.Info($"**** start refresh request for '{state.Code}' @ {formatDate}");

            // For testing only...
            if (state.RefreshCounter < state.MaxTestCounter)
            {
                digitalMemberships.Add("TEST");
            }

            now        = DateTime.Now;
            formatDate = now.ToString("MM/dd/yyyy hh:mm:ss.fff tt");
            log.Info($"**** end refresh request for '{state.Code}' @ {formatDate}");
            return(digitalMemberships.Count);
        }
        public static async Task <HotelGroupActorState> Run(
            [OrchestrationTrigger] DurableOrchestrationContext context,
            TraceWriter log)
        {
            HotelGroupActorState state = context.GetInput <HotelGroupActorState>();

            log.Info($"HotelGroupActor starting with refresh counter: {state.RefreshCounter} and isTest: {state.IsTest}");

            string operation = "refresh";

            using (var cts = new CancellationTokenSource())
            {
                var      operationTask = context.WaitForExternalEvent <string>("operation");
                DateTime deadline      = context.CurrentUtcDateTime.AddMinutes(state.MinutesBetweenInvocations);
                var      timeoutTask   = context.CreateTimer(deadline, cts.Token);

                Task winner = await Task.WhenAny(operationTask, timeoutTask);

                if (winner == operationTask)
                {
                    log.Info($"An operation event received!");
                    operation = operationTask.Result;
                    // Cancel the timer
                    cts.Cancel();
                }
                else
                {
                    // Default the timeout task to mean a 'refresh' operation
                    log.Info($"A timeout event received!");
                    operation = "refresh";
                }
            }

            log.Info($"***** received '{operation}' event.");

            operation = operation?.ToLowerInvariant();
            if (operation == "refresh")
            {
                state.UpTimeInMinutes += state.MinutesBetweenInvocations;

                log.Info($"Calling the refresh memberships function {state.UpTimeInMinutes}");
                var memberships = 0;
                memberships = await context.CallActivityAsync <int>("RefreshMemberships", state);

                state.RefreshCounter += memberships;
                log.Info($"Resuming after the refresh memberships function: {state.RefreshCounter}");

                string reason = $"Simulate an end due to no more memberships";
                if (memberships == 0)
                {
                    log.Info(reason);
                    state.EndReason = reason;
                    operation       = "end";
                }
                else if (state.UpTimeInMinutes >= state.MaxMinutesToRun)
                {
                    reason = $"Simulate an end due to max run time reached";
                    log.Info(reason);
                    state.EndReason = reason;
                    operation       = "end";
                }
            }
            else
            {
                // Support other operations
            }

            if (operation != "end")
            {
                log.Info($"Re-enqueing the state");
                context.ContinueAsNew(state);
            }

            if (operation == "end")
            {
                // Externalize the state to email, SMS or both - trigger a logic app
            }

            return(state);
        }