public static async Task <Chirp[]> RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var userId = context.GetInput <string>();

            // call the UserFollows entity to figure out whose chirps should be included
            var userFollowsProxy = context.CreateEntityProxy <IUserFollows>(userId);
            var followedUsers    = await userFollowsProxy.Get();

            // in parallel, collect all the chirps
            var tasks = followedUsers
                        .Select(id => context
                                .CreateEntityProxy <IUserChirps>(id)
                                .Get())
                        .ToList();

            await Task.WhenAll(tasks);

            // combine and sort the returned lists of chirps
            var sortedResults = tasks
                                .SelectMany(task => task.Result)
                                .OrderBy(chirp => chirp.Timestamp);

            return(sortedResults.ToArray());
        }
        public static async Task <bool> TransferFun(
            [OrchestrationTrigger] IDurableOrchestrationContext ctx
            )
        {
            var input = ctx.GetInput <TransferArgs>();

            var fromEntity = new EntityId(nameof(Account), input.FromAccount);
            var toEntity   = new EntityId(nameof(Account), input.ToAccount);

            using (await ctx.LockAsync(fromEntity, toEntity))
            {
                var fromAccount = ctx.CreateEntityProxy <IAccount>(fromEntity);
                var toAccount   = ctx.CreateEntityProxy <IAccount>(toEntity);

                var hasEnoughFunds = await fromAccount.Withdraw(input.Amount);

                if (!hasEnoughFunds)
                {
                    return(false);
                }

                await toAccount.Replenish(input.Amount);
            }

            return(true);
        }
예제 #3
0
        public async Task Run(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var proxy    = context.CreateEntityProxy <IEntitiesAggregator>(new EntityId(nameof(EntitiesAggregator), EntitiesAggregator.EntityId));
            var entities = await proxy.GetWorkedServices();

            var tasks = new List <Task>();

            foreach (var entity in entities)
            {
                var entityId     = new EntityId(nameof(ServiceAggregator), entity);
                var serviceProxy = context.CreateEntityProxy <IServiceAggregator>(entityId);
                var service      = await serviceProxy.Get();

                tasks.Add(
                    context.CallSubOrchestratorAsync(nameof(HealCheckOrchestration),
                                                     new ServiceInput
                {
                    Id   = entity,
                    Name = service.Name,
                    Url  = service.Url
                }));
            }

            await Task.WhenAll(tasks);
        }
예제 #4
0
        public static async Task <bool> RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var userId             = context.GetInput <string>();
            var shoppingCartEntity = new EntityId(nameof(ShoppingCartEntity), userId);
            var inventoryEntity    = new EntityId(nameof(InventoryEntity), "onestore");
            var orderEntity        = new EntityId(nameof(OrderEntity), userId);

            // Create a critical section to avoid race conditions.
            using (await context.LockAsync(inventoryEntity, orderEntity, shoppingCartEntity))
            {
                IShoppingCart shoppingCartProxy =
                    context.CreateEntityProxy <IShoppingCart>(shoppingCartEntity);
                IInventory inventoryProxy =
                    context.CreateEntityProxy <IInventory>(inventoryEntity);
                IOrder orderProxy =
                    context.CreateEntityProxy <IOrder>(orderEntity);

                var shoppingCartItems = await shoppingCartProxy.GetItemsAsync();

                var orderItem = new OrderItem()
                {
                    Timestamp = DateTime.UtcNow,
                    UserId    = userId,
                    Details   = shoppingCartItems
                };

                var canSell = true;
                foreach (var inventoryItem in orderItem.Details)
                {
                    if (await inventoryProxy.IsItemInInventory(inventoryItem))
                    {
                        await inventoryProxy.RemoveStockAsync(inventoryItem);

                        await shoppingCartProxy.RemoveItemAsync(inventoryItem);
                    }
                    else
                    {
                        canSell = false;
                        break;
                    }
                }

                if (canSell)
                {
                    await orderProxy.AddAsync(orderItem);

                    // order placed successfully
                    return(true);
                }
                // the order failed due to insufficient stock
                return(false);
            }
        }
