-
-
Save aLekSer/655c43bd622199c4752bd77a6b1180d6 to your computer and use it in GitHub Desktop.
aLekSer
commented
Oct 14, 2020
Sean's comment : A numbered list of steps would make it a little easier to understand. I still don't think the Backfill ticket should contain the list of tickets, but I might not fully understand. I think that after a Backfill ticket is created, it contains the server's IP and port (one way to populate this is to have the Backfill ticket ID in the Match that the Director receives, and the Director calls an API to populate the connection data after the Match gets a server), and the number of spots that need to be filled. The 2nd time the MMF runs, when it finds a Match that would fulfill the Backfill ticket, it will add the Backfill ticket ID to the Match. When the Match proposals are coming back to the Backend, the Backend can update the Backfill ticket and go through the assignment process for those tickets.
As a side note, the original Match that is created will also have the Backfill ticket ID in it as well. It will be added by the Backend after the Backend creates the Backfill ticket. Then the Director can pass that information on to the Game Server, so it can update the ticket if needed.
BF Ticket has properties like : remaining Number of open slots and searchFields to be used to show up in results of filter by MatchProfile pools.
M1 = {T1, BF1} M2 = {T2, BF1} - Evaluator would leave only M1 or M2.
M1 = {T1} + extensions {BF1 ID} or add to match a new field.
I added a few things to the sequence diagram. Please review.
sequenceDiagram
participant Player
participant GS
participant MMF
participant Director
participant OpenMatchCore
participant Backfill
Player->>OpenMatchCore: Create Ticket T1 (skill 10)
Director ->> + OpenMatchCore: FetchMatches
OpenMatchCore->>+MMF: Run
MMF->>+OpenMatchCore: Query Tickets
OpenMatchCore->>-MMF: Return ticket T1: Match is not full
MMF->>-OpenMatchCore: Return Match with T1<br/> Add BF Ticket creation info to Match
OpenMatchCore->>+Backfill: Create BF-Ticket<br/> Put average skill (10) as searchfield (optional)
Note right of Backfill: BF-Ticket contains: <br/>-Current/Desired number of players<br/>-SearchFields
Backfill->>-OpenMatchCore: BF-Ticket ID: BF1
Note left of OpenMatchCore: Update Match object new members:<br/>BackfillTicketID: BF1<br/>Allocated: false
OpenMatchCore ->> - Director: Match (partially filled)
Note right of Director: if !Match.Allocated, Director allocates
Director ->> GS: Allocate GS with BF-Ticket ID
Note right of Director: Add new member to AssignmentGroup:<br/>BackfillTicketID: BF1
Director ->> OpenMatchCore: Assign(assignments: [{ticket_ids:[T1], assignment:"ip:port", backfillID: BF1}])
OpenMatchCore->>+Backfill: Get(bfTicketID: string)
Backfill->>-OpenMatchCore: Ticket BF1
Note right of OpenMatchCore: OpenMatchCore will see no IP:Port on BF1, so will add it
OpenMatchCore->>Backfill: Assign(bfTicketID: string, assignment: string)
opt
GS -x OpenMatchCore: Remove BF Ticket
end
Player ->> OpenMatchCore: Fetch ConnInfo
Player ->> GS: Connect using ConnInfo
Note over Player: Next Iteration (Player2)
Player->>OpenMatchCore: Create Ticket T2 (skill 18)
Director ->> +OpenMatchCore: Fetch matches
OpenMatchCore->>+MMF: Run
MMF->>+OpenMatchCore: Get Tickets with Skill < 20
OpenMatchCore->>-MMF: Retrieve two tickets (BF1 and new T2)
Note over MMF: Received 1 BF-Ticket and 1 regular T2
MMF->> -OpenMatchCore: Match(tickets: [T2], backfillTicketID: BF1, backfillCreateParams: {}, allocated: True)
OpenMatchCore ->> - Director: Match(tickets: [T2], backfillTicketID: BF1, backfillCreateParams: {}, allocated: True)
Director -x GS: Notify GS about new match & players using current BF1 id
Director ->> OpenMatchCore: Assign(assignments: [{ticket_ids:[T2], assignment:"ip:port", backfillID: BF1}])
OpenMatchCore->>+Backfill: Get(bfTicketID: string)
Backfill->>-OpenMatchCore: Ticket BF1
Note right of OpenMatchCore: OpenMatchCore will see IP:Port on BF1, so will just change open slot count<br/>and search fields
OpenMatchCore->>Backfill: Update(bfTicket: BFTicket)
Player ->> OpenMatchCore: Fetch ConnInfo
Player ->> GS: Connect using ConnInfo
opt
GS ->> OpenMatchCore: Update BF1, set available slots to N (N - number of players)
end
opt
GS ->> OpenMatchCore: Remove BF-Ticket before shutdown
end
opt
GS ->> OpenMatchCore: Create BF-Ticket again when GS is waiting for new players
end
Thanks for an updated, applied your version to this gist as revision 5.
As I see here you introduced a change to Assign operation which now will holds a new BackfillID argument, in that way we can do both operations in one place.
A new version proposed by @scosgrave , revision 6
This revision tries to solve the problem of having a second or third round of match making complete prior to the first one getting an allocated game server. This situation might happen if game server allocation happens asynchronously to match making.
One potential issue with this flow is that it breaks one of the properties of the Director. Usually the Director knows which tickets have been assigned because it is the one calling AssignTickets, but in this flow, if a 2nd match making round completed before the allocation happened, then the Backfill service calls AssignTickets on the tickets that are in the unassignedTicket array. The Director has no idea that those tickets have been assigned. It could find out that they were assigned if it called WatchAssignments on tickets that were in the unassignedTickets array, but that would require the Director to create a go-routine per unassignedTicket, which doesn't scale well. It would be better if the Director's domain name, or IP, and port were sent in with the FetchMatches request, and saved with the Backfill ticket. Then the Backfill service could call an API on each Director associated with the Backfill ticket, to notify the Director that these tickets were assigned.
A second option could be the create a new API on the FrontEnd called WatchManyAssignments which could get the assignments for many tickets with one request. This might cut down on the number of go-routines watching assignments from the Director, but again, it is also possible it could degenerate into a single go-routine per ticket.
I don't think trying to watch the tickets from the Director is going to work. I think the most efficient approach is going to be having the Backfill or OpenMatch Backend notify the Director that a ticket, or tickets, have been assigned. Or, we need to come up with a different flow.
One more note about the last sequence diagram that was posted.
When Matches are returned to the Director, we should always populate the new tickets that were added to the Backfill in the tickets slice. The reason for this is the Director can't tell which tickets in the unassignedTickets array were most recently added. If we put the newly added tickets in the tickets member, then the Director can tell the newly added tickets from the existing ones in the unassignedTickets slice on the Backfill ticket.
Based on this idea, here are some example responses to the Director, and their meaning:
Tickets T1, and T2 were matched together, but the match is not full, so a Backfill Ticket was created. This is the first time any tickets have been associated with this Match, so needsAssignment is True, and the Director should allocate a game server for the Match:
Match(tickets: [T1, T2], backfillTicket{ID: BF1, needsAssignment: True, unassignedTickets[]})
Ticket T3 and T4 were added to the Backfill Ticket, but the game server allocation for the match hasn't completed yet, so they were added to the unassignedTickets slice:
Match(tickets: [T3, T4], backfillTicket{ID: BF1, needsAssignment: False, unassignedTickets[T3, T4]})
Tickets T5 and T6 matched into this Backfill Ticket, but the game server allocation for the match hasn't completed yet, so they were added to the unassignedTickets slice:
Match(tickets: [T5, T6], backfillTicket{ID: BF1, needsAssignment: False, unassignedTickets[T3, T4, T5, T6]})
Tickets T7 and T8 matched into this Backfill Ticket. The game server allocation has already happened, so the Director should be able to get the connection info from the Backfill Ticket, and call AssignTickets right away without doing any game server allocation:
Match(tickets: [T7, T8], backfillTicket{ID: BF1, needsAssignment: False, unassignedTickets[]})
Made a new diagram (rev 7), updating current gist.
The idea here is that Director always would perform assignments.
It can skip the backfill ticket for some reason, so it can have more options how to treat unassigned_tickets. He can use some of them for instance, and UpdateBFTicket with the rest, so later on for example on delete all UnassignedTickets could be returned to the pool of tickets. This way we don't have the only one implementation contained inside OM Core.