1 | package geniusweb.protocol.tournament.allpermutations;
|
---|
2 |
|
---|
3 | import java.util.List;
|
---|
4 | import java.util.logging.Level;
|
---|
5 |
|
---|
6 | import geniusweb.events.ProtocolEvent;
|
---|
7 | import geniusweb.events.TournamentStarted;
|
---|
8 | import geniusweb.protocol.CurrentNegoState;
|
---|
9 | import geniusweb.protocol.partyconnection.ProtocolToPartyConnFactory;
|
---|
10 | import geniusweb.protocol.session.SessionProtocol;
|
---|
11 | import geniusweb.protocol.session.SessionResult;
|
---|
12 | import geniusweb.protocol.session.SessionSettings;
|
---|
13 | import geniusweb.protocol.session.SessionState;
|
---|
14 | import geniusweb.protocol.tournament.TournamentProtocol;
|
---|
15 | import geniusweb.protocol.tournament.TournamentState;
|
---|
16 | import geniusweb.references.PartyWithProfile;
|
---|
17 | import geniusweb.references.ProtocolRef;
|
---|
18 | import tudelft.utilities.listener.DefaultListenable;
|
---|
19 | import tudelft.utilities.logging.Reporter;
|
---|
20 |
|
---|
21 | /**
|
---|
22 | * This protocol creates sequentially all permutations of available parties and
|
---|
23 | * profiles. Only 1 session is run at a time because managing multiple sessions
|
---|
24 | * is more complex to manage in the {@link TournamentState}
|
---|
25 | *
|
---|
26 | */
|
---|
27 | public class AllPermutationsProtocol extends DefaultListenable<ProtocolEvent>
|
---|
28 | implements TournamentProtocol {
|
---|
29 | private static final ProtocolRef APP = new ProtocolRef("APP");
|
---|
30 | private final transient Reporter log;
|
---|
31 |
|
---|
32 | private ProtocolToPartyConnFactory connectionFactory; // FINAL
|
---|
33 | private AllPermutationsState state; // MUTABLE
|
---|
34 |
|
---|
35 | /**
|
---|
36 | *
|
---|
37 | * @param state the {@link AllPermutationsState}
|
---|
38 | * @param logger used for all logging, about the tournament, and the created
|
---|
39 | * the session and protocols.
|
---|
40 | */
|
---|
41 | public AllPermutationsProtocol(AllPermutationsState state,
|
---|
42 | Reporter logger) {
|
---|
43 | this.state = state;
|
---|
44 | this.log = logger;
|
---|
45 | }
|
---|
46 |
|
---|
47 | @Override
|
---|
48 | public void start(ProtocolToPartyConnFactory connectionfactory) {
|
---|
49 | this.connectionFactory = connectionfactory;
|
---|
50 | notifyListeners(new TournamentStarted(state.getSize().longValue()));
|
---|
51 | startNextSession();
|
---|
52 | }
|
---|
53 |
|
---|
54 | /**
|
---|
55 | * Start the next session in a new thread. Using a new thread ensures that
|
---|
56 | * all calls to this return immediately.
|
---|
57 | */
|
---|
58 | private void startNextSession() {
|
---|
59 | new Thread(new Runnable() {
|
---|
60 |
|
---|
61 | @Override
|
---|
62 | public void run() {
|
---|
63 | log.log(Level.INFO,
|
---|
64 | "Tournament " + this + " starting next session ");
|
---|
65 | SessionSettings settings = state.getNextSettings();
|
---|
66 | SessionProtocol sessionprotocol = settings.getProtocol(log);
|
---|
67 | sessionprotocol.addListener(evt -> sessionEvent(evt));
|
---|
68 | sessionprotocol.start(connectionFactory);
|
---|
69 | }
|
---|
70 | }).start();
|
---|
71 | }
|
---|
72 |
|
---|
73 | /**
|
---|
74 | * Called when the session completed.
|
---|
75 | *
|
---|
76 | * @param data the ProtocolEvent data,
|
---|
77 | */
|
---|
78 | private void sessionEvent(ProtocolEvent data) {
|
---|
79 | if (data instanceof CurrentNegoState) {
|
---|
80 | SessionState sessionstate = (SessionState) ((CurrentNegoState) data)
|
---|
81 | .getState();
|
---|
82 | long now = System.currentTimeMillis();
|
---|
83 | if (sessionstate.isFinal(now)) {
|
---|
84 | List<SessionResult> results = sessionstate.getResults();
|
---|
85 | state = state.with(results);
|
---|
86 | notifyListeners(new CurrentNegoState(state));
|
---|
87 | if (!state.isFinal(now)) {
|
---|
88 | startNextSession();
|
---|
89 | }
|
---|
90 | }
|
---|
91 | }
|
---|
92 | }
|
---|
93 |
|
---|
94 | @Override
|
---|
95 | public String getDescription() {
|
---|
96 | return "Runs all possible permutations of provided parties and profiles, "
|
---|
97 | + "with the given number of parties per session. Sessions run one at a time. "
|
---|
98 | + "If reuseParties is set, then a party can occur more than 1 time in each session. "
|
---|
99 | + "The sessionSettings determine the baseline settings for each session, eg the deadline "
|
---|
100 | + "and the protocol to be used. The AllPermutationsProtocol supports all basic SessionProtocols. "
|
---|
101 | + "parties and protocols already available in the settings will participate in every session. ";
|
---|
102 | }
|
---|
103 |
|
---|
104 | @Override
|
---|
105 | public TournamentState getState() {
|
---|
106 | return state;
|
---|
107 | }
|
---|
108 |
|
---|
109 | @Override
|
---|
110 | public ProtocolRef getRef() {
|
---|
111 | return APP;
|
---|
112 | }
|
---|
113 |
|
---|
114 | @Override
|
---|
115 | public void addParticipant(PartyWithProfile party) {
|
---|
116 | log.log(Level.INFO, "tournament ignoring join attempt by " + party);
|
---|
117 | }
|
---|
118 |
|
---|
119 | }
|
---|