-
Notifications
You must be signed in to change notification settings - Fork 83
Group & Submission Consistency
John DeNero edited this page Jan 13, 2015
·
1 revision
Invariants:
- Every person is either not in a group,
pending
in exactly 1 group, oractive
in exactly 1 group. - Every group has at least 1
active
member; empty groups are deleted. - Every group has at least 2
active
orpending
members; 1-person groups are deleted.
Permitted actions:
- An active member can add a new pending member (make invitation).
- A pending member can only accept or reject the invitation to join the group. (accept invitation) [A pending member cannot be invited to another group, create a group, or invite someone else to a group.]
- An active member can remove a pending member (cancel invitation).
- An active/pending member can leave a group (leave group or reject invitation).
- A person not in a group can create a new group by adding a new pending member.
- An active/pending member can see all active/pending members of the group.
- An active member can see all active members' submissions.
- An active member can select the final submission of the group.
Submissions:
- Whenever a new active member is added to a group, the group final submission is updated to the most recent submission of any active member of the group.
- Whenever the final submission of a person changes, that person should be notified with a link to the new final submission. This can occur because (a) they joined a group with a more recent final submission than theirs, or (b) someone else joined their group with a more recent final submission than the group's current final submission.
Enforcing invariants:
- When inviting someone to a group, that invitation may fail because the target is already active/pending in another group, the group is too big, or the inviter is pending. A complete invitation transaction is:
- [person A invites person B]
- [concurrency lock A]
- [check that A is not pending in any group]
- [if A is not in a group, create group G_A with A as an active member]
- [unlock A]
- [concurrency lock G_A (group containing A)]
- [check that G_A has capacity for another member]
- [concurrency lock B]
- [check that B is not pending or active]
- [add B as pending member of G_A]
- [unlock B]
- [if G_A has only 1 member (because adding B failed), delete G_A]
- [unlock G_A]
- When B accepts an invitation to group G_A:
- [concurrency lock G_A]
- [check that B is a pending member of G_A]
- [move B from pending to active in G_A]
- [unlock G_A]
- When A cancels an invitation to B for group G_A:
- [concurrency lock B]
- [concurrency lock G_A]
- [check that B is a pending member of G_A]
- [remove B from pending members of G_A]
- [unlock G_A]
- [unlock B]
- When A rejects or leaves G_A:
- [concurrency lock A]
- [concurrency lock G_A]
- [remove A from active and pending members of G_A]
- [unlock G_A]
- [unlock A]