[52] | 1 | package geniusweb.protocol.session.mopac.phase;
|
---|
| 2 |
|
---|
| 3 | import java.util.List;
|
---|
| 4 |
|
---|
| 5 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
---|
| 6 | import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
|
---|
| 7 | import com.fasterxml.jackson.annotation.JsonSubTypes;
|
---|
| 8 | import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
---|
| 9 |
|
---|
| 10 | import geniusweb.actions.Action;
|
---|
| 11 | import geniusweb.actions.PartyId;
|
---|
| 12 | import geniusweb.inform.Inform;
|
---|
| 13 | import geniusweb.protocol.ProtocolException;
|
---|
| 14 | import geniusweb.protocol.session.mopac.PartyStates;
|
---|
| 15 | import geniusweb.voting.VotingEvaluator;
|
---|
| 16 |
|
---|
| 17 | /**
|
---|
| 18 | * A Phase is a part of the round structure. In each round parties have to take
|
---|
| 19 | * multiple actions. Each action is part of a phase.
|
---|
| 20 | *
|
---|
| 21 | * Invariant: A phase object handles negotiation events, ensuring that the
|
---|
| 22 | * events are handled according to the possible actions in this phase. A phase
|
---|
| 23 | * object must always remain in a consistent state. It does so by modifying the
|
---|
| 24 | * contained {@link PartyStates} as needed.
|
---|
| 25 | * <p>
|
---|
| 26 | * The standard exception handling is assumed: unchecked exceptions are thrown
|
---|
| 27 | * only if there is a bug in the protocol. Because none of the functions in this
|
---|
| 28 | * interface throws, any error must be either ignored or the party must be
|
---|
| 29 | * kicked.
|
---|
| 30 | */
|
---|
| 31 | @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
|
---|
| 32 | @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE)
|
---|
| 33 | @JsonSubTypes({ @JsonSubTypes.Type(value = OfferPhase.class),
|
---|
| 34 | @JsonSubTypes.Type(value = OptInPhase.class),
|
---|
| 35 | @JsonSubTypes.Type(value = VotingPhase.class) })
|
---|
| 36 | public interface Phase {
|
---|
| 37 | public static final Long PHASE_MAXTIME = 30000l; // 30sec
|
---|
| 38 | public static final Long PHASE_MINTIME = 100l; // 100 millisec
|
---|
| 39 |
|
---|
| 40 | /**
|
---|
| 41 | * Handle an actor's action. If a {@link ProtocolException} occurs, this is
|
---|
| 42 | * handled by updating the PartyStates
|
---|
| 43 | *
|
---|
| 44 | * @param actor the real actor (may differ from the actor contained in the
|
---|
| 45 | * action)
|
---|
| 46 | * @param action the action submitted by actor, which this phase can really
|
---|
| 47 | * handle.
|
---|
| 48 | * @param now the current time
|
---|
| 49 | * @return new Phase
|
---|
| 50 | */
|
---|
| 51 | public Phase with(PartyId actor, Action action, long now);
|
---|
| 52 |
|
---|
| 53 | /**
|
---|
| 54 | *
|
---|
| 55 | * @param e a {@link ProtocolException}
|
---|
| 56 | * @return new Phase with a party disabled because it violated a protocol eg
|
---|
| 57 | * breaking a websocket link.
|
---|
| 58 | */
|
---|
| 59 | public Phase with(ProtocolException e);
|
---|
| 60 |
|
---|
| 61 | /**
|
---|
| 62 | *
|
---|
| 63 | * @return the inform object to send to all parties at start of phase.
|
---|
| 64 | */
|
---|
| 65 | public Inform getInform();
|
---|
| 66 |
|
---|
| 67 | /**
|
---|
| 68 | *
|
---|
| 69 | * @param now the current time
|
---|
| 70 | * @return true iff past deadline or no more actions are allowed anyway.
|
---|
| 71 | * (which usually means, all parties have done exactly one act).
|
---|
| 72 | * Notice, this is the main reason that it is desirable to require
|
---|
| 73 | * all parties to act exactly once in each phase. Without such a
|
---|
| 74 | * rule, the protocol will always have to wait till the deadline.
|
---|
| 75 | */
|
---|
| 76 | public boolean isFinal(long now);
|
---|
| 77 |
|
---|
| 78 | /**
|
---|
| 79 | *
|
---|
| 80 | * @return finished state. That means, all parties that did not act have
|
---|
| 81 | * been kicked, new agreements have been computed, etc.
|
---|
| 82 | */
|
---|
| 83 | public Phase finish();
|
---|
| 84 |
|
---|
| 85 | /**
|
---|
| 86 | * Determines the next phase. Resets the actions field. Can only be called
|
---|
| 87 | * after {@link #finish()}
|
---|
| 88 | *
|
---|
| 89 | * @param now the current time
|
---|
| 90 | * @param duration the max duration (ms) of the next phase. Must be between
|
---|
| 91 | * {@link #PHASE_MINTIME} and {@link #PHASE_MAXTIME}. Also
|
---|
| 92 | * make sure that now+duration is at most at the total
|
---|
| 93 | * negotiation deadline.
|
---|
| 94 | * @return the next phase, or null if negotiation is complete.
|
---|
| 95 | */
|
---|
| 96 | public Phase next(long now, long duration);
|
---|
| 97 |
|
---|
| 98 | /**
|
---|
| 99 | * @return the voting evaluator
|
---|
| 100 | */
|
---|
| 101 | public VotingEvaluator getEvaluator();
|
---|
| 102 |
|
---|
| 103 | /**
|
---|
| 104 | *
|
---|
| 105 | * @return time (ms since 1970) at which phase ends. The phase may end
|
---|
| 106 | * before, but never after this.
|
---|
| 107 | */
|
---|
| 108 | public long getDeadline();
|
---|
| 109 |
|
---|
| 110 | /**
|
---|
| 111 | * @return the party states. Notice that someone must call
|
---|
| 112 | * {@link PartyStates#finish()} if passed the deadline.
|
---|
| 113 | */
|
---|
| 114 | public PartyStates getPartyStates();
|
---|
| 115 |
|
---|
| 116 | /**
|
---|
| 117 | * @return the allowed actinos in this phase
|
---|
| 118 | */
|
---|
| 119 | public abstract List<Class<? extends Action>> getAllowedActions();
|
---|
| 120 |
|
---|
| 121 | }
|
---|