1 | from typing import TYPE_CHECKING
|
---|
2 | from pyson.JsonSubTypes import JsonSubTypes
|
---|
3 | from tudelft.utilities.listener.Listenable import Listenable
|
---|
4 |
|
---|
5 | from geniusweb.events.ProtocolEvent import ProtocolEvent
|
---|
6 | if TYPE_CHECKING:
|
---|
7 | from geniusweb.protocol.NegoState import NegoState
|
---|
8 | from geniusweb.protocol.partyconnection.ProtocolToPartyConnFactory import ProtocolToPartyConnFactory
|
---|
9 | from geniusweb.references.PartyWithProfile import PartyWithProfile
|
---|
10 | from geniusweb.references.ProtocolRef import ProtocolRef
|
---|
11 |
|
---|
12 |
|
---|
13 | @JsonSubTypes(["SessionProtocol"])
|
---|
14 | class NegoProtocol (Listenable[ProtocolEvent]):
|
---|
15 | '''
|
---|
16 | Abstract interface to all negotiation protocols, both single session and
|
---|
17 | tournaments. Generally a protocol handles events on the provided connections
|
---|
18 | according to the rules set by the protocol. The rules are explained by
|
---|
19 | {@link #getDescription()}. A protocol reports the progress through its
|
---|
20 | {@link Listenable} interface. <br>
|
---|
21 | <h2>General information</h2>
|
---|
22 |
|
---|
23 | A protocol is mutable because the incoming connections cause state changes.
|
---|
24 | But it is recommended to push changing properties into the state so that the
|
---|
25 | complete state can be recovered and analysed.
|
---|
26 | <p>
|
---|
27 | Because a protocol contains an internal state, it can be used only once.
|
---|
28 | <p>
|
---|
29 | The protocol can emit a {@link CurrentState} event at any time. It should do
|
---|
30 | so at least once, to log the final outcome of the nego.
|
---|
31 | <p>
|
---|
32 |
|
---|
33 | Normally the constructor will receive a {@link ConnectionFactory} through
|
---|
34 | which it can resolve received {@link Reference}s. <br>
|
---|
35 | First call to instances <b>must be</b>
|
---|
36 | {@link #start(ProtocolToPartyConnFactory)}.
|
---|
37 |
|
---|
38 | <h2>Ensure time deadline</h2>
|
---|
39 |
|
---|
40 | The protocol also needs to keep an eye on the deadline and take appropriate
|
---|
41 | actions when the deadline is reached. <br>
|
---|
42 | <p>
|
---|
43 | All protocol implementations must ensure that the deadline is kept and that
|
---|
44 | the session ends at the agreed time {@link Deadline#getDuration()}. This is
|
---|
45 | to ensure that the negotiation ends and resources are freed up at or before
|
---|
46 | some known time.
|
---|
47 | '''
|
---|
48 | def start(self, connectionfactory:ProtocolToPartyConnFactory):
|
---|
49 | '''
|
---|
50 | Start the protocol: make connection with parties and follow the protocol.
|
---|
51 | This must be called once and should be the first call after construction.
|
---|
52 | <p>
|
---|
53 |
|
---|
54 | The protocol implementation should not start any real work (eg making
|
---|
55 | connections) before this point. That also allows us to construct protocol
|
---|
56 | instances just to fetch the description.
|
---|
57 | <p>
|
---|
58 |
|
---|
59 | All errors are to be handled through {@link SessionState#getResult()}
|
---|
60 | except for bugs that use {@link RuntimeException} like
|
---|
61 | {@link IllegalArgumentException}s. <br>
|
---|
62 | The protocol usually uses the incoming connections to keep running. It
|
---|
63 | does not need to run in a separate thread or so.
|
---|
64 |
|
---|
65 |
|
---|
66 | @param connectionfactory the {@link ProtocolToPartyConnFactory} that
|
---|
67 | allows the protocol to connect with the
|
---|
68 | {@link Reference}s in the settings
|
---|
69 | '''
|
---|
70 |
|
---|
71 | def getDescription(self)-> str:
|
---|
72 | '''
|
---|
73 | @return a complete description of how this protocol behaves. Presented to
|
---|
74 | the end users who should know negotiation basics but not all
|
---|
75 | technical terms.
|
---|
76 | '''
|
---|
77 | def getState(self)->"NegoState" :
|
---|
78 | '''
|
---|
79 | @return current state: the results of all sessions run so far and how to
|
---|
80 | continue from that point. Changes over time as the session
|
---|
81 | proceeds. Errors are also stored in the state.
|
---|
82 | '''
|
---|
83 |
|
---|
84 |
|
---|
85 | def getRef(self) -> ProtocolRef :
|
---|
86 | '''
|
---|
87 | @return the {@link ProtocolRef} for this protocol
|
---|
88 | '''
|
---|
89 |
|
---|
90 | def addParticipant(self, party:PartyWithProfile ):
|
---|
91 | '''
|
---|
92 | Add a party after the protocol has started. Only some protocols can
|
---|
93 | handle this call. Usual protocols take the settings with their
|
---|
94 | constructor.
|
---|
95 | @param party the {@link PartyWithProfile} to be added.
|
---|
96 | '''
|
---|
97 |
|
---|