Beispiel #1
0
        public override async Task <AssignDeploymentsResponse> AssignDeployments(AssignDeploymentsRequest request,
                                                                                 ServerCallContext context)
        {
            try
            {
                using (var memClient = _matchmakingMemoryStoreClientManager.GetClient())
                {
                    var toUpdate = new List <Entry>();
                    foreach (var assignment in request.Assignments)
                    {
                        Reporter.AssignDeploymentInc(assignment.DeploymentId, assignment.Result);
                        foreach (var memberId in assignment.Party.MemberIds)
                        {
                            var playerJoinRequest = await memClient.GetAsync <PlayerJoinRequest>(memberId);

                            if (playerJoinRequest == null)
                            {
                                continue;
                            }
                            switch (assignment.Result)
                            {
                            case Assignment.Types.Result.Error:
                                playerJoinRequest.State = MatchState.Error;
                                break;

                            case Assignment.Types.Result.Matched:
                                playerJoinRequest.AssignMatch(assignment.DeploymentId, assignment.DeploymentName);
                                break;

                            case Assignment.Types.Result.Requeued:
                                playerJoinRequest.State = MatchState.Requested;
                                break;
                            }

                            toUpdate.Add(playerJoinRequest);
                        }
                    }

                    var toRequeue = new List <PartyJoinRequest>();
                    var toDelete  = new List <PartyJoinRequest>();

                    foreach (var assignment in request.Assignments)
                    {
                        var party            = assignment.Party;
                        var partyJoinRequest = await memClient.GetAsync <PartyJoinRequest>(party.Id);

                        if (partyJoinRequest == null)
                        {
                            // Party join request has been cancelled.
                            continue;
                        }
                        if (assignment.Result == Assignment.Types.Result.Requeued)
                        {
                            partyJoinRequest.RefreshQueueData();
                            toRequeue.Add(partyJoinRequest);
                            toUpdate.Add(partyJoinRequest);
                        }
                        else
                        {
                            // If the matchmaking process for this party has reached a final state, we should delete the
                            // PartyJoinRequest associated to it.
                            toDelete.Add(partyJoinRequest);
                        }
                    }

                    using (var tx = memClient.CreateTransaction())
                    {
                        tx.UpdateAll(toUpdate);
                        tx.EnqueueAll(toRequeue);
                        tx.DeleteAll(toDelete);
                    }
                }
            }
            catch (EntryNotFoundException e)
            {
                Reporter.AssignDeploymentNotFoundInc(e.Id);
                Log.Warning($"Attempted to assign deployment to nonexistent join request {e.Id}.");
                throw new RpcException(new Status(StatusCode.NotFound, "Join request does not exist"));
            }
            catch (TransactionAbortedException)
            {
                Reporter.TransactionAbortedInc("AssignDeployments");
                Log.Warning("Transaction aborted during deployment assignment.");
                throw new RpcException(new Status(StatusCode.Unavailable,
                                                  "assignment aborted due to concurrent modification; safe to retry"));
            }

            return(new AssignDeploymentsResponse());
        }
        public override async Task <AssignDeploymentsResponse> AssignDeployments(AssignDeploymentsRequest request,
                                                                                 ServerCallContext context)
        {
            try
            {
                using (var memClient = _matchmakingMemoryStoreClientManager.GetClient())
                {
                    var toUpdate = new List <Entry>();
                    foreach (var assignment in request.Assignments)
                    {
                        Reporter.AssignDeploymentInc(assignment.DeploymentId, assignment.Result);
                        foreach (var memberId in assignment.Party.MemberIds)
                        {
                            var playerJoinRequest = await memClient.GetAsync <PlayerJoinRequest>(memberId);

                            if (playerJoinRequest == null)
                            {
                                continue;
                            }
                            switch (assignment.Result)
                            {
                            case Assignment.Types.Result.Error:
                                playerJoinRequest.State = MatchState.Error;
                                break;

                            case Assignment.Types.Result.Matched:
                                playerJoinRequest.AssignMatch(assignment.DeploymentId, assignment.DeploymentName);
                                break;

                            case Assignment.Types.Result.Requeued:
                                playerJoinRequest.State = MatchState.Requested;
                                break;
                            }

                            toUpdate.Add(playerJoinRequest);
                        }
                    }

                    var toRequeue = new List <PartyJoinRequest>();
                    var toDelete  = new List <PartyJoinRequest>();

                    foreach (var assignment in request.Assignments)
                    {
                        var party            = assignment.Party;
                        var partyJoinRequest = await memClient.GetAsync <PartyJoinRequest>(party.Id);

                        if (partyJoinRequest == null)
                        {
                            // Party join request has been cancelled.
                            continue;
                        }

                        var eventAttributes = new Dictionary <string, string>
                        {
                            { "partyId", partyJoinRequest.Id },
                            { "matchRequestId", partyJoinRequest.MatchRequestId },
                            { "queueType", partyJoinRequest.Type },
                            { "partyPhase", partyJoinRequest.Party.CurrentPhase.ToString() }
                        };

                        if (assignment.Result == Assignment.Types.Result.Matched)
                        {
                            toDelete.Add(partyJoinRequest);

                            eventAttributes.Add("spatialProjectId", _project);
                            eventAttributes.Add("deploymentName", assignment.DeploymentName);
                            eventAttributes.Add("deploymentId", assignment.DeploymentId);
                            _analytics.Send("party_matched", eventAttributes, partyJoinRequest.Party.LeaderPlayerId);
                        }
                        else if (assignment.Result == Assignment.Types.Result.Requeued)
                        {
                            partyJoinRequest.RefreshQueueData();
                            toRequeue.Add(partyJoinRequest);
                            toUpdate.Add(partyJoinRequest);
                            _analytics.Send("party_requeued", eventAttributes, partyJoinRequest.Party.LeaderPlayerId);
                        }
                        else if (assignment.Result == Assignment.Types.Result.Error)
                        {
                            toDelete.Add(partyJoinRequest);
                            _analytics.Send("party_error", eventAttributes, partyJoinRequest.Party.LeaderPlayerId);
                        }
                        else
                        {
                            toDelete.Add(partyJoinRequest);
                        }
                    }

                    using (var tx = memClient.CreateTransaction())
                    {
                        tx.UpdateAll(toUpdate);
                        tx.EnqueueAll(toRequeue);
                        tx.DeleteAll(toDelete);
                    }

                    foreach (var playerJoinRequest in toUpdate.OfType <PlayerJoinRequest>())
                    {
                        var eventAttributes = new Dictionary <string, string>
                        {
                            { "partyId", playerJoinRequest.PartyId },
                            { "matchRequestId", playerJoinRequest.MatchRequestId },
                            { "queueType", playerJoinRequest.Type },
                            { "playerJoinRequestState", playerJoinRequest.State.ToString() }
                        };

                        switch (playerJoinRequest.State)
                        {
                        case MatchState.Matched:
                            eventAttributes.Add("spatialProjectId", _project);
                            eventAttributes.Add("deploymentName", playerJoinRequest.DeploymentName);
                            eventAttributes.Add("deploymentId", playerJoinRequest.DeploymentId);
                            _analytics.Send("player_matched", eventAttributes, playerJoinRequest.Id);
                            break;

                        case MatchState.Requested:
                            _analytics.Send("player_requeued", eventAttributes, playerJoinRequest.Id);
                            break;

                        case MatchState.Error:
                            _analytics.Send("player_error", eventAttributes, playerJoinRequest.Id);
                            break;
                        }
                    }
                }
            }
            catch (EntryNotFoundException e)
            {
                Reporter.AssignDeploymentNotFoundInc(e.Id);
                Log.Warning($"Attempted to assign deployment to nonexistent join request {e.Id}.");
                throw new RpcException(new Status(StatusCode.NotFound, "Join request does not exist"));
            }
            catch (TransactionAbortedException)
            {
                Reporter.TransactionAbortedInc("AssignDeployments");
                Log.Warning("Transaction aborted during deployment assignment.");
                throw new RpcException(new Status(StatusCode.Unavailable,
                                                  "assignment aborted due to concurrent modification; safe to retry"));
            }

            return(new AssignDeploymentsResponse());
        }