예제 #5
0
        public static async Task <bool> TryFinalizeMatch(string initiator, string candidate, IDurableOrchestrationContext context)
        {
            var initiatorEntity = new EntityId(nameof(UserEntity), initiator);
            var candidateEntity = new EntityId(nameof(UserEntity), candidate);

            // Check if both users are still available and close enough.
            // To prevent race conditions, we do this in a critical section
            // that locks both users.

            using (await context.LockAsync(initiatorEntity, candidateEntity))
            {
                var initiatorProxy = context.CreateEntityProxy <IUserEntity>(initiatorEntity);
                var candidateProxy = context.CreateEntityProxy <IUserEntity>(candidateEntity);

                var initiatorInfo = await initiatorProxy.GetState();

                var candidateInfo = await candidateProxy.GetState();

                if (initiatorInfo.Location == null)
                {
                    // initiator is no longer trying to find a match! No need to keep trying.
                    return(true);
                }
                if (candidateInfo.Location == null ||
                    !ZipCodes.GetProximityList(initiatorInfo.Location.Value).Contains(candidateInfo.Location.Value))
                {
                    // candidate is no longer eligible
                    return(false);
                }

                // match was successful. Create a new ride.

                var driver = initiator.StartsWith("D") ? initiatorInfo : candidateInfo;
                var rider  = initiator.StartsWith("R") ? initiatorInfo : candidateInfo;

                var rideInfo = new RideInfo()
                {
                    RideId         = context.NewGuid(),
                    DriverId       = driver.UserId,
                    DriverLocation = driver.Location.Value,
                    RiderId        = rider.UserId,
                    RiderLocation  = rider.Location.Value,
                };

                // assign both users to the new ride.
                // (this is happening within the critical section)
                await Task.WhenAll(initiatorProxy.SetRide(rideInfo), candidateProxy.SetRide(rideInfo));

                return(true);
            }
        }
예제 #6
0
        public static async Task RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var(userId, location) = context.GetInput <(string, int)>();

            var userEntity = new EntityId(nameof(UserEntity), userId);

            // first, update the user information to advertise the location.

            await context.CallEntityAsync(userEntity, nameof(UserEntity.SetLocation), location);

            // next, try to match this user with
            // someone who has already advertised their location in a nearby region

            var nearbyRegions = ZipCodes.GetProximityList(location);

            foreach (var region in nearbyRegions)
            {
                var regionProxy = context.CreateEntityProxy <IRegionEntity>(region.ToString());

                string[] candidates = await(userId.StartsWith("R") ? regionProxy.GetAvailableDrivers() : regionProxy.GetAvailableRiders());

                foreach (var candidate in candidates)
                {
                    if (await TryFinalizeMatch(userId, candidate, context))
                    {
                        return;
                    }
                }
            }

            // we could not find a match.
            // we will just wait until someone else finds us.
        }
        public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var proxy = context.CreateEntityProxy <IDemoEntity>(new EntityId(nameof(DemoEntity), context.GetInput <Guid>().ToString()));
            await proxy.Do();

            await context.CallActivityAsync(nameof(Activity), null);
        }
        public static async Task <NewEmployeeRequest> RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log)
        {
            var employeeRuest = new NewEmployeeRequest
            {
                EmployeeFullName = new Faker().Name.FullName()
            };

            employeeRuest = await context.CallActivityAsync <NewEmployeeRequest>("GenerateEmployeeId", employeeRuest);

            employeeRuest = await context.CallActivityAsync <NewEmployeeRequest>("AssignManager", employeeRuest);

            string remarks;

            using (var timeoutCts = new CancellationTokenSource())
            {
                var  dueTime        = context.CurrentUtcDateTime.AddSeconds(300);
                Task durableTimeout = context.CreateTimer(dueTime, timeoutCts.Token);

                remarks = $"Waiting for Approval for Employee:{employeeRuest.EmployeeFullName} from the assigned manager: [{employeeRuest.ManagerFullName}]";
                employeeRuest.Remarks = remarks;
                log.LogInformation(remarks);

                var entityId = new EntityId(nameof(EmployeeCounter), nameof(EmployeeCounter));

                var proxy = context.CreateEntityProxy <IEmployeeCounter>(entityId);
                proxy.IncrementWaitingForApproval();

                context.SetCustomStatus(remarks);

                Task <bool> approvalEvent = context.WaitForExternalEvent <bool>("ApprovalEvent");
                if (approvalEvent == await Task.WhenAny(approvalEvent, durableTimeout))
                {
                    timeoutCts.Cancel();
                    remarks = $"Approval for employee[{employeeRuest.EmployeeFullName}] received from the assigned manager: [{employeeRuest.ManagerFullName}]";
                    proxy.IncrementEmployee();
                    context.SetCustomStatus(remarks);
                    log.LogInformation(remarks);
                    employeeRuest.ManagerApproved = true;
                }
                else
                {
                    remarks = $"Approval was not received from the assigned manager: [{employeeRuest.ManagerFullName}]. Please escalate";
                    context.SetCustomStatus(remarks);
                    log.LogInformation(remarks);
                    employeeRuest.ManagerApproved = false;
                    employeeRuest.Remarks         = remarks;
                    return(employeeRuest);
                }
            }

            employeeRuest = await context.CallActivityAsync <NewEmployeeRequest>("RegisterForGroupInsurance", employeeRuest);

            employeeRuest = await context.CallActivityAsync <NewEmployeeRequest>("PrintBadge", employeeRuest);

            remarks = $"All formalities completed for Employee {employeeRuest.EmployeeFullName}, ID: {employeeRuest.EmployeeId}";
            context.SetCustomStatus(remarks);
            employeeRuest.Remarks = remarks;
            return(employeeRuest);
        }
        public async Task <List <string> > RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            using var disposable = context.PushLoggerProperties();
            var phone   = context.GetInput <string>();
            var outputs = new List <string>();

            var proxy =
                context.CreateEntityProxy <INotifySubscriptionEntity>(NotifySubscriptionEntity.BuildId(phone, EventNameApproved));

            try
            {
                await proxy.Subscribe(context.InstanceId);

                await context.CallActivityWithRetryAsync(nameof(SendMessageActivity), _retryOptions, phone);                 // might fail, better include retry mechanism

                var approvalNotification = await proxy.GetLatestNotification()                                               // get latest, maybe already approved (optional)
                                           ?? await WaitForUserAction(context, _timeToWait, EventNameApproved);              // wait for user approval

                outputs.Add(approvalNotification != null
                                                                                        ? $"We have approval from {phone} at {approvalNotification.Timestamp}"
                                                                                        : $"No approval from {phone} after waiting {_timeToWait}");
            }
            finally
            {
                await proxy.Unsubscribe(context.InstanceId);
            }
            return(outputs);
        }
        public async Task ExecuteTransfer([OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var message = context.GetInput <TransferMessage>();

            var fromAccountEntity = new EntityId(nameof(AccountEntity), message.FromAccountId);
            var toAccountEntity   = new EntityId(nameof(AccountEntity), message.ToAccountId);

            using (await context.LockAsync(fromAccountEntity, toAccountEntity))
            {
                var fromAccountProxy = context.CreateEntityProxy <IAccountEntity>(fromAccountEntity);
                var toAccountProxy   = context.CreateEntityProxy <IAccountEntity>(toAccountEntity);

                await fromAccountProxy.Debit(new DebitAccountMessage(message.Amount));

                await toAccountProxy.Credit(new CreditAccountMessage(message.Amount));
            }
        }
예제 #11
0
        private void LogEmailSent(IDurableOrchestrationContext client, CommunicationSendRequest request)
        {
            var key = new EntityId(nameof(CommsTrackingEntity), request.PersonId.ToString());

            var proxy = client.CreateEntityProxy <ICommsTrackingEntity>(key);

            proxy.Track(request.UseCase.Id);
        }
        public static Task <List <LoanTransaction> > ListTransaction(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var input   = context.GetInput <object>() as dynamic;
            var account = input.account.Value as string;
            var loan    = context.CreateEntityProxy <ILoan>(account);

            return(loan.GetTransactionHistory());
        }
        public static async Task <decimal> GetBalance(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var input   = context.GetInput <object>() as dynamic;
            var account = input.account.Value as string;
            var loan    = context.CreateEntityProxy <ILoan>(account);

            return(await loan.GetBalance());
        }
예제 #14
0
        public static async Task <string> EnvironmentOrchestration([OrchestrationTrigger] IDurableOrchestrationContext ctx)
        {
            var environment = ctx.GetInput <EntityId>();

            var entityProxy = ctx.CreateEntityProxy <IEnvironment>(environment);

            // get current value
            return(await entityProxy.GetEnvironmentVariable(DummyEnvironmentVariable));
        }
예제 #15
0
        public static async Task <bool> BankTransaction([OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var iterationLength   = context.GetInput <Tuple <int, int> >();
            var targetAccountPair = iterationLength.Item1;
            var length            = iterationLength.Item2;

            var sourceAccountId = $"src{targetAccountPair}-!{(targetAccountPair + 1) % 32:D2}";
            var sourceEntity    = new EntityId(nameof(Account), sourceAccountId);

            var destinationAccountId = $"dst{targetAccountPair}-!{(targetAccountPair + 2) % 32:D2}";
            var destinationEntity    = new EntityId(nameof(Account), destinationAccountId);

            // Add an amount to the first account
            var transferAmount = 1000;

            IAccount sourceProxy =
                context.CreateEntityProxy <IAccount>(sourceEntity);
            IAccount destinationProxy =
                context.CreateEntityProxy <IAccount>(destinationEntity);

            // we want the balance check to always succeeed to reduce noise
            bool forceSuccess = true;

            // Create a critical section to avoid race conditions.
            // No operations can be performed on either the source or
            // destination accounts until the locks are released.
            using (await context.LockAsync(sourceEntity, destinationEntity))
            {
                int sourceBalance = await sourceProxy.Get();

                if (sourceBalance > transferAmount || forceSuccess)
                {
                    await sourceProxy.Add(-transferAmount);

                    await destinationProxy.Add(transferAmount);

                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }
예제 #16
0
        public static async Task <int> CounterOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var input = context.GetInput <CounterOrchestratorInput>();

            ICounter counter = context.CreateEntityProxy <ICounter>(input.EntityKey); // EntityId also works as parameter.

            // Two-way call to the entity which awaits the response value.
            return(await counter.Add(input.Amount));
        }
        public static void InitializeLoan(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var input   = context.GetInput <object>() as dynamic;
            var account = input.account.Value as string;
            var amount  = (decimal)input.amount.Value;
            var loan    = context.CreateEntityProxy <ILoan>(account);

            loan.InitializeLoan(amount);
        }
예제 #18
0
        public async Task <ProcessedNeoEvent> Run(
            [OrchestrationTrigger] IDurableOrchestrationContext context,
            ILogger logger)
        {
            var detectedNeoEvent = context.GetInput <DetectedNeoEvent>();

            var kineticEnergy = await context.CallActivityWithRetryAsync <KineticEnergyResult>(
                nameof(EstimateKineticEnergyActivity),
                GetRetryOptions(),
                detectedNeoEvent);

            var impactProbability = await context.CallActivityWithRetryAsync <ImpactProbabilityResult>(
                nameof(EstimateImpactProbabilityActivity),
                GetRetryOptions(),
                detectedNeoEvent);

            var torinoImpactRequest = TorinoImpactRequestBuilder.Build(
                detectedNeoEvent.Id,
                impactProbability.ImpactProbability,
                kineticEnergy.KineticEnergyInMegatonTnt);

            var torinoImpact = await context.CallActivityWithRetryAsync <TorinoImpactResult>(
                nameof(EstimateTorinoImpactActivity),
                GetRetryOptions(),
                torinoImpactRequest);

            var processedNeoEvent = ProcessedNeoEventBuilder.Build(
                detectedNeoEvent,
                impactProbability.ImpactProbability,
                kineticEnergy.KineticEnergyInMegatonTnt,
                torinoImpact.TorinoImpact);

            var proxy = context.CreateEntityProxy <IProcessedNeoEventCounter>(
                EntityIdBuilder.BuildForProcessedNeoEventCounter());

            proxy.Add();

            if (processedNeoEvent.TorinoImpact > 0)
            {
                await context.CallActivityWithRetryAsync(
                    nameof(StoreProcessedNeoEventActivity),
                    GetRetryOptions(),
                    processedNeoEvent);
            }

            if (processedNeoEvent.TorinoImpact > 7)
            {
                await context.CallActivityWithRetryAsync(
                    nameof(SendNotificationActivity),
                    GetRetryOptions(),
                    processedNeoEvent);
            }

            return(processedNeoEvent);
        }
    private static async Task <List <string> > ContactDurableEntity(
        IDurableOrchestrationContext context)
    {
        var            entity      = new EntityId(nameof(EntityExample), "myEntityKey");
        IEntityExample entityProxy = context.CreateEntityProxy <IEntityExample>(entity);

        entityProxy.AddEvent("my new event");                      // signal (don't wait) as return is void.
        List <string> result = await entityProxy.GetEventsAsync(); // signal (wait & return) as return is a task.

        return(result);
    }
        public async Task <bool> IsExecutionPermitted(string circuitBreakerId, ILogger log, IDurableOrchestrationContext orchestrationContext)
        {
            if (string.IsNullOrEmpty(circuitBreakerId))
            {
                throw new ArgumentNullException($"{nameof(circuitBreakerId)}");
            }

            log?.LogCircuitBreakerMessage(circuitBreakerId, $"Asking IsExecutionPermitted (consistency priority) for circuit-breaker = '{circuitBreakerId}'.");

            return(await orchestrationContext.CreateEntityProxy <IDurableCircuitBreaker>(circuitBreakerId).IsExecutionPermitted());
        }
예제 #21
0
        public static async Task <bool> WithdrawFun(
            [OrchestrationTrigger] IDurableOrchestrationContext ctx
            )
        {
            var input   = ctx.GetInput <WithdrawArgs>();
            var account = ctx.CreateEntityProxy <IAccount>(input.Account);

            var wasSuccessful = await account.Withdraw(input.Amount);

            return(wasSuccessful);
        }
예제 #22
0
        public async Task HealCheckOrchestration(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var service            = context.GetInput <ServiceInput>();
            var entityId           = new EntityId(nameof(ServiceAggregator), service.Id);
            var serviceProxy       = context.CreateEntityProxy <IServiceAggregator>(entityId);
            var httpClientResponse = await context.CallHttpAsync(HttpMethod.Get, new Uri(service.Url));

            var status = httpClientResponse.StatusCode == HttpStatusCode.OK ? Status.Closed : Status.Open;

            await serviceProxy.ChangeState(new StatusCommand(status));
        }
예제 #23
0
        public static async Task RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            InventoryEvent data = context.GetInput <InventoryEvent>();

            var entityId = new EntityId("Store", data.StoreId);
            var proxy    = context.CreateEntityProxy <IStore>(entityId);

            var itemInventory = await proxy.process(data);

            await context.CallActivityAsync <string>("MDSWrite", itemInventory);
        }
        public static void AddTransaction(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var input   = context.GetInput <object>() as dynamic;
            var account = input.account.Value as string;
            var amount  = (decimal)input.amount.Value;
            var loan    = context.CreateEntityProxy <ILoan>(account);

            loan.AddTransaction(new LoanTransaction {
                Amount = amount, TypeOfTransaction = TransactionType.Repay, TransactionTimeStamp = context.CurrentUtcDateTime
            });
        }
예제 #25
0
        public static async Task <bool> Run([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger logger)
        {
            var hostId = context.GetInput <EntityId>();

            logger = context.CreateReplaySafeLogger(logger);

            var state = await context.CallActivityAsync <EntityStateResponse <HostEntity> >(nameof(GetHostState), hostId);

            if (!state.EntityExists)
            {
                logger.LogError("Attempted to start watch dog for a non-existing host entity: {hostId}", hostId);
                throw new Exception("Failed to start watch dog for non-existing entity");
            }

            if (context.InstanceId != HostEntity.calculateHash(state.EntityState.IpAddress))
            {
                throw new Exception("violent suicide committed on watchdog!");
            }

            if (state.EntityState.ipv4Support || state.EntityState.ipv6Support)
            {
                context.SignalEntity(HostList.Id, HostList.AddHost, hostId);
                logger.LogInformation("Adding {hostId} to active hosts", hostId);
            }
            else
            {
                context.SignalEntity(HostList.Id, HostList.RemoveHost, hostId);
                logger.LogInformation("Removing {hostId} from active hosts", hostId);
            }

            var nextCheck = state.EntityState.DnsUptime switch
            {
                { } v when v < 0.2m => TimeSpan.FromDays(1),
                { } v when v >= 0.2m && v < 0.75m => TimeSpan.FromHours(12 + new Random().Next(-1, 1)),
                { } v when v >= 0.75m => TimeSpan.FromMinutes(60 + new Random().Next(-5, 5)),
                _ => TimeSpan.FromHours(1)
            };

#if DEBUG
            nextCheck = TimeSpan.FromMinutes(5);
#endif

            await context.CreateTimer(context.CurrentUtcDateTime + nextCheck, CancellationToken.None);

            var host = context.CreateEntityProxy <IHostEntity>(hostId);

            await host.CheckUp();

            context.ContinueAsNew(hostId);

            return(true);
        }
    }
        public static async Task TransferFundsAsync(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var transferCommand = context.GetInput <TransferCommand>();

            if (transferCommand == null)
            {
                return;
            }

            var source = new EntityId(nameof(BankAccountEntity), transferCommand.SourceAccountId);
            var target = new EntityId(nameof(BankAccountEntity), transferCommand.TargetAccountId);

            using (await context.LockAsync(source, target))
            {
                Console.WriteLine($"{transferCommand.SourceAccountId}: Locked");
                Console.WriteLine($"{transferCommand.TargetAccountId}: Locked");

                var sourceProxy = context.CreateEntityProxy <IBankAccountEntity>(source);
                if (await sourceProxy.GetBalanceAsync() < transferCommand.Amount)
                {
                    Console.WriteLine($"{transferCommand.SourceAccountId}: Is broke. Bouncing transfer.");
                    return;
                }

                var targetProxy = context.CreateEntityProxy <IBankAccountEntity>(target);

                await sourceProxy.ModifyBalanceAsync(-transferCommand.Amount);

                Console.WriteLine($"{transferCommand.SourceAccountId}: Taken amount out");
                await targetProxy.ModifyBalanceAsync(transferCommand.Amount);

                Console.WriteLine($"{transferCommand.TargetAccountId}: Added amount to");
            }

            Console.WriteLine($"{transferCommand.SourceAccountId}: Unlocked");
            Console.WriteLine($"{transferCommand.TargetAccountId}: Unlocked");
        }
        public async Task RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context,
            ILogger log)
        {
            _correlationInitializer.Initialize(context.InstanceId);
            await context.CallActivityAsync(nameof(StartReindex), null);

            var categoryIds =
                await context.CallActivityAsync <IReadOnlyCollection <string> >(nameof(ReadCategoriesToRebuild), null);

            var rebuildTasks =
                categoryIds.Select(id => context.CreateEntityProxy <ICategoryEntity>(id).Reindex());

            await Task.WhenAll(rebuildTasks);

            log.LogProgress(OperationStatus.InProgress, "Rebuild of events stored in event store finished", context.InstanceId);

            categoryIds =
                await context.CallActivityAsync <IReadOnlyCollection <string> >(nameof(ReadCategoriesToRebuild), null);


            var applyEventTasks =
                categoryIds.Select(id => context.CreateEntityProxy <ICategoryEntity>(id).ApplyPendingEvents());

            await Task.WhenAll(applyEventTasks);

            log.LogProgress(OperationStatus.InProgress, "Applied pending events", context.InstanceId);


            var deleteStateTasks =
                categoryIds.Select(id => context.CreateEntityProxy <ICategoryEntity>(id).Delete());

            await Task.WhenAll(deleteStateTasks);

            await context.CallActivityAsync(nameof(FinishReindex), null);

            log.LogProgress(OperationStatus.Finished, string.Empty, context.InstanceId);
        }
예제 #28
0
        public static async Task RunOrchestrator([OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var input = context.GetInput <AddItemToPlayerInventoryOrchestratorInput>();

            var playerEntityId = new EntityId(nameof(Player), input.Player);
            var itemEntityId   = new EntityId(nameof(ShopItem), input.Item);

            using (await context.LockAsync(playerEntityId, itemEntityId))
            {
                var playerProxy = context.CreateEntityProxy <IPlayer>(playerEntityId);
                var itemProxy   = context.CreateEntityProxy <IShopItem>(itemEntityId);

                var itemStock = await itemProxy.GetStock();

                await playerProxy.AddItemToInventory(new AddItemToInventoryParams
                {
                    Quantity = input.Quantity,
                    Item     = input.Item
                });

                await itemProxy.UpdateStock(itemStock - input.Quantity);
            }
        }
        public static async Task <IEnumerable <InventoryItem> > RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var userId = context.GetInput <string>();
            var target = new EntityId(nameof(ShoppingCartEntity), userId);

            var shoppingCartProxy = context.CreateEntityProxy <IShoppingCart>(target);
            var shoppingCart      = await shoppingCartProxy.GetItemsAsync();

            var tasks = shoppingCart
                        .Select(id => context
                                .CreateEntityProxy <IInventory>(new EntityId(nameof(InventoryEntity), "onestore"))
                                .GetItemAsync(id))
                        .ToList();

            await Task.WhenAll(tasks);

            var result = tasks
                         .Select(task => task.Result)
                         .ToList();

            return(result);
        }
        public static async Task StartComputeSetOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context,
            ILogger log)
        {
            log = context.CreateReplaySafeLogger(log);
            var computeSetId = context.GetInput <string>();

            log.LogWarning("*** {eventName}: {computeSetId}", "ComputeSetStarting", computeSetId);

            // pretend to start compute set
            await context.CreateTimer(context.CurrentUtcDateTime.AddSeconds(5), CancellationToken.None);

            var computeSet = context.CreateEntityProxy <IComputeSet>(new EntityId(nameof(ComputeSet), computeSetId));
            await computeSet.SignalComputeSetStarted();
        }