/*
* Copyright 2010 Glencoe Software, Inc. All rights reserved.
* Use is subject to license terms supplied in LICENSE.txt
*/
package ome.services.blitz.util;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import ome.services.blitz.fire.TopicManager;
import ome.services.util.Executor;
import ome.tools.spring.OnContextRefreshedEventListener;
import ome.util.SqlAction;
import omero.constants.categories.PROCESSORCALLBACK;
import omero.constants.topics.PROCESSORACCEPTS;
import omero.grid.ProcessorCallbackPrx;
import omero.grid.ProcessorCallbackPrxHelper;
import omero.grid.ProcessorPrx;
import omero.grid.ProcessorPrxHelper;
import omero.grid._ProcessorCallbackDisp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.transaction.annotation.Transactional;
import Ice.Current;
import Ice.ObjectAdapter;
/**
*
* @author Josh Moore, josh at glencoesoftware.com
* @since Beta4.2
*/
public class CheckAllJobs extends OnContextRefreshedEventListener {
private static final Logger log = LoggerFactory.getLogger(CheckAllJobs.class);
private final Executor ex;
private final ObjectAdapter oa;
private final TopicManager tm;
private final Ice.Identity id;
private final long waitMs;
public CheckAllJobs(Executor ex, ObjectAdapter oa, TopicManager tm) {
this(ex, oa, tm, 10000);
}
public CheckAllJobs(Executor ex, ObjectAdapter oa, TopicManager tm,
long waitMs) {
this.waitMs = waitMs;
this.ex = ex;
this.oa = oa;
this.tm = tm;
this.id = new Ice.Identity(UUID.randomUUID().toString(),
PROCESSORCALLBACK.value);
}
@Override
public void handleContextRefreshedEvent(ContextRefreshedEvent event) {
run();
}
public void run() {
Callback cb = new Callback();
Ice.ObjectPrx prx = oa.add(cb, id); // OK ADAPTER USAGE
ProcessorCallbackPrx cbPrx = ProcessorCallbackPrxHelper.uncheckedCast(prx);
tm.onApplicationEvent(new TopicManager.TopicMessage(this,
PROCESSORACCEPTS.value, new ProcessorPrxHelper(),
"requestRunning", cbPrx));
new Thread() {
@Override
public void run() {
log.info("Waiting " + waitMs / 1000 + " secs. for callbacks");
long start = System.currentTimeMillis();
while (System.currentTimeMillis() < (start + waitMs)) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// ok
}
}
synchronizeJobs();
}
}.start();
}
public void synchronizeJobs() {
final Callback cb = (Callback) oa.find(id);
final List<Long> ids = new ArrayList<Long>();
synchronized (cb.openJobs) {
ids.addAll(cb.openJobs);
}
try {
ex.executeSql(new Executor.SimpleSqlWork(this,
"synchronizeJobs") {
@Transactional(readOnly = false)
public Object doWork(SqlAction sql) {
int count = sql.synchronizeJobs(ids);
if (count > 0) {
log.warn("Forcibly closed " + count
+ " abandoned job(s).");
}
return null;
}
});
} finally {
oa.remove(id); // OK ADAPTER USAGE
}
}
private class Callback extends _ProcessorCallbackDisp {
private final List<Long> openJobs = new ArrayList<Long>();
public void isAccepted(boolean accepted, String sessionUuid,
String proxyConn, Current __current) {
log.error("isAccepted should not have been called");
}
public void isProxyAccepted(boolean accepted, String sessionUuid,
ProcessorPrx procProxy, Current __current) {
log.error("isProxyAccepted should not have been called");
}
public void responseRunning(List<Long> jobIds, Current __current) {
synchronized (openJobs) {
if (jobIds != null) {
log.info("Received " + jobIds.size() + " job(s)");
openJobs.addAll(jobIds);
} else {
log.warn("Null jobIds list sent.");
}
}
}
}
}