use of org.atmosphere.cache.CacheMessage in project atmosphere by Atmosphere.
the class DefaultBroadcaster method deliverPush.
protected void deliverPush(Deliver deliver, boolean rec) {
recentActivity.set(true);
String prevMessage = deliver.message.toString();
if (rec && !delayedBroadcast.isEmpty()) {
Iterator<Deliver> i = delayedBroadcast.iterator();
StringBuilder b = new StringBuilder();
while (i.hasNext()) {
Deliver e = i.next();
e.future.cancel(true);
try {
// Append so we do a single flush
if (e.message instanceof String && deliver.message instanceof String) {
b.append(e.message);
} else {
deliverPush(e, false);
}
} finally {
i.remove();
}
}
if (b.length() > 0) {
deliver.message = b.append(deliver.message).toString();
}
}
Object finalMsg = callable(deliver.message);
if (finalMsg == null) {
logger.error("Callable exception. Please catch all exceptions from your callable. Message {} will be lost and all AtmosphereResource " + "associated with this Broadcaster resumed.", deliver.message);
entryDone(deliver.future);
switch(deliver.type) {
case ALL:
synchronized (resources) {
for (AtmosphereResource r : resources) {
if (Utils.resumableTransport(r.transport()))
try {
r.resume();
} catch (Throwable t) {
logger.trace("resumeAll", t);
}
}
}
break;
case RESOURCE:
deliver.resource.resume();
break;
case SET:
for (AtmosphereResource r : deliver.resources) {
r.resume();
}
break;
}
return;
}
notifyOnMessage(deliver);
Object prevM = deliver.originalMessage;
deliver.originalMessage = (deliver.originalMessage != deliver.message ? callable(deliver.originalMessage) : finalMsg);
if (deliver.originalMessage == null) {
logger.trace("Broadcasted message was null {}", prevM);
entryDone(deliver.future);
return;
}
deliver.message = finalMsg;
Map<String, CacheMessage> cacheForSet = deliver.type == Deliver.TYPE.SET ? new HashMap<String, CacheMessage>() : null;
// We cache first, and if the broadcast succeed, we will remove it.
switch(deliver.type) {
case ALL:
deliver.cache = bc.getBroadcasterCache().addToCache(getID(), BroadcasterCache.NULL, new BroadcastMessage(deliver.originalMessage));
break;
case RESOURCE:
deliver.cache = bc.getBroadcasterCache().addToCache(getID(), deliver.resource.uuid(), new BroadcastMessage(deliver.originalMessage));
break;
case SET:
for (AtmosphereResource r : deliver.resources) {
cacheForSet.put(r.uuid(), bc.getBroadcasterCache().addToCache(getID(), r.uuid(), new BroadcastMessage(deliver.originalMessage)));
}
break;
}
if (resources.isEmpty()) {
logger.trace("No resource available for {} and message {}", getID(), finalMsg);
entryDone(deliver.future);
if (cacheForSet != null) {
cacheForSet.clear();
}
return;
}
try {
if (logger.isTraceEnabled()) {
for (AtmosphereResource r : resources) {
logger.trace("AtmosphereResource {} available for {}", r.uuid(), deliver.message);
}
}
boolean hasFilters = bc.hasPerRequestFilters();
Object beforeProcessingMessage = deliver.message;
switch(deliver.type) {
case ALL:
AtomicInteger count = new AtomicInteger(resources.size());
for (AtmosphereResource r : resources) {
deliver.message = beforeProcessingMessage;
boolean deliverMessage = perRequestFilter(r, deliver);
if (endBroadcast(deliver, r, deliver.cache, deliverMessage))
continue;
if (deliver.writeLocally) {
queueWriteIO(r, hasFilters ? new Deliver(r, deliver) : deliver, count);
}
}
break;
case RESOURCE:
boolean deliverMessage = perRequestFilter(deliver.resource, deliver);
if (endBroadcast(deliver, deliver.resource, deliver.cache, deliverMessage))
return;
if (deliver.writeLocally) {
queueWriteIO(deliver.resource, deliver, new AtomicInteger(1));
}
break;
case SET:
count = new AtomicInteger(deliver.resources.size());
for (AtmosphereResource r : deliver.resources) {
deliver.message = beforeProcessingMessage;
deliverMessage = perRequestFilter(r, deliver);
CacheMessage cacheMsg = cacheForSet.remove(r.uuid());
if (endBroadcast(deliver, r, cacheMsg, deliverMessage))
continue;
if (deliver.writeLocally) {
queueWriteIO(r, new Deliver(r, deliver, cacheMsg), count);
}
}
break;
}
deliver.message = prevMessage;
} catch (InterruptedException ex) {
logger.debug(ex.getMessage(), ex);
if (cacheForSet != null) {
cacheForSet.clear();
}
}
}
use of org.atmosphere.cache.CacheMessage in project atmosphere by Atmosphere.
the class BroadcasterCacheTest method testCache.
@Test
public void testCache() throws ExecutionException, InterruptedException, ServletException {
broadcaster.getBroadcasterConfig().setBroadcasterCache(new AbstractBroadcasterCache() {
@Override
public CacheMessage addToCache(String id, String uuid, BroadcastMessage e) {
CacheMessage c = put(e, System.nanoTime(), uuid, broadcaster.getID());
cachedMessage.set(messages);
return c;
}
@Override
public List<Object> retrieveFromCache(String id, String uuid) {
return Collections.<Object>emptyList();
}
}).getBroadcasterCache().inspector(new BroadcasterCacheInspector() {
@Override
public boolean inspect(BroadcastMessage message) {
return true;
}
});
broadcaster.broadcast("foo", ar).get();
assertEquals(cachedMessage.get().size(), 0);
}
use of org.atmosphere.cache.CacheMessage in project atmosphere by Atmosphere.
the class BroadcasterCacheTest method testEmptyCache.
@Test
public void testEmptyCache() throws ExecutionException, InterruptedException, ServletException {
final CountDownLatch latch = new CountDownLatch(1);
broadcaster.getBroadcasterConfig().setBroadcasterCache(new AbstractBroadcasterCache() {
@Override
public CacheMessage addToCache(String id, String uuid, BroadcastMessage e) {
CacheMessage c = put(e, System.nanoTime(), uuid, broadcaster.getID());
cachedMessage.set(messages);
latch.countDown();
return c;
}
@Override
public List<Object> retrieveFromCache(String id, String uuid) {
return Collections.<Object>emptyList();
}
}).getBroadcasterCache().inspector(new BroadcasterCacheInspector() {
@Override
public boolean inspect(BroadcastMessage message) {
return true;
}
});
broadcaster.broadcast("foo", ar);
latch.await(10, TimeUnit.SECONDS);
assertEquals(cachedMessage.get().size(), 1);
}
use of org.atmosphere.cache.CacheMessage in project atmosphere by Atmosphere.
the class DefaultBroadcasterTest method testSimultaneousAddResourceAndPush.
@Test
public void testSimultaneousAddResourceAndPush() throws ExecutionException, InterruptedException, ServletException {
final Map<String, BroadcastMessage> cache = new HashMap<String, BroadcastMessage>();
broadcaster.getBroadcasterConfig().setBroadcasterCache(new AbstractBroadcasterCache() {
@Override
public CacheMessage addToCache(String id, String uuid, BroadcastMessage e) {
CacheMessage c = put(e, System.nanoTime(), uuid, broadcaster.getID());
cache.put(id, e);
return c;
}
@Override
public List<Object> retrieveFromCache(String id, String uuid) {
ArrayList<Object> cacheContents = new ArrayList<Object>();
if (!cache.isEmpty()) {
cacheContents.add(cache.get(id).message());
cache.clear();
}
return cacheContents;
}
});
final AtmosphereResourceImpl ar = new AtmosphereResourceImpl(new AtmosphereFramework().getAtmosphereConfig(), broadcaster, mock(AtmosphereRequestImpl.class), AtmosphereResponseImpl.newInstance(), mock(Servlet30CometSupport.class), new AR());
final String message = "foo";
Runnable broadcastRunnable = new Runnable() {
@Override
public void run() {
try {
broadcaster.broadcast(message).get();
} catch (InterruptedException ex) {
Logger.getLogger(DefaultBroadcasterTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(DefaultBroadcasterTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
Runnable pollRunnable = new Runnable() {
@Override
public void run() {
broadcaster.addAtmosphereResource(ar);
}
};
int remainingTest = 10;
ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(2);
while (remainingTest > 0) {
remainingTest--;
Future<?> pollFuture = newFixedThreadPool.submit(pollRunnable);
Future<?> broadcastFuture = newFixedThreadPool.submit(broadcastRunnable);
broadcastFuture.get();
pollFuture.get();
Object eventMessage = ar.getAtmosphereResourceEvent().getMessage();
Object retrievedMessage;
if (eventMessage instanceof List) {
retrievedMessage = ((List) eventMessage).get(0);
} else {
retrievedMessage = eventMessage;
}
//cleanup
broadcaster.removeAtmosphereResource(ar);
cache.clear();
//System.out.println(iterations++ + ": message:" + retrievedMessage);
assertEquals(retrievedMessage, message);
}
}
use of org.atmosphere.cache.CacheMessage in project atmosphere by Atmosphere.
the class BroadcasterCacheTest method testRejectedCache.
@Test
public void testRejectedCache() throws ExecutionException, InterruptedException, ServletException {
broadcaster.getBroadcasterConfig().setBroadcasterCache(new AbstractBroadcasterCache() {
@Override
public CacheMessage addToCache(String id, String uuid, BroadcastMessage e) {
CacheMessage c = put(e, System.nanoTime(), uuid, broadcaster.getID());
cachedMessage.set(messages);
return c;
}
@Override
public List<Object> retrieveFromCache(String id, String uuid) {
return Collections.<Object>emptyList();
}
}).getBroadcasterCache().inspector(new BroadcasterCacheInspector() {
@Override
public boolean inspect(BroadcastMessage message) {
return false;
}
});
broadcaster.broadcast("foo", ar).get();
assertEquals(cachedMessage.get().size(), 0);
}
Aggregations