1 package at.ac.tuwien.sbc.valesriegler.xvsm;
3 import at.ac.tuwien.sbc.valesriegler.common.Util;
4 import at.ac.tuwien.sbc.valesriegler.types.*;
5 import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceAction;
6 import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceListener;
7 import org.mozartspaces.core.ContainerReference;
8 import org.mozartspaces.core.MzsConstants.RequestTimeout;
9 import org.mozartspaces.core.MzsCoreException;
10 import org.mozartspaces.core.TransactionReference;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
14 import java.io.Serializable;
16 import java.util.Arrays;
17 import java.util.Collections;
18 import java.util.List;
20 public class CookXVSM extends AbstractXVSMConnector {
21 private static final Logger log = LoggerFactory.getLogger(CookXVSM.class);
25 public CookXVSM(int id, int port) {
29 orderTakenContainer = useContainer(Util.ORDER_TAKEN);
30 deliveryOrderTakenContainer = useContainer(Util.DELIVERY_ORDER_TAKEN);
31 preparedPizzasContainer = useContainer(Util.DELIVER_PIZZAS);
32 preparePizzasContainer = useContainer(Util.PREPARE_PIZZAS);
33 prepareDeliveryPizzasContainer = useContainer(Util.PREPARE_DELIVERY_PIZZAS);
34 pizzaInProgressContainer = useContainer(Util.PIZZAS_IN_PROGRESS);
35 preparedDeliveryPizzasContainer = useContainer(Util.DELIVER_DELIVERY_PIZZAS);
36 pizzeriaGroupContainer = useContainer(Util.PIZZERIA_GROUP);
39 public void listenForPizzas() {
40 SpaceListener pizzasListener = getDefaultBuilder().setCref(preparePizzasContainer).setTimeout(15000).setSpaceAction(new SpaceAction() {
43 public void onEntriesWritten(List<? extends Serializable> entries)
46 List<PizzaOrder> pizzas = castEntries(entries);
48 if (inNotification.get()) Collections.shuffle(pizzas);
50 for (PizzaOrder pizzaOrder : pizzas) {
52 TransactionReference tx = capi.createTransaction(9000, URI.create(String.format(Util.SERVER_ADDR, port)));
53 String pizzaAlreadyCooked = String.format("Pizza with id %d has already been cooked by another cook", pizzaOrder.getId());
56 if (!mayPreparePizza(pizzaOrder, tx)) {
57 capi.rollbackTransaction(tx);
61 // Require the lock for preparing the pizza
62 PizzaOrder order = takeMatchingEntity(new PizzaOrder(pizzaOrder.getId()), preparePizzasContainer, tx, RequestTimeout.ZERO, pizzaAlreadyCooked);
65 // tell the space that you prepare the pizza -> without a transaction!!
66 Pizza pizzaInProgress = Pizza.createPizzaFromPizzaOrder(order, cookId, true);
67 pizzaInProgress.setStatus(PizzaOrderStatus.IN_PREPARATION);
70 log.debug("I say that I now prepare a pizza for order {}", pizzaInProgress.getOrderId());
71 sendItemsToContainer(Arrays.asList(pizzaInProgress), pizzaInProgressContainer, RequestTimeout.DEFAULT, null);
73 PizzaOrder pizza = createPizza(order);
75 final ContainerReference container = preparedPizzasContainer;
76 sendItemsToContainer(Arrays.asList(pizza), container, RequestTimeout.DEFAULT, tx);
77 final GroupData group = new GroupData();
78 final Order groupOrder = new Order();
79 groupOrder.setId(pizza.getOrderId());
80 group.setOrder(groupOrder);
81 group.setState(GroupState.ORDERED);
82 GroupData groupData = takeMatchingEntity(group, pizzeriaGroupContainer, tx, RequestTimeout.DEFAULT, "Cannot take the group from pizzeriaGroupContainer");
83 final List<PizzaOrder> orderedPizzas = groupData.getOrder().getOrderedPizzas();
84 for (PizzaOrder orderedPizza : orderedPizzas) {
85 if (orderedPizza.getId() == pizza.getId()) {
86 orderedPizza.setStatus(PizzaOrderStatus.DONE);
87 orderedPizza.setCookId(pizza.getCookId());
90 sendItemsToContainer(Arrays.asList(groupData), pizzeriaGroupContainer, RequestTimeout.DEFAULT, tx);
91 capi.commitTransaction(tx);
92 log.debug("I have completed preparing a pizza for order {}!", pizza.getOrderId());
93 } catch (NullPointerException e) {
94 // the strange nullpointer exception from the space
95 } catch (Exception e) {
96 log.info(e.getMessage());
101 }).createSpaceListenerImpl();
106 * A cook may prepare a pizza if there is no current delivery order or if at least a pizza of the same order is
109 private boolean mayPreparePizza(PizzaOrder pizzaOrder, TransactionReference tx) throws MzsCoreException {
110 List<PizzaOrder> deliveryPizzas = readMatchingEntities(new PizzaOrder(), prepareDeliveryPizzasContainer, tx, RequestTimeout.ZERO, "BBBBBB");
111 if (!deliveryPizzas.isEmpty()) {
112 final PizzaOrder template = new PizzaOrder();
113 template.setOrderId(pizzaOrder.getOrderId());
114 final List<PizzaOrder> pizzasOfOrderInProgress = readMatchingEntities(template, pizzaInProgressContainer, tx, RequestTimeout.ZERO, "ASDF");
115 if (pizzasOfOrderInProgress.isEmpty()) return false;
121 public void listenForDeliveryPizzas() {
122 SpaceListener pizzasListener = getDefaultBuilder().setCref(prepareDeliveryPizzasContainer).setTimeout(15000).setSpaceAction(new SpaceAction() {
125 public void onEntriesWritten(List<? extends Serializable> entries)
128 List<PizzaOrder> pizzas = castEntries(entries);
130 if (inNotification.get()) Collections.shuffle(pizzas);
132 for (PizzaOrder pizzaOrder : pizzas) {
134 TransactionReference tx = capi.createTransaction(9000, URI.create(String.format(Util.SERVER_ADDR, port)));
135 String pizzaAlreadyCooked = String.format("Pizza with id %d has already been cooked by another cook", pizzaOrder.getId());
138 // Require the lock for preparing the pizza
139 PizzaOrder order = takeMatchingEntity(new PizzaOrder(pizzaOrder.getId()), prepareDeliveryPizzasContainer, tx, RequestTimeout.ZERO, pizzaAlreadyCooked);
141 // tell the space that you prepare the pizza -> without a transaction!!
142 Pizza pizzaInProgress = Pizza.createPizzaFromPizzaOrder(order, cookId, true);
143 pizzaInProgress.setStatus(PizzaOrderStatus.IN_PREPARATION);
146 log.info("I say that I now prepare a pizza for order {}", pizzaInProgress.getOrderId());
147 sendItemsToContainer(Arrays.asList(pizzaInProgress), pizzaInProgressContainer, RequestTimeout.DEFAULT, null);
149 PizzaOrder pizza = createPizza(order);
151 final ContainerReference container = preparedDeliveryPizzasContainer;
152 sendItemsToContainer(Arrays.asList(pizza), container, RequestTimeout.DEFAULT, tx);
154 capi.commitTransaction(tx);
155 log.info("I have completed preparing a delivery pizza for order {}!", pizza.getOrderId());
156 } catch (NullPointerException e) {
157 // the strange nullpointer exception from the space
158 } catch (Exception e) {
159 log.info(e.getMessage());
164 }).createSpaceListenerImpl();
168 private PizzaOrder createPizza(PizzaOrder order) throws InterruptedException {
169 long duration = order.getPizzaType().duration;
170 Thread.sleep(duration * 1000);
172 PizzaOrder pizza = Pizza.createPizzaFromPizzaOrder(order, cookId, false);
173 pizza.setStatus(PizzaOrderStatus.DONE);