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()); }