From d37e1a292501548e92815642805f82debe77e33b Mon Sep 17 00:00:00 2001 From: Gregor Riegler Date: Thu, 9 May 2013 02:42:52 +0200 Subject: [PATCH] Waiter takes Order from guests --- .../tuwien/sbc/valesriegler/common/Util.java | 3 +- .../xvsm/AbstractXVSMConnector.java | 41 +++---- .../xvsm/WaiterXVSMConnector.java | 100 ++++++++++++------ .../sbc/valesriegler/xvsm/waiter/Waiter.java | 4 + 4 files changed, 98 insertions(+), 50 deletions(-) diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/common/Util.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/common/Util.java index d95ad31..28dc0d1 100644 --- a/src/main/java/at/ac/tuwien/sbc/valesriegler/common/Util.java +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/common/Util.java @@ -17,7 +17,8 @@ public abstract class Util { public static final String TABLES_CONTAINER = "tables"; public static final String GROUPS_CONTAINER = "groups"; public static final String ASSIGN_TABLE = "assignTable"; - public static final String TAKE_ORDER = "takeOrder"; + public static final String TAKE_ORDER = "takeOrder"; + public static final String ORDER = "order"; public static final String DELIVER_PIZZAS = "deliverPizzas"; public static final String PAYMENT = "payment"; public static final String FREE_TABLES = "freeTables"; diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java index e317610..887ee5b 100644 --- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java @@ -34,8 +34,9 @@ public abstract class AbstractXVSMConnector { protected ContainerReference groupsContainer; protected ContainerReference assignTableContainer; protected ContainerReference takeOrderContainer; - private ContainerReference deliverPizzasContainer; - private ContainerReference paymentContainer; + protected ContainerReference ordersContainer; + protected ContainerReference deliverPizzasContainer; + protected ContainerReference paymentContainer; protected ContainerReference freeTablesContainer; protected Capi capi; protected NotificationManager notificationMgr; @@ -62,6 +63,10 @@ public abstract class AbstractXVSMConnector { public void useTakeOrderContainer() { takeOrderContainer = useContainer(Util.TAKE_ORDER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ; } + + public void useorderContainer() { + ordersContainer = useContainer(Util.ORDER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ; + } public void useGroupsContainer() { groupsContainer = useContainer(Util.GROUPS_CONTAINER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ; @@ -96,19 +101,19 @@ public abstract class AbstractXVSMConnector { } protected void sendItemsToContainer( - List items, ContainerReference cref) { - - try { - List entries = new ArrayList<>(); - for (Serializable item : items) { - entries.add(new Entry(item)); - } - capi.write(entries, cref); - } catch (Exception e) { - log.info(e.getMessage()); - e.printStackTrace(); + List items, ContainerReference cref, long timeout, TransactionReference tx) { + + try { + List entries = new ArrayList<>(); + for (Serializable item : items) { + entries.add(new Entry(item)); } + capi.write(entries, cref, timeout, tx); + } catch (Exception e) { + log.info(e.getMessage()); + e.printStackTrace(); } + } @SuppressWarnings("unchecked") protected T takeEntityByTemplateFromContainer( @@ -118,7 +123,7 @@ public abstract class AbstractXVSMConnector { LindaSelector sel = LindaCoordinator.newSelector(entity, 1); T singleEntity = null; - ArrayList entities = capi.take(ref, sel, RequestTimeout.DEFAULT, tx); + ArrayList entities = capi.take(ref, sel, timeout, tx); return (T) CapiUtil.getSingleEntry(entities); } catch (CountNotMetException e) { @@ -139,17 +144,17 @@ public abstract class AbstractXVSMConnector { } public void sendTablesToSpace(List tables) { - sendItemsToContainer(tables, tablesContainer); + sendItemsToContainer(tables, tablesContainer, RequestTimeout.DEFAULT, null); } public void sendFreeTablesToSpace(List
tables) { - sendItemsToContainer(tables, freeTablesContainer); + sendItemsToContainer(tables, freeTablesContainer, RequestTimeout.DEFAULT, null); sendTablesToSpace(tables); } public void sendNewGroupsToSpace(List newGroups) { - sendItemsToContainer(newGroups, groupsContainer); - sendItemsToContainer(newGroups, assignTableContainer); + sendItemsToContainer(newGroups, groupsContainer, RequestTimeout.DEFAULT, null); + sendItemsToContainer(newGroups, assignTableContainer, RequestTimeout.DEFAULT, null); } } \ No newline at end of file diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSMConnector.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSMConnector.java index 8c91546..02819c4 100644 --- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSMConnector.java +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSMConnector.java @@ -2,14 +2,15 @@ package at.ac.tuwien.sbc.valesriegler.xvsm; import java.io.Serializable; import java.net.URI; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.mozartspaces.capi3.CountNotMetException; +import org.mozartspaces.core.MzsConstants.RequestTimeout; import org.mozartspaces.core.MzsCoreException; import org.mozartspaces.core.TransactionReference; -import org.mozartspaces.core.MzsConstants.RequestTimeout; import org.mozartspaces.notifications.Notification; import org.mozartspaces.notifications.NotificationListener; import org.mozartspaces.notifications.Operation; @@ -30,6 +31,7 @@ public class WaiterXVSMConnector extends AbstractXVSMConnector { useAssignTableContainer(); useTablesContainer(); useTakeOrderContainer(); + useorderContainer(); useGroupsContainer(); } @@ -46,31 +48,22 @@ public class WaiterXVSMConnector extends AbstractXVSMConnector { for (Table table : tables) { try { - TransactionReference tx = capi.createTransaction(RequestTimeout.INFINITE, URI.create(Util.SERVER_ADDR)); + TransactionReference tx = capi.createTransaction(3000, URI.create(Util.SERVER_ADDR)); try { // Acquire a lock for the free table in the FreeTableContainer int id = table.getId(); log.info("Try to find the table with id {}", id); - Table lockedFreeTable = takeEntityByTemplateFromContainer(new Table(id), freeTablesContainer, tx, 1000, String.format("There was no free table found with id %d", id)); + Table tableTemplate = new Table(id); + Table lockedFreeTable = takeEntityByTemplateFromContainer(tableTemplate, freeTablesContainer, tx, 1000, String.format("There was no free table found with id %d", id)); log.info("Table with id {} was found", id); - GroupData lockedGroup = takeEntityByTemplateFromContainer(new GroupData(), assignTableContainer, tx, 1000, "There is no group waiting for a table at the moment"); - - // The new group sits down at the table - lockedFreeTable.setGroupId(lockedGroup.getId()); - lockedGroup.setTable(lockedFreeTable); - - // The new group now wants to order - lockedGroup.setState(GroupState.ORDER_PENDING); - sendItemsToContainer(Arrays.asList(lockedFreeTable), tablesContainer); - sendItemsToContainer(Arrays.asList(lockedGroup), groupsContainer); - sendItemsToContainer(Arrays.asList(lockedGroup), takeOrderContainer); - - log.info("Assigned Table to group with groupId {}", lockedGroup.getId()); - capi.commitTransaction(tx); + GroupData groupTemplate = new GroupData(); + GroupData lockedGroup = takeEntityByTemplateFromContainer(groupTemplate, assignTableContainer, tx, RequestTimeout.DEFAULT, "There is no group waiting for a table at the moment"); + + assignGroupToTable(lockedGroup, lockedFreeTable, tx); } catch (IllegalArgumentException e) { log.error("SHOULD NEVER HAPPEN!"); @@ -128,23 +121,12 @@ public class WaiterXVSMConnector extends AbstractXVSMConnector { try { // Acquire a lock for the group in the AssignTableContainer String groupNotFound = String.format("Group with id %d was already assigned a table by another waiter!", group.getId()); + GroupData lockedGroup = takeEntityByTemplateFromContainer(new GroupData(group.getId()), assignTableContainer, tx, 1000, groupNotFound); // Acquire a lock for one free table in the TablesContainer - Table lockedFreeTable = takeEntityByTemplateFromContainer(new Table(), freeTablesContainer, tx, 1000, String.format("No free table for group with id %d could be found", group.getId())); - - // The new group sits down at the table - lockedFreeTable.setGroupId(lockedGroup.getId()); - lockedGroup.setTable(lockedFreeTable); + Table lockedFreeTable = takeEntityByTemplateFromContainer(new Table(), freeTablesContainer, tx, RequestTimeout.DEFAULT, String.format("No free table for group with id %d could be found", group.getId())); - // The new group now wants to order - lockedGroup.setState(GroupState.ORDER_PENDING); - - sendItemsToContainer(Arrays.asList(lockedFreeTable), tablesContainer); - sendItemsToContainer(Arrays.asList(lockedGroup), groupsContainer); - sendItemsToContainer(Arrays.asList(lockedGroup), takeOrderContainer); - - log.info("Assigned Table to group with groupId {}", lockedGroup.getId()); - capi.commitTransaction(tx); + assignGroupToTable(lockedGroup, lockedFreeTable, tx); } catch (IllegalArgumentException e) { log.error("SHOULD NEVER HAPPEN!"); @@ -181,4 +163,60 @@ public class WaiterXVSMConnector extends AbstractXVSMConnector { } } + public void listenForOrders() { + NotificationListener ordersListener = new NotificationListener() { + @Override + public void entryOperationFinished(final Notification notification, final Operation operation, final List entries) { + log.info("A new order has arrived!"); + + List groups = castEntries(entries); + if(groups.size() != 1) throw new RuntimeException("Multiple orders in one notification?! That should not happen!"); + + GroupData groupData = groups.get(0); + groupData.setState(GroupState.ORDERED); + + try { + TransactionReference tx = capi.createTransaction(1500, URI.create(Util.SERVER_ADDR)); + GroupData entity = new GroupData(groupData.getId()); + entity.setState(GroupState.ORDER_PENDING); + takeEntityByTemplateFromContainer(entity, takeOrderContainer, tx, RequestTimeout.DEFAULT, String.format("The order for group %d was already taken by an other waiter!", groupData.getId())); + sendItemsToContainer(Arrays.asList(groupData), ordersContainer, RequestTimeout.ZERO, tx); + sendItemsToContainer(Arrays.asList(groupData), groupsContainer, RequestTimeout.ZERO, tx); + capi.commitTransaction(tx); + } catch (MzsCoreException e) { + log.info("ERROR in listenForOrders"); + e.printStackTrace(); + } + } + }; + + try { + notificationMgr.createNotification(takeOrderContainer, ordersListener, Operation.WRITE); + log.info("Created takeOrderContainer notification for a waiter"); + } catch (MzsCoreException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + private void assignGroupToTable(GroupData lockedGroup, + Table lockedFreeTable, TransactionReference tx) + throws MzsCoreException { + // The new group sits down at the table + lockedFreeTable.setGroupId(lockedGroup.getId()); + lockedGroup.setTable(lockedFreeTable); + + // The new group now wants to order + lockedGroup.setState(GroupState.ORDER_PENDING); + + sendItemsToContainer(Arrays.asList(lockedFreeTable), tablesContainer, RequestTimeout.ZERO, tx); + sendItemsToContainer(Arrays.asList(lockedGroup), groupsContainer, RequestTimeout.ZERO, tx); + sendItemsToContainer(Arrays.asList(lockedGroup), takeOrderContainer, RequestTimeout.ZERO, tx); + + log.info("Assigned Table to group with groupId {}", lockedGroup.getId()); + if(tx != null) capi.commitTransaction(tx); + else log.error("TX IS NULL!"); + } + } diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/waiter/Waiter.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/waiter/Waiter.java index 36bedce..069f055 100644 --- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/waiter/Waiter.java +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/waiter/Waiter.java @@ -52,11 +52,15 @@ public class Waiter implements Serializable { private void start() { xvsm = new WaiterXVSMConnector(); + xvsm.listenForOrders(); + // when new guests arrive the waiter should try to assign a table to them xvsm.listenForNewGuests(); // when tables get free the waiter should have a look if there are waiting guests and assign the new table to them xvsm.listenForFreeTable(); + + } -- 2.43.0