ResultSet oRSet;
int iJobCount;
int nThreads;
String sSQL;
AtomConsumer oCsr = null;
JDCConnection oJcn = null;
if (DebugFile.trace) DebugFile.writeln("Begin SchedulerDaemon.run()");
try {
nThreads = Integer.parseInt(oEnvProps.getProperty("maxschedulerthreads","1"));
} catch (Exception xcpt) { nThreads = 1; }
try {
if (null==oDbb) oDbb = new DBBind(sProfile);
oJcn = oDbb.getConnection("SchedulerDaemon",true);
Event.trigger(oJcn, 1024, "startschedulerdaemon", new HashMap(), oEnvProps);
oJcn.close("SchedulerDaemon");
oDbb.connectionPool().setPoolSize(4*nThreads);
// No more that ten times the number of threads allowed for connections
oDbb.connectionPool().setMaxPoolSize(10*nThreads);
// Create Atom queue.
if (DebugFile.trace) DebugFile.writeln("new AtomQueue()");
oQue = new AtomQueue();
// This object feeds the queue with new atoms
// extracted from the database.
if (DebugFile.trace) DebugFile.writeln("new AtomFeeder()");
AtomFeeder oFdr = new AtomFeeder();
// This is the queue consumer object
// it grants that only one atom is
// poped from the queue at a time.
if (DebugFile.trace) DebugFile.writeln("new AtomConsumer([JDCconnection], [AtomQueue])");
oCsr = new AtomConsumer(oDbb, oQue);
// Create WorkerThreadPool
if (DebugFile.trace) DebugFile.writeln("new WorkerThreadPool([AtomConsumer], [Properties])");
oThreadPool = new WorkerThreadPool(oCsr, oEnvProps);
// Register callbacks on each worker thread
ListIterator oIter = oCallbacks.listIterator();
while (oIter.hasNext())
oThreadPool.registerCallback((WorkerThreadCallback) oIter.next());
dtStartDate = new Date();
do {
try {
while (bContinue) {
oJcn = oDbb.getConnection("SchedulerDaemon");
oJcn.setAutoCommit(true);
// Count how many atoms are pending of processing at the database
oStmt = oJcn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
// ***************************************************
// Finish all the jobs that have no more pending atoms
sSQL = "SELECT j.gu_job FROM k_jobs j WHERE ("+
"j.id_status="+String.valueOf(Job.STATUS_PENDING)+" OR "+
"j.id_status="+String.valueOf(Job.STATUS_RUNNING)+") AND "+
"NOT EXISTS (SELECT a.pg_atom FROM k_job_atoms a WHERE "+
"j.gu_job=a.gu_job AND a.id_status IN ("+
String.valueOf(Atom.STATUS_PENDING)+","+
String.valueOf(Atom.STATUS_RUNNING)+","+
String.valueOf(Atom.STATUS_SUSPENDED)+"))";
if (DebugFile.trace) DebugFile.writeln("Statement.executeQuery("+sSQL+") on connection with process id. "+oJcn.pid());
oRSet = oStmt.executeQuery(sSQL);
LinkedList<String> oFinished = new LinkedList<String>();
while (oRSet.next()) {
oFinished.add(oRSet.getString(1));
} // wend
oRSet.close();
oStmt.close();
if (DebugFile.trace) DebugFile.writeln("Already finished jobs "+String.valueOf(oFinished.size()));
if (oFinished.size()>0) {
sSQL = "UPDATE k_jobs SET id_status="+String.valueOf(Job.STATUS_FINISHED)+",dt_finished="+DBBind.Functions.GETDATE+" WHERE gu_job=?";
if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement("+sSQL+") on connection with process id. "+oJcn.pid());
PreparedStatement oUpdt = oJcn.prepareStatement(sSQL);
oIter = oFinished.listIterator();
while (oIter.hasNext()) {
oUpdt.setObject(1, oIter.next(), java.sql.Types.CHAR);
oUpdt.executeUpdate();
} // wend
oUpdt.close();
} // fi
// ***************************************************
// Count jobs running or pending of begining execution
if (DebugFile.trace) DebugFile.writeln("Statement.executeQuery(SELECT COUNT(*) FROM k_jobs WHERE id_status=" + String.valueOf(Job.STATUS_PENDING) + " AND ("+DB.dt_execution+" IS NULL OR "+DB.dt_execution+"<="+DBBind.Functions.GETDATE+")) on connection with process id. "+oJcn.pid());
iJobCount = DBCommand.queryCount(oJcn, "*", DB.k_jobs, DB.id_status + "=" + String.valueOf(Job.STATUS_RUNNING) + " OR (" + DB.id_status + "=" + String.valueOf(Job.STATUS_PENDING)+" AND ("+DB.dt_execution+" IS NULL OR "+DB.dt_execution+"<="+DBBind.Functions.GETDATE+"))");
oJcn.close("SchedulerDaemon");
if (DebugFile.trace) DebugFile.writeln(String.valueOf(iJobCount) + " pending jobs");
if (0==iJobCount) {
if (DebugFile.trace) DebugFile.writeln("sleep (10000)");
sleep (10000);
}
else {
break;
}
} // wend
if (bContinue) {
try {
oJcn = oDbb.getConnection("SchedulerDaemon.AtomFeeder");
oJcn.setAutoCommit(true);
oFdr.loadAtoms(oJcn, oThreadPool.size());
oFdr.feedQueue(oJcn, oQue);
oJcn.close("SchedulerDaemon.AtomFeeder");
oJcn=null;
} finally {
try { if (null!=oJcn) oJcn.close("SchedulerDaemon.AtomFeeder"); } catch (Exception ignore) { }
}
if (DebugFile.trace) {
DebugFile.writeln("Queue has "+String.valueOf(oQue.size())+" atoms");
}
if (oQue.size()>0) {
oThreadPool.launchAll();
}
do {
if (DebugFile.trace) DebugFile.writeln("sleep (10000)");
sleep(10000);
if (DebugFile.trace) DebugFile.writeln(String.valueOf(oThreadPool.livethreads()) + " live threads");
} while(oThreadPool.livethreads()==oThreadPool.size());
} // fi (bContinue)
}
catch (InterruptedException e) {
if (DebugFile.trace)
DebugFile.writeln("SchedulerDaemon InterruptedException " + e.getMessage());
}
} while (bContinue) ;
if (DebugFile.trace) DebugFile.writeln(" exiting SchedulerDaemon");
oThreadPool.haltAll();
oThreadPool = null;
oCsr.close();
oCsr = null;
oFdr = null;
oQue = null;
if (DebugFile.trace) DebugFile.writeln("JDConnection.close()");
if (oJcn!=null) { if (!oJcn.isClosed()) { oJcn.close("SchedulerDaemon"); } oJcn = null; }
oJcn = oDbb.getConnection("SchedulerDaemon",true);
Event.trigger(oJcn, 1024, "stopschedulerdaemon", new HashMap(), oEnvProps);
oJcn.close("SchedulerDaemon");
oDbb.close();
oDbb=null;
}
catch (Exception e) {
if (DebugFile.trace) {
DebugFile.writeln("SchedulerDaemon " + e.getClass().getName() + " " + e.getMessage());
try {
DebugFile.writeln(StackTraceUtil.getStackTrace(e));
} catch (IOException ignore) {}
DebugFile.writeln("SchedulerDaemon.run() abnormal termination");
}
try {
System.err.println("Hipergate SchedulerDaemon fatal error " + e.getClass().getName() + " " + e.getMessage());
System.err.println(StackTraceUtil.getStackTrace(e));
} catch (IOException ignore) {}
try { oThreadPool.haltAll(); oThreadPool=null; } catch (Exception ignore) {}
try {
if (oJcn!=null) if (!oJcn.isClosed()) oJcn.close("SchedulerDaemon");
} catch (SQLException sqle) {
if (DebugFile.trace) DebugFile.writeln("SchedulerDaemon SQLException on close() " + sqle.getMessage());
}
if (null!=oDbb) { try { oDbb.close(); } catch (Exception ignore) {} }
oJcn = null;