source: src/main/java/bargainingchips/protocol/BilateralProtocol.java@ 341

Last change on this file since 341 was 340, checked in by Tim Baarslag, 5 years ago

Change BilateralProtocol loop to avoid busy wait; note that this fixes only a part of the busy wait problem.

Package structure now in line with latest Acumex discussions.

Pinpointed error avoidance in Agent.

File size: 3.0 KB
Line 
1package bargainingchips.protocol;
2
3import java.util.List;
4
5import java.util.ArrayList;
6import java.util.concurrent.BlockingQueue;
7
8import bargainingchips.actions.Offer;
9import bargainingchips.actions.OfferBy;
10
11/**
12 * A (possibly asynchronous) protocol between two agents A and B.
13 * The protocol acts as the postman of delivering messages between the agents and validates their messages.
14 * The protocol keeps the one official (synchronized) log of what has happened.
15 */
16public abstract class BilateralProtocol implements Runnable
17{
18 // Messaging to and from A and B
19 protected final BlockingQueue<OfferBy> from;
20
21 // Should be considered final
22 protected String nameA;
23 protected BlockingQueue<Offer> toA;
24 protected String nameB;
25 protected BlockingQueue<Offer> toB;
26
27 protected final List<OfferBy> log;
28
29 public BilateralProtocol(BlockingQueue<OfferBy> from, String nameA,
30 BlockingQueue<Offer> toA, String nameB, BlockingQueue<Offer> toB) {
31 super();
32 this.from = from;
33 this.nameA = nameA;
34 this.toA = toA;
35 this.nameB = nameB;
36 this.toB = toB;
37 this.log = new ArrayList<OfferBy>();
38 }
39
40 protected abstract ValidationResult validate(OfferBy o);
41
42 @Override
43 public void run()
44 {
45 // Wait for a message from A or B
46 try {
47 while (true)
48 {
49 // Wait for a message, avoiding busy wait
50 OfferBy ob = from.take();
51
52 if (ob != null)
53 {
54 String sender = ob.getSender();
55 Offer o = ob.getOffer();
56 ValidationResult validationResult = validate(ob);
57
58 if (validationResult.isValid()) // if the offer was valid
59 {
60 log(ob); // make it official
61 BlockingQueue<Offer> to = addressee(sender); // put it in the right outbox by looking up sender among nameA and nameB
62 to.put(o);
63 }
64 else // drop!
65 System.err.println("Warning: " + ob + " was not a valid offer and was dropped. Log: " + log.toString());
66
67 // The validation could result in a state where the negotiation ended.
68 // We have an outcome, we let both agents know and clean up
69 if (validationResult.hasEnded())
70 {
71 Offer finalOutcome = validationResult.getOutcome();
72 toA.put(finalOutcome);
73 toB.put(finalOutcome);
74 System.out.println("Protocol detected final outcome: " + finalOutcome +
75 ". Notified agents and quitting.");
76 return;
77 }
78 }
79 }
80 } catch (InterruptedException e) {
81 // TODO Auto-generated catch block
82 e.printStackTrace();
83 }
84 }
85
86 /**
87 * Gives the correct outbox for the sender
88 */
89 private BlockingQueue<Offer> addressee(String sender)
90 {
91 if (nameA.equals(sender))
92 return toB;
93
94 if (nameB.equals(sender))
95 return toA;
96
97 throw new IllegalStateException("Sender " + sender + " unknown! Should be either " + nameA + " or " + nameB);
98 }
99
100 private void log(OfferBy ob)
101 {
102 log.add(ob);
103 System.out.println("Logged: " + ob);
104 }
105
106 protected OfferBy getLastOffer()
107 {
108 return log.get(log.size() - 1);
109 }
110
111}
Note: See TracBrowser for help on using the repository browser.