]> git.somenet.org - pub/jan/sbc.git/blob - src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaAgentXVSM.java
Solve some space concurrency bugs
[pub/jan/sbc.git] / src / main / java / at / ac / tuwien / sbc / valesriegler / xvsm / PizzeriaAgentXVSM.java
1 package at.ac.tuwien.sbc.valesriegler.xvsm;
2
3 import java.io.Serializable;
4 import java.net.URI;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.List;
8
9 import javax.swing.SwingUtilities;
10
11 import org.mozartspaces.capi3.AnyCoordinator;
12 import org.mozartspaces.capi3.FifoCoordinator;
13 import org.mozartspaces.capi3.LindaCoordinator;
14 import org.mozartspaces.core.MzsCoreException;
15 import org.mozartspaces.core.TransactionReference;
16 import org.mozartspaces.core.MzsConstants.RequestTimeout;
17 import org.mozartspaces.notifications.Notification;
18 import org.mozartspaces.notifications.NotificationListener;
19 import org.mozartspaces.notifications.Operation;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 import at.ac.tuwien.sbc.valesriegler.common.Util;
24 import at.ac.tuwien.sbc.valesriegler.pizzeria.PizzeriaAgent;
25 import at.ac.tuwien.sbc.valesriegler.types.GroupData;
26 import at.ac.tuwien.sbc.valesriegler.types.GroupState;
27 import at.ac.tuwien.sbc.valesriegler.types.Order;
28 import at.ac.tuwien.sbc.valesriegler.types.Pizza;
29 import at.ac.tuwien.sbc.valesriegler.types.PizzaOrder;
30 import at.ac.tuwien.sbc.valesriegler.types.Table;
31
32 public class PizzeriaAgentXVSM extends AbstractXVSMConnector {
33         private static final Logger log = LoggerFactory.getLogger(PizzeriaAgentXVSM.class);
34         
35         public PizzeriaAgentXVSM() {
36                 super();
37                 tableAssignedContainer = useContainer(Util.TABLE_ASSIGNED) ;
38                 freeTablesContainer = useContainer(Util.FREE_TABLES);
39                 pizzaInProgressContainer = useContainer(Util.PIZZAS_IN_PROGRESS) ;
40                 orderCompleteContainer = useContainer(Util.ORDER_COMPLETE) ;
41                 deliverPizzasContainer = useContainer(Util.DELIVER_PIZZAS);
42                 paymentDoneContainer = useContainer(Util.PAYMENT_DONE) ;
43                 orderTakenContainer = useContainer(Util.ORDER_TAKEN);
44                 assignTableContainer = useContainer(Util.ASSIGN_TABLE);
45         }
46
47         public void listenForOccupiedTables() {
48                 NotificationListener tablesListener = new NotificationListener() {
49             @Override
50             public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
51                 log.info("A new group was assigned to a table!");
52                 
53                 final List<Table> tables = castEntries(entries);
54                 
55                 if(tables.size() != 1) {
56                         throw new RuntimeException("Only one table can get free at once!");
57                 }
58                 final Table table = tables.get(0);
59         
60                 SwingUtilities.invokeLater(new Runnable() {
61                                         @Override
62                                         public void run() {
63                                                 PizzeriaAgent.getInstance().getTablesModel().addItems(Arrays.asList(table));
64                                                 PizzeriaAgent.getInstance().getGroupModel().removeGroup(table.getGroupId());
65                                         }
66                                 });
67             }
68         };
69         try {
70                 notificationMgr.createNotification(tableAssignedContainer, tablesListener, Operation.WRITE);
71                 log.info("Created tableAssigned notification for pizzeria!");
72         } catch (Exception e) {
73             handleSpaceErrorAndTerminate(e);
74         }
75         }
76         
77         public void listenForFreeTables() {
78                 NotificationListener tablesListener = new NotificationListener() {
79             @Override
80             public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
81                 log.info("A table has become free");
82                 
83                 final List<Table> tables = castEntries(entries);
84         
85                 SwingUtilities.invokeLater(new Runnable() {
86                                         @Override
87                                         public void run() {
88                                                 PizzeriaAgent.getInstance().getTablesModel().addItems(tables);
89                                         }
90                                 });
91             }
92         };
93         try {
94                 notificationMgr.createNotification(freeTablesContainer, tablesListener, Operation.WRITE);
95         } catch (Exception e) {
96             handleSpaceErrorAndTerminate(e);
97         }
98         }
99
100         public void listenForWaitingGroups() {
101                 
102         NotificationListener groupsListener = new NotificationListener() {
103             @Override
104             public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
105                 final List<GroupData> groups = castEntries(entries);
106                 
107                 SwingUtilities.invokeLater(new Runnable() {
108                                         @Override
109                                         public void run() {
110                                                 PizzeriaAgent.getInstance().getGroupModel().addItems(groups);
111                                         }
112                                 });
113                 
114             }
115         };
116           try {
117                 notificationMgr.createNotification(assignTableContainer, groupsListener, Operation.WRITE);
118         } catch (Exception e) {
119            handleSpaceErrorAndTerminate(e);
120         }
121         }
122         
123 public void listenForTakenOrders() {
124                 
125         NotificationListener orderTakenListener = new NotificationListener() {
126             @Override
127             public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
128                 final List<GroupData> groups = castEntries(entries);
129                 
130                 if(groups.size() != 1) {
131                         throw new RuntimeException("Only one order per table!");
132                 }
133                 final GroupData group = groups.get(0);
134                 
135                 SwingUtilities.invokeLater(new Runnable() {
136                                         @Override
137                                         public void run() {
138                                                 PizzeriaAgent.getInstance().getOrdersModel().addItems(Arrays.asList(group));
139                                         }
140                                 });
141                 
142             }
143         };
144           try {
145                 notificationMgr.createNotification(orderTakenContainer, orderTakenListener, Operation.WRITE);
146         } catch (Exception e) {
147            handleSpaceErrorAndTerminate(e);
148         }
149         }
150
151         public void listenForPizzasInPreparation() {
152                 NotificationListener pizzasInProgress = new NotificationListener() {
153             @Override
154             public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
155                 final List<Pizza> pizzas = castEntries(entries);
156                 
157                 log.info("{} pizzas in progress changes!", pizzas.size());
158                 for (PizzaOrder pizza : pizzas) {
159                         log.info(pizza.toString());
160                                 }
161                 
162                 SwingUtilities.invokeLater(new Runnable() {
163                                         @Override
164                                         public void run() {
165                                                 PizzeriaAgent.getInstance().getOrdersModel().updatePizzasInPreparation(pizzas);
166                                         }
167                                 });
168                 
169             }
170         };
171           try {
172                 notificationMgr.createNotification(pizzaInProgressContainer, pizzasInProgress, Operation.WRITE);
173         } catch (Exception e) {
174            handleSpaceErrorAndTerminate(e);
175         }
176         }
177
178         public void listenForDeliveredOrders() {
179                 NotificationListener deliveredOrders = new NotificationListener() {
180             @Override
181             public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
182                 final List<GroupData> groups = castEntries(entries);
183                 
184                 log.info("{} order was delivered!", groups.size());
185                 if(groups.size() != 1) {
186                         throw new RuntimeException("A waiter should only deliver one order at once!");
187                 }
188                 final GroupData group = groups.get(0);
189                            
190                 SwingUtilities.invokeLater(new Runnable() {
191                                         @Override
192                                         public void run() {
193                                                 PizzeriaAgent.getInstance().getOrdersModel().updateStatusOfOrder(group);
194                                         }
195                                 });
196                 
197             }
198         };
199           try {
200                 notificationMgr.createNotification(orderCompleteContainer, deliveredOrders, Operation.WRITE);
201         } catch (Exception e) {
202            handleSpaceErrorAndTerminate(e);
203         }
204         }
205
206         public void listenForPreparedPizzas() {
207                 NotificationListener preparedPizzasListener = new NotificationListener() {
208             @Override
209             public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
210                
211                List<Pizza> pizzas = castEntries(entries);
212                if(pizzas.size() != 1) throw new RuntimeException("Multiple pizzas in one notification?! That should not happen! A cook can only prepare one at the same time!");
213                
214                final Pizza pizza = pizzas.get(0);
215                
216                SwingUtilities.invokeLater(new Runnable() {
217                                         @Override
218                                         public void run() {
219                                                 PizzeriaAgent.getInstance().getOrdersModel().updateStatusOfPizzasDone(pizza);
220                                         }
221                         });
222               
223             }
224                 };
225                 
226         try {
227                         notificationMgr.createNotification(deliverPizzasContainer, preparedPizzasListener, Operation.WRITE);
228                         log.info("Created deliverPizzasContainer notification for the pizzeria");
229                 } catch (Exception e) {
230                         handleSpaceErrorAndTerminate(e);
231                 }
232         }
233
234         public void listenForPayment() {
235                 NotificationListener isGoneListener = new NotificationListener() {
236             @Override
237             public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
238                 final List<GroupData> groups = castEntries(entries);
239           
240                 final GroupData group = groups.get(0);
241                 log.info("Group {} is gone", group.getId());
242                            
243                 final int tableId = PizzeriaAgent.getInstance().getTablesModel().getTableIdOfGroup(group);
244                 SwingUtilities.invokeLater(new Runnable() {
245                                         
246                                         @Override
247                                         public void run() {
248                                                 PizzeriaAgent.getInstance().getOrdersModel().updatePaymentWaiter(group);
249                                                 PizzeriaAgent.getInstance().getTablesModel().makeTableFree(tableId);
250                                         }
251                                 });
252                                 
253                                 Table table = new Table(tableId);
254                                 
255                                 sendItemsToContainer(Arrays.asList(table), freeTablesContainer, RequestTimeout.DEFAULT, null);
256             }
257         };
258           try {
259                 notificationMgr.createNotification(paymentDoneContainer, isGoneListener, Operation.WRITE);
260         } catch (Exception e) {
261            handleSpaceErrorAndTerminate(e);
262         }
263         }
264
265         public void sendFreeTablesToContainer(List<Table> tables) {
266                 sendItemsToContainer(tables, freeTablesContainer, RequestTimeout.DEFAULT, null);
267         }
268
269         
270
271
272 }