Skip to content

Commit 1da7036

Browse files
committed
fix task: atomic update/get fields and re-schedule (#1361)
* atomic update and get task status&result * call resubmitTask() when re-schedule task Change-Id: I2efa9fd4979492c6901e1ae11fbaf2be451f0354
1 parent 0f3be14 commit 1da7036

File tree

3 files changed

+37
-18
lines changed

3 files changed

+37
-18
lines changed

hugegraph-core/src/main/java/com/baidu/hugegraph/task/HugeTask.java

+17-17
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,13 @@ public String result() {
222222
return this.result;
223223
}
224224

225-
private void result(String result) {
225+
private synchronized boolean result(TaskStatus status, String result) {
226226
checkPropertySize(result, P.RESULT);
227-
this.result = result;
227+
if (this.status(status)) {
228+
this.result = result;
229+
return true;
230+
}
231+
return false;
228232
}
229233

230234
public void server(Id server) {
@@ -319,18 +323,17 @@ public boolean fail(Throwable e) {
319323
LOG.warn("An exception occurred when running task: {}",
320324
this.id(), e);
321325
// Update status to FAILED if exception occurred(not interrupted)
322-
if (this.status(TaskStatus.FAILED)) {
323-
this.result(e.toString());
326+
if (this.result(TaskStatus.FAILED, e.toString())) {
324327
return true;
325328
}
326329
}
327330
return false;
328331
}
329332

330-
public void failSave(Throwable e) {
333+
public void failToSave(Throwable e) {
331334
if (!this.fail(e)) {
332335
// Can't update status, just set result to error message
333-
this.result(e.toString());
336+
this.result = e.toString();
334337
}
335338
}
336339

@@ -352,9 +355,7 @@ protected void done() {
352355
protected void set(V v) {
353356
String result = JsonUtil.toJson(v);
354357
checkPropertySize(result, P.RESULT);
355-
if (this.status(TaskStatus.SUCCESS)) {
356-
this.result = result;
357-
} else {
358+
if (!this.result(TaskStatus.SUCCESS, result)) {
358359
assert this.completed();
359360
}
360361
// Will call done() and may cause to save to store
@@ -381,22 +382,21 @@ protected boolean checkDependenciesSuccess() {
381382
if (this.dependencies == null || this.dependencies.isEmpty()) {
382383
return true;
383384
}
385+
TaskScheduler scheduler = this.scheduler();
384386
for (Id dependency : this.dependencies) {
385-
HugeTask<?> task = this.scheduler().task(dependency);
387+
HugeTask<?> task = scheduler.task(dependency);
386388
if (!task.completed()) {
387389
// Dependent task not completed, re-schedule self
388-
this.scheduler().schedule(this);
390+
scheduler.schedule(this);
389391
return false;
390392
} else if (task.status() == TaskStatus.CANCELLED) {
391-
this.status(TaskStatus.CANCELLED);
392-
this.result(String.format(
393+
this.result(TaskStatus.CANCELLED, String.format(
393394
"Cancelled due to dependent task '%s' cancelled",
394395
dependency));
395396
this.done();
396397
return false;
397398
} else if (task.status() == TaskStatus.FAILED) {
398-
this.status(TaskStatus.FAILED);
399-
this.result(String.format(
399+
this.result(TaskStatus.FAILED, String.format(
400400
"Failed due to dependent task '%s' failed",
401401
dependency));
402402
this.done();
@@ -483,7 +483,7 @@ protected void property(String key, Object value) {
483483
}
484484
}
485485

486-
protected Object[] asArray() {
486+
protected synchronized Object[] asArray() {
487487
E.checkState(this.type != null, "Task type can't be null");
488488
E.checkState(this.name != null, "Task name can't be null");
489489

@@ -563,7 +563,7 @@ public Map<String, Object> asMap() {
563563
return this.asMap(true);
564564
}
565565

566-
public Map<String, Object> asMap(boolean withDetails) {
566+
public synchronized Map<String, Object> asMap(boolean withDetails) {
567567
E.checkState(this.type != null, "Task type can't be null");
568568
E.checkState(this.name != null, "Task name can't be null");
569569

hugegraph-core/src/main/java/com/baidu/hugegraph/task/StandardTaskScheduler.java

+19
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,15 @@ private <V> Future<?> restore(HugeTask<V> task) {
205205
public <V> Future<?> schedule(HugeTask<V> task) {
206206
E.checkArgumentNotNull(task, "Task can't be null");
207207

208+
if (task.status() == TaskStatus.QUEUED) {
209+
/*
210+
* Just submit to queue if status=QUEUED (means re-schedule task)
211+
* NOTE: schedule() method may be called multi times by
212+
* HugeTask.checkDependenciesSuccess() method
213+
*/
214+
return this.resubmitTask(task);
215+
}
216+
208217
if (task.callable() instanceof EphemeralJob) {
209218
/*
210219
* Due to EphemeralJob won't be serialized and deserialized through
@@ -252,6 +261,16 @@ private <V> Future<?> submitTask(HugeTask<V> task) {
252261
return this.taskExecutor.submit(task);
253262
}
254263

264+
private <V> Future<?> resubmitTask(HugeTask<V> task) {
265+
E.checkArgument(task.status() == TaskStatus.QUEUED,
266+
"Can't resubmit task '%s' with status %s",
267+
task.id(), TaskStatus.QUEUED);
268+
E.checkArgument(this.tasks.containsKey(task.id()),
269+
"Can't resubmit task '%s' not been submitted before",
270+
task.id());
271+
return this.taskExecutor.submit(task);
272+
}
273+
255274
public <V> void initTaskCallable(HugeTask<V> task) {
256275
task.scheduler(this);
257276

hugegraph-core/src/main/java/com/baidu/hugegraph/task/TaskCallable.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ protected void save() {
117117
e, task.asMap(false));
118118
String message = e.getMessage();
119119
if (message.contains(ERROR_COMMIT) && needSaveWithEx(message)) {
120-
task.failSave(e);
120+
task.failToSave(e);
121121
this.graph().taskScheduler().save(task);
122122
return;
123123
}

0 commit comments

Comments
 (0)