[Major] Fixed StrolchJob's synchronization
This commit is contained in:
parent
294ddecf2d
commit
f4162541be
|
@ -48,6 +48,8 @@ public abstract class StrolchJob implements Runnable, Restrictable {
|
||||||
|
|
||||||
protected static final Logger logger = LoggerFactory.getLogger(StrolchJob.class);
|
protected static final Logger logger = LoggerFactory.getLogger(StrolchJob.class);
|
||||||
|
|
||||||
|
private final Object mutex;
|
||||||
|
|
||||||
private final StrolchAgent agent;
|
private final StrolchAgent agent;
|
||||||
private final String id;
|
private final String id;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
@ -76,6 +78,7 @@ public abstract class StrolchJob implements Runnable, Restrictable {
|
||||||
private ZonedDateTime cronStartDate;
|
private ZonedDateTime cronStartDate;
|
||||||
|
|
||||||
public StrolchJob(StrolchAgent agent, String id, String name, JobMode jobMode) {
|
public StrolchJob(StrolchAgent agent, String id, String name, JobMode jobMode) {
|
||||||
|
this.mutex = new Object();
|
||||||
this.agent = agent;
|
this.agent = agent;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -142,38 +145,6 @@ public abstract class StrolchJob implements Runnable, Restrictable {
|
||||||
return this.agent;
|
return this.agent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getInitialDelay() {
|
|
||||||
return this.initialDelay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInitialDelay(long initialDelay) {
|
|
||||||
this.initialDelay = initialDelay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeUnit getInitialDelayTimeUnit() {
|
|
||||||
return this.initialDelayTimeUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInitialDelayTimeUnit(TimeUnit initialDelayTimeUnit) {
|
|
||||||
this.initialDelayTimeUnit = initialDelayTimeUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getDelay() {
|
|
||||||
return this.delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDelay(long delay) {
|
|
||||||
this.delay = delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeUnit getDelayTimeUnit() {
|
|
||||||
return this.delayTimeUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDelayTimeUnit(TimeUnit delayTimeUnit) {
|
|
||||||
this.delayTimeUnit = delayTimeUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ComponentContainer getContainer() {
|
protected ComponentContainer getContainer() {
|
||||||
return getAgent().getContainer();
|
return getAgent().getContainer();
|
||||||
}
|
}
|
||||||
|
@ -234,7 +205,7 @@ public abstract class StrolchJob implements Runnable, Restrictable {
|
||||||
*
|
*
|
||||||
* @return the newly created transaction
|
* @return the newly created transaction
|
||||||
*/
|
*/
|
||||||
protected synchronized StrolchTransaction openTx(Certificate cert) {
|
protected StrolchTransaction openTx(Certificate cert) {
|
||||||
StrolchRealm realm = getContainer().getRealm(cert);
|
StrolchRealm realm = getContainer().getRealm(cert);
|
||||||
this.realmName = realm.getRealm();
|
this.realmName = realm.getRealm();
|
||||||
return realm.openTx(cert, this.getClass(), false);
|
return realm.openTx(cert, this.getClass(), false);
|
||||||
|
@ -248,7 +219,7 @@ public abstract class StrolchJob implements Runnable, Restrictable {
|
||||||
*
|
*
|
||||||
* @return the newly created transaction
|
* @return the newly created transaction
|
||||||
*/
|
*/
|
||||||
protected synchronized StrolchTransaction openTx(Certificate cert, boolean readOnly) {
|
protected StrolchTransaction openTx(Certificate cert, boolean readOnly) {
|
||||||
StrolchRealm realm = getContainer().getRealm(cert);
|
StrolchRealm realm = getContainer().getRealm(cert);
|
||||||
this.realmName = realm.getRealm();
|
this.realmName = realm.getRealm();
|
||||||
return realm.openTx(cert, this.getClass(), readOnly);
|
return realm.openTx(cert, this.getClass(), readOnly);
|
||||||
|
@ -257,22 +228,25 @@ public abstract class StrolchJob implements Runnable, Restrictable {
|
||||||
/**
|
/**
|
||||||
* Executes this job now, but if the job is currently running, then it is blocked till the job is complete
|
* Executes this job now, but if the job is currently running, then it is blocked till the job is complete
|
||||||
*/
|
*/
|
||||||
public synchronized void runNow() throws Exception {
|
public void runNow() throws Exception {
|
||||||
doWork();
|
doWork();
|
||||||
schedule();
|
schedule();
|
||||||
if (this.lastException != null)
|
if (this.lastException != null)
|
||||||
throw this.lastException;
|
throw this.lastException;
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void doWork() {
|
private void doWork() {
|
||||||
this.running = true;
|
synchronized (this.mutex) {
|
||||||
|
if (this.running)
|
||||||
|
throw new IllegalStateException("Already running!");
|
||||||
|
this.running = true;
|
||||||
|
}
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
runAsAgent(this::execute);
|
runAsAgent(this::execute);
|
||||||
this.lastException = null;
|
this.lastException = null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
this.running = false;
|
|
||||||
this.lastException = e;
|
this.lastException = e;
|
||||||
logger.error("Execution of Job " + getName() + " failed.", e);
|
logger.error("Execution of Job " + getName() + " failed.", e);
|
||||||
|
|
||||||
|
@ -284,14 +258,17 @@ public abstract class StrolchJob implements Runnable, Restrictable {
|
||||||
LogMessageState.Information, ResourceBundle.getBundle("strolch-agent"),
|
LogMessageState.Information, ResourceBundle.getBundle("strolch-agent"),
|
||||||
"job.failed").withException(e).value("jobName", getClass().getName()).value("reason", e));
|
"job.failed").withException(e).value("jobName", getClass().getName()).value("reason", e));
|
||||||
}
|
}
|
||||||
}
|
} finally {
|
||||||
|
long took = System.currentTimeMillis() - start;
|
||||||
|
this.totalDuration += took;
|
||||||
|
this.lastDuration = took;
|
||||||
|
this.lastExecution = ZonedDateTime.now();
|
||||||
|
this.nrOfExecutions++;
|
||||||
|
|
||||||
long took = System.currentTimeMillis() - start;
|
synchronized (this.mutex) {
|
||||||
this.totalDuration += took;
|
this.running = false;
|
||||||
this.lastDuration = took;
|
}
|
||||||
this.running = false;
|
}
|
||||||
this.lastExecution = ZonedDateTime.now();
|
|
||||||
this.nrOfExecutions++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -337,7 +314,7 @@ public abstract class StrolchJob implements Runnable, Restrictable {
|
||||||
*
|
*
|
||||||
* @return this instance for chaining
|
* @return this instance for chaining
|
||||||
*/
|
*/
|
||||||
public synchronized StrolchJob schedule() {
|
public StrolchJob schedule() {
|
||||||
if (this.mode == JobMode.Manual) {
|
if (this.mode == JobMode.Manual) {
|
||||||
logger.info("Not scheduling " + getName() + " as mode is " + this.mode);
|
logger.info("Not scheduling " + getName() + " as mode is " + this.mode);
|
||||||
return this;
|
return this;
|
||||||
|
@ -418,7 +395,7 @@ public abstract class StrolchJob implements Runnable, Restrictable {
|
||||||
return this.getClass().getName();
|
return this.getClass().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized JsonObject toJson() {
|
public JsonObject toJson() {
|
||||||
JsonObject jsonObject = new JsonObject();
|
JsonObject jsonObject = new JsonObject();
|
||||||
|
|
||||||
jsonObject.addProperty(Tags.Json.ID, this.id);
|
jsonObject.addProperty(Tags.Json.ID, this.id);
|
||||||
|
@ -433,7 +410,9 @@ public abstract class StrolchJob implements Runnable, Restrictable {
|
||||||
jsonObject.addProperty("delay", this.delay);
|
jsonObject.addProperty("delay", this.delay);
|
||||||
jsonObject.addProperty("delayTimeUnit", this.delayTimeUnit == null ? "-" : this.delayTimeUnit.name());
|
jsonObject.addProperty("delayTimeUnit", this.delayTimeUnit == null ? "-" : this.delayTimeUnit.name());
|
||||||
|
|
||||||
jsonObject.addProperty("running", this.running);
|
synchronized (this.mutex) {
|
||||||
|
jsonObject.addProperty("running", this.running);
|
||||||
|
}
|
||||||
jsonObject.addProperty("totalDuration", formatMillisecondsDuration(this.totalDuration));
|
jsonObject.addProperty("totalDuration", formatMillisecondsDuration(this.totalDuration));
|
||||||
jsonObject.addProperty("lastDuration", formatMillisecondsDuration(this.lastDuration));
|
jsonObject.addProperty("lastDuration", formatMillisecondsDuration(this.lastDuration));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue