jbholden / cdcpool_google

0 stars 1 forks source link

Do we need memcache locks? #18

Open blreams opened 10 years ago

blreams commented 10 years ago

I was thinking some more about the race condition that was discussed in Issue #10. Basically, we had the following scenario:

Pooler P:

  1. Gets the current pick sheet (call it revision 1).
  2. Submits her picks based on pick sheet revision 1.

In parallel, Commissioner C:

  1. Gets the current pick sheet (revision 1) and modifies it to revision 2.
  2. Submits pick sheet revision 2 to the database.

Now these four events can interleave in six possible ways (there are 3 ways in which P1 occurs first and there are 3 ways in which C1 occurs first):

P1->P2->C1->C2:

P1->C1->P2->C2:

P1->C1->C2->P2:

C1->C2->P1->P2:

C1->P1->C2->P2:

C1->P1->P2->C2:

I think the key to handling this correctly lies in treating memcache as the locking mechanism and doing the database updates after the lock is resolved by memcache.

I still need to think about this some more, though...would appreciate any insights that you have.

jbholden commented 10 years ago

This post addresses what I think the end behavior should be (comments in code boxes.)

P1->P2->C1->C2:

Brent:  The end result of this case would be that you live with the current spread value?

P1->C1->P2->C2:

Brent:  The end result of this case would be that you live with the current spread value?

P1->C1->C2->P2:

Brent:  The end result of this case would be that the spread change succeeds 
and when the pooler tries to enter their picks they get an error message say to repick.

C1->C2->P1->P2:

Brent:  Agree.  No issue.

C1->P1->C2->P2:

Brent:  The end result of this case would be that the spread change succeeds 
and when the pooler tries to enter their picks they get an error message saying to repick.

C1->P1->P2->C2:

C2 must check for any successful P2 picks. C2 will not succeed.

Brent:  The end result of this case would be that you live with the current spread value?
jbholden commented 10 years ago

This post is a proposed solution (you may already be thinking like this with the memcache lock)

code change summary (commissioner)

code change summary (pooler GET picks request)

code change summary (pooler POST picks)

P1->P2->C1->C2 (Byron)

P1->P2->C1->C2 (Brent)

P1->C1->P2->C2 (Byron)

\ adding a c_lock step indicating the setting of the lock

P1->C1->C_lock->P2->C2 (Brent)

P1->C1->P2->C_lock->C2 (Brent)

P1->C1->C2->P2 (Byron):

P1->C1->C2->P2 (Brent):

C1->C2->P1->P2 (Byron):

C1->C2->P1->P2 (Brent):

C1->P1->C2->P2 (Byron):

C1->C_lock->P1->C2->P2 (Brent version 1):

C1->P1->c_lock->C2->P2 (Brent version 2):

C1->P1->P2->C2 (Byron):

C1->c_lock->P1->P2->C2 (Brent version 1):

C1->P1->c_lock->P2->C2 (Brent version 2):

blreams commented 10 years ago

I've been doing some more thinking about this and here is what I've come up with:

I'm going to add a new field to the Week table (probably call it block_picks and it will be a boolean). Basically, when this boolean is True, no picks will be accepted to the DB corresponding to that week. This will serve as the lock mentioned above. Anytime a pooler submits picks (either initial picks or edited picks), this boolean will be checked for the corresponding week. If block_picks is True, then the submitted picks will be rejected.

In Issue #6 we talked about having a week state (Invalid, Open, Locked). I'm not sure we need that anymore. The state is still a valid concept, but can be determined implicitly as follows:

  1. Invalid (a week is invalid if it doesn't exist in the Week table)
  2. Open (a week is open if it exists in the Week table and block_picks is False)
  3. Locked (a week is locked if it exists in the Week table and block_picks is True)

There will be at least two cases where we set block_picks for a week:

  1. A commissioner is submitting an edited pick sheet.
  2. The pick deadline has passed and no more picks will be accepted for the given week.

For completeness, I've documented all the race conditions noted above in an excel spreadsheet. In my next commit of my development branch, I will include a top level "docs" directory and will add this spreadsheet.

jbholden commented 10 years ago

I have been thinking about the overall state of the pool for which I will open a new issue.