package geniusweb.protocol.session.mopac.phase; import java.util.List; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import geniusweb.actions.Action; import geniusweb.actions.PartyId; import geniusweb.inform.Inform; import geniusweb.protocol.ProtocolException; import geniusweb.protocol.session.mopac.PartyStates; import geniusweb.voting.VotingEvaluator; /** * A Phase is a part of the round structure. In each round parties have to take * multiple actions. Each action is part of a phase. * * Invariant: A phase object handles negotiation events, ensuring that the * events are handled according to the possible actions in this phase. A phase * object must always remain in a consistent state. It does so by modifying the * contained {@link PartyStates} as needed. *
* The standard exception handling is assumed: unchecked exceptions are thrown
* only if there is a bug in the protocol. Because none of the functions in this
* interface throws, any error must be either ignored or the party must be
* kicked.
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE)
@JsonSubTypes({ @JsonSubTypes.Type(value = OfferPhase.class),
@JsonSubTypes.Type(value = OptInPhase.class),
@JsonSubTypes.Type(value = VotingPhase.class) })
public interface Phase {
public static final Long PHASE_MAXTIME = 30000l; // 30sec
public static final Long PHASE_MINTIME = 100l; // 100 millisec
/**
* Handle an actor's action. If a {@link ProtocolException} occurs, this is
* handled by updating the PartyStates
*
* @param actor the real actor (may differ from the actor contained in the
* action)
* @param action the action submitted by actor, which this phase can really
* handle.
* @param now the current time
* @return new Phase
*/
public Phase with(PartyId actor, Action action, long now);
/**
*
* @param e a {@link ProtocolException}
* @return new Phase with a party disabled because it violated a protocol eg
* breaking a websocket link.
*/
public Phase with(ProtocolException e);
/**
*
* @return the inform object to send to all parties at start of phase.
*/
public Inform getInform();
/**
*
* @param now the current time
* @return true iff past deadline or no more actions are allowed anyway.
* (which usually means, all parties have done exactly one act).
* Notice, this is the main reason that it is desirable to require
* all parties to act exactly once in each phase. Without such a
* rule, the protocol will always have to wait till the deadline.
*/
public boolean isFinal(long now);
/**
*
* @return finished state. That means, all parties that did not act have
* been kicked, new agreements have been computed, etc.
*/
public Phase finish();
/**
* Determines the next phase. Resets the actions field. Can only be called
* after {@link #finish()}
*
* @param now the current time
* @param duration the max duration (ms) of the next phase. Must be between
* {@link #PHASE_MINTIME} and {@link #PHASE_MAXTIME}. Also
* make sure that now+duration is at most at the total
* negotiation deadline.
* @return the next phase, or null if negotiation is complete.
*/
public Phase next(long now, long duration);
/**
* @return the voting evaluator
*/
public VotingEvaluator getEvaluator();
/**
*
* @return time (ms since 1970) at which phase ends. The phase may end
* before, but never after this.
*/
public long getDeadline();
/**
* @return the party states. Notice that someone must call
* {@link PartyStates#finish()} if passed the deadline.
*/
public PartyStates getPartyStates();
/**
* @return the allowed actinos in this phase
*/
public abstract List