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

Last change on this file since 343 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
RevLine 
[316]1package bargainingchips.protocol;
[315]2
3import java.util.List;
4
5import java.util.ArrayList;
6import java.util.concurrent.BlockingQueue;
7
[316]8import bargainingchips.actions.Offer;
9import bargainingchips.actions.OfferBy;
[315]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
[322]19 protected final BlockingQueue<OfferBy> from;
[337]20
21 // Should be considered final
22 protected String nameA;
23 protected BlockingQueue<Offer> toA;
24 protected String nameB;
25 protected BlockingQueue<Offer> toB;
[315]26
[322]27 protected final List<OfferBy> log;
[315]28
[322]29 public BilateralProtocol(BlockingQueue<OfferBy> from, String nameA,
30 BlockingQueue<Offer> toA, String nameB, BlockingQueue<Offer> toB) {
[315]31 super();
[322]32 this.from = from;
33 this.nameA = nameA;
[315]34 this.toA = toA;
[322]35 this.nameB = nameB;
[315]36 this.toB = toB;
37 this.log = new ArrayList<OfferBy>();
38 }
39
[319]40 protected abstract ValidationResult validate(OfferBy o);
[315]41
42 @Override
43 public void run()
44 {
45 // Wait for a message from A or B
46 try {
47 while (true)
48 {
[340]49 // Wait for a message, avoiding busy wait
50 OfferBy ob = from.take();
[315]51
[322]52 if (ob != null)
[315]53 {
[322]54 String sender = ob.getSender();
55 Offer o = ob.getOffer();
[319]56 ValidationResult validationResult = validate(ob);
[322]57
58 if (validationResult.isValid()) // if the offer was valid
[315]59 {
[322]60 log(ob); // make it official
[337]61 BlockingQueue<Offer> to = addressee(sender); // put it in the right outbox by looking up sender among nameA and nameB
[315]62 to.put(o);
63 }
64 else // drop!
[317]65 System.err.println("Warning: " + ob + " was not a valid offer and was dropped. Log: " + log.toString());
[319]66
67 // The validation could result in a state where the negotiation ended.
[322]68 // We have an outcome, we let both agents know and clean up
[319]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 }
[315]78 }
79 }
80 } catch (InterruptedException e) {
81 // TODO Auto-generated catch block
82 e.printStackTrace();
83 }
84 }
85
[322]86 /**
87 * Gives the correct outbox for the sender
88 */
89 private BlockingQueue<Offer> addressee(String sender)
[315]90 {
[322]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);
[315]98 }
99
100 private void log(OfferBy ob)
101 {
102 log.add(ob);
[337]103 System.out.println("Logged: " + ob);
[315]104 }
105
106 protected OfferBy getLastOffer()
107 {
108 return log.get(log.size() - 1);
[319]109 }
[315]110
111}
Note: See TracBrowser for help on using the repository browser.