Commit 5ea99194 by Tuomas Riihimäki

Remove synchronized from mapQueue

1 parent 0e84e27d
...@@ -9,6 +9,7 @@ import java.util.PriorityQueue; ...@@ -9,6 +9,7 @@ import java.util.PriorityQueue;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -24,10 +25,11 @@ public class MapQueue implements MapQueueI { ...@@ -24,10 +25,11 @@ public class MapQueue implements MapQueueI {
private int minimumSlotsInQueue = 1; private int minimumSlotsInQueue = 1;
private int reservingSize = 5; private int reservingSize = 5;
// private final Set<MapReservationQueueEntry> reserving = new HashSet<>(); // private final Set<MapReservationQueueEntry> reserving = new HashSet<>();
private volatile Set<EventUser> reserving = Collections.newSetFromMap(new ConcurrentHashMap<>()); private final Set<EventUser> reserving = Collections.newSetFromMap(new ConcurrentHashMap<>());
private final PriorityQueue<MapReservationQueueEntry> queue = new PriorityQueue<>(); private final PriorityQueue<MapReservationQueueEntry> queue = new PriorityQueue<>();
private final ConcurrentMap<EventUser, MapReservationQueueEntry> queEntries = new ConcurrentHashMap<>(); private final ConcurrentMap<EventUser, MapReservationQueueEntry> queEntries = new ConcurrentHashMap<>();
private final Integer mapId; private final Integer mapId;
//private final Object reservingLock = new Object();
private static final Logger logger = LoggerFactory.getLogger(MapQueue.class); private static final Logger logger = LoggerFactory.getLogger(MapQueue.class);
...@@ -50,8 +52,8 @@ public class MapQueue implements MapQueueI { ...@@ -50,8 +52,8 @@ public class MapQueue implements MapQueueI {
} }
// Set idle time to the past. // Set idle time to the past.
// Idle timeout after 60 seconds // Idle timeout after 12 seconds
Date idleTimeout = new Date(System.currentTimeMillis() - 1000 * 60); Date idleTimeout = new Date(System.currentTimeMillis() - 1000 * 120);
for (MapReservationQueueEntry entry : queue) { for (MapReservationQueueEntry entry : queue) {
if (entry.getSeenTime() == null) { if (entry.getSeenTime() == null) {
...@@ -77,12 +79,13 @@ public class MapQueue implements MapQueueI { ...@@ -77,12 +79,13 @@ public class MapQueue implements MapQueueI {
} }
private final Object reservingLock = new Object(); private final AtomicBoolean modifyReservers = new AtomicBoolean(false);
private void checkReservingEntry() { private void checkReservingEntry() {
if (reserving.size() < getReservingSize()) { if (reserving.size() < getReservingSize() && modifyReservers.compareAndSet(false, true)) {
synchronized (reservingLock) {
try {
if (reserving.size() < getReservingSize()) { if (reserving.size() < getReservingSize()) {
MapReservationQueueEntry queEntry = queue.poll(); MapReservationQueueEntry queEntry = queue.poll();
if (queEntry != null) { if (queEntry != null) {
...@@ -90,12 +93,14 @@ public class MapQueue implements MapQueueI { ...@@ -90,12 +93,14 @@ public class MapQueue implements MapQueueI {
queEntry.setReservationTimeout(new Date(System.currentTimeMillis() + getDefaultTimeoutMin() * 60 * 1000)); queEntry.setReservationTimeout(new Date(System.currentTimeMillis() + getDefaultTimeoutMin() * 60 * 1000));
} }
} }
} finally {
modifyReservers.set(false);
} }
} }
} }
public MapReservationQueueEntry remove(EventUser user) public MapReservationQueueEntry remove(EventUser user) {
{
if (user == null) { if (user == null) {
return null; return null;
} }
......
...@@ -13,6 +13,8 @@ import javax.ejb.LocalBean; ...@@ -13,6 +13,8 @@ import javax.ejb.LocalBean;
import javax.ejb.Lock; import javax.ejb.Lock;
import javax.ejb.LockType; import javax.ejb.LockType;
import javax.ejb.Singleton; import javax.ejb.Singleton;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -34,6 +36,8 @@ import fi.codecrew.moya.model.map.MapReservationQueueEntry; ...@@ -34,6 +36,8 @@ import fi.codecrew.moya.model.map.MapReservationQueueEntry;
@Singleton @Singleton
@LocalBean @LocalBean
@Lock(LockType.READ) @Lock(LockType.READ)
@TransactionManagement(value = TransactionManagementType.BEAN)
@DeclareRoles({ MapPermission.S_MANAGE_MAPS }) @DeclareRoles({ MapPermission.S_MANAGE_MAPS })
public class QueueBean implements QueueBeanLocal { public class QueueBean implements QueueBeanLocal {
private static final Logger logger = LoggerFactory.getLogger(QueueBean.class); private static final Logger logger = LoggerFactory.getLogger(QueueBean.class);
...@@ -45,15 +49,13 @@ public class QueueBean implements QueueBeanLocal { ...@@ -45,15 +49,13 @@ public class QueueBean implements QueueBeanLocal {
logger.info("Initialized2 QueueBean, {}", mapqueues); logger.info("Initialized2 QueueBean, {}", mapqueues);
} }
@EJB
private PlaceBeanLocal placebean;
private final ConcurrentHashMap<Integer, MapQueue> mapqueues = new ConcurrentHashMap<Integer, MapQueue>(); private final ConcurrentHashMap<Integer, MapQueue> mapqueues = new ConcurrentHashMap<Integer, MapQueue>();
private final AtomicLong nextReservingTimeoutCheck = new AtomicLong();
@EJB
private PlaceBeanLocal placebean;
@EJB @EJB
private EventBeanLocal eventbean; private EventBeanLocal eventbean;
private AtomicLong nextReservingTimeoutCheck = new AtomicLong();
@EJB @EJB
private PlaceSlotFacade slotfacade; private PlaceSlotFacade slotfacade;
@EJB @EJB
...@@ -79,6 +81,7 @@ public class QueueBean implements QueueBeanLocal { ...@@ -79,6 +81,7 @@ public class QueueBean implements QueueBeanLocal {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
long nextTime = nextReservingTimeoutCheck.get(); long nextTime = nextReservingTimeoutCheck.get();
// Update next checktime to 120 seconds in to the future, so we should have plenty of time // Update next checktime to 120 seconds in to the future, so we should have plenty of time
// to do the checks we need.. // to do the checks we need..
if (now > nextTime && nextReservingTimeoutCheck.compareAndSet(nextTime, now + 1000 * 120)) { if (now > nextTime && nextReservingTimeoutCheck.compareAndSet(nextTime, now + 1000 * 120)) {
...@@ -127,8 +130,7 @@ public class QueueBean implements QueueBeanLocal { ...@@ -127,8 +130,7 @@ public class QueueBean implements QueueBeanLocal {
@Lock(LockType.READ) @Lock(LockType.READ)
@Override @Override
public Date getReservationTimeout(EventMap map) public Date getReservationTimeout(EventMap map) {
{
Date d = null; Date d = null;
MapReservationQueueEntry ret = getMapque(map).getEntry(permbean.getCurrentUser()); MapReservationQueueEntry ret = getMapque(map).getEntry(permbean.getCurrentUser());
if (ret != null) if (ret != null)
...@@ -136,8 +138,7 @@ public class QueueBean implements QueueBeanLocal { ...@@ -136,8 +138,7 @@ public class QueueBean implements QueueBeanLocal {
return d; return d;
} }
public Date getReservingTimeout(EventMap map) public Date getReservingTimeout(EventMap map) {
{
MapReservationQueueEntry ret = getMapque(map).getEntry(permbean.getCurrentUser()); MapReservationQueueEntry ret = getMapque(map).getEntry(permbean.getCurrentUser());
Date time = null; Date time = null;
if (ret != null) if (ret != null)
...@@ -147,8 +148,7 @@ public class QueueBean implements QueueBeanLocal { ...@@ -147,8 +148,7 @@ public class QueueBean implements QueueBeanLocal {
@Lock(LockType.READ) @Lock(LockType.READ)
@Override @Override
public Integer getQueuePosition(EventMap map, EventUser user) public Integer getQueuePosition(EventMap map, EventUser user) {
{
if (!permbean.isCurrentUser(user) && !permbean.hasPermission(MapPermission.MANAGE_OTHERS)) if (!permbean.isCurrentUser(user) && !permbean.hasPermission(MapPermission.MANAGE_OTHERS))
throw new RuntimeException("Use " + permbean.getCurrentUser() + "tried to get queuepos in behalf of another user: " + user); throw new RuntimeException("Use " + permbean.getCurrentUser() + "tried to get queuepos in behalf of another user: " + user);
...@@ -212,7 +212,7 @@ public class QueueBean implements QueueBeanLocal { ...@@ -212,7 +212,7 @@ public class QueueBean implements QueueBeanLocal {
} }
@Lock(LockType.READ) @Lock(LockType.READ)
@RolesAllowed({MapPermission.S_MANAGE_MAPS, MapPermission.S_BUY_PLACES}) @RolesAllowed({ MapPermission.S_MANAGE_MAPS, MapPermission.S_BUY_PLACES })
@Override @Override
public MapQueue getMapQueue(EventMap map) { public MapQueue getMapQueue(EventMap map) {
return getMapque(map); return getMapque(map);
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!