MartinWinchester / Booking

1 stars 0 forks source link

Implement 2 phase transaction for Booking journey #12

Open peterrefila opened 3 years ago

peterrefila commented 3 years ago

Coordinator (first server contacted with request by a user) When a server receives a request to book a journey from point A to B (from endpoint: Post URL/book):

Verify that request is valid: not in past, required parameters supplied, (not double booked)

Find shortest path using utils.find_shortest_path (make sure in memory distance matrix is up to date (this can be done in parallel with running the shortest path algorithm, if new map is fetched re-run shortest path algorithm, if not use the previously found result)), results in an array of nodes (cities)

Find servers responsible for nodes

Prepared state

In log file record [“prepared”, JID, servers,1]

Since transaction coordinators depend only on who the first server contacted was on recovery the 1 signifies that this server is coordinator

Usually for 2PC the logs would have enough information to redo transaction but we will just abort if coordinator failed while in prepared state

Only 1 log file with only latest transaction necessary? Can overwrite with new transaction?

If a trip is in coordinators node: see Participant

Send these servers requests to start transaction to book trips (back channel endpoint responsible for 2 phase transaction)

All trips that a specific server is responsible for should be delivered in the same request i.e. if server responsible for D and F on journey [A, B, C, D, E, F, G], the same request should include trips D->E and F->G

If all servers vote yes Commit state

In log file record [“commit”, JID, servers,1]

Don't need servers but make implementation easier

Send commit message to servers, start timer(s)

If any timeout, re-transmit commit message

When receive acknowledgements in log file record [“done”, JID]

(update global UID-JID DB?)

If any servers vote no Abort state

In log file record [“Abort”, JID, servers,1]

Send commit message to servers, start timer(s)

If any timeout, re-transmit abort message

When receive acknowledgements in log file record [“done”, JID]

Participant When a server receives a request to book a trip from point A to B (from back channel endpoint):

(Lock own DB)

Find out if A is at capacity

If so Abort state

In log file record [“Abort”, JID, coordinator]

(release lock on own DB)

reply abort

If not Prepared state

start timer

In log file record [“Prepared”, JID, trip info, coordinator]

if timeout go to Abort state

If coordinator sends commit message Commit state

In log file record [“Commit”, JID, trip info, coordinator]

Commit trip to own DB

(release lock on own DB)

Reply ACK

If coordinator sends abort message go to Abort state

Notes:

in final implementation fetching servers from journey, journeys from user might not be done using global UID-JID DB

might not be very efficient: have to wait from beginning of transaction till everyone done to be able to start new transaction

on (re)start server should check for any outstanding transactions

Questions:

On recovery avoid recommitting same trip (JID in logs, messages enough?)

DB locked but node lost how is lock recovered?

out of the box 2PC implementation?

How to handle if nodes are being reassigned to new city after T started? Should server contacted (A) act as intermediary to server actually responsible (B) (such that B thinks A the coordinator, real coordinator thinks A participant, A forwards all messages between coordinator and B) or just abort?