package de.anycook.api.providers; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import de.anycook.db.mysql.DBMessage; import de.anycook.messages.MessageSession; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import javax.ws.rs.WebApplicationException; import javax.ws.rs.container.AsyncResponse; import javax.ws.rs.core.Response; import java.sql.SQLException; import java.util.concurrent.*; /** * @author Jan Graßegger<jan@anycook.de> */ public enum MessageProvider { INSTANCE; private final Logger logger; private final Cache<Integer, BlockingQueue<UserResponse>> suspended; MessageProvider(){ logger = LogManager.getLogger(getClass()); suspended = CacheBuilder.newBuilder() .maximumSize(10000) .expireAfterWrite(5, TimeUnit.MINUTES) .build(); } public void wakeUpSuspended(int sessionId) throws SQLException { logger.debug("waking up suspended"); BlockingQueue<UserResponse> queue = suspended.getIfPresent(sessionId); if(queue == null) return; while(!queue.isEmpty()){ LogManager.getLogger(MessageSession.class).debug("reading response"); try { UserResponse userResponse = queue.take(); AsyncResponse asyncResponse = userResponse.response; try { MessageSession session = MessageSession.getSession(sessionId, userResponse.userId); if(asyncResponse.isSuspended()) asyncResponse.resume(session); } catch (DBMessage.SessionNotFoundException e) { logger.error(e, e); asyncResponse.resume(new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR)); } } catch (InterruptedException e) { logger.warn(e, e); } } suspended.put(sessionId, queue); } public void suspend(int sessionId, int userId, AsyncResponse response){ logger.debug("supending "+userId); try { BlockingQueue<UserResponse> queue = suspended.get(sessionId, new Callable<BlockingQueue<UserResponse>>() { @Override public BlockingQueue<UserResponse> call() throws Exception { return new ArrayBlockingQueue<>(1000); } }); queue.add(new UserResponse(userId, response)); suspended.put(userId, queue); } catch (ExecutionException e) { logger.error(e, e); } } private static class UserResponse{ public final int userId; public final AsyncResponse response; public UserResponse(int userId, AsyncResponse response){ this.userId = userId; this.response = response; } } }