Skip to content

Commit ecf7a66

Browse files
authored
Merge pull request #475 from iExecBlockchainComputing/hotfix/fix-initialized2Running-deadlock
Fix `initialized2Running`
2 parents 8252d86 + 56e7901 commit ecf7a66

File tree

5 files changed

+140
-5
lines changed

5 files changed

+140
-5
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version=6.4.1
1+
version=6.4.2
22
iexecCommonVersion=5.8.0
33
nexusUser=fake
44
nexusPassword=fake

src/main/java/com/iexec/core/replicate/ReplicatesService.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,18 @@ public int getNbReplicatesWithCurrentStatus(String chainTaskId, ReplicateStatus.
141141
return nbReplicates;
142142
}
143143

144+
public int getNbReplicatesWithLastRelevantStatus(String chainTaskId, ReplicateStatus... listStatus) {
145+
int nbReplicates = 0;
146+
for (Replicate replicate : getReplicates(chainTaskId)) {
147+
for (ReplicateStatus status : listStatus) {
148+
if (Objects.equals(replicate.getLastRelevantStatus().orElse(null), status)) {
149+
nbReplicates++;
150+
}
151+
}
152+
}
153+
return nbReplicates;
154+
}
155+
144156
public int getNbReplicatesContainingStatus(String chainTaskId, ReplicateStatus... listStatus) {
145157
Set<String> addressReplicates = new HashSet<>();
146158
for (Replicate replicate : getReplicates(chainTaskId)) {

src/main/java/com/iexec/core/task/TaskUpdateManager.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,26 @@ void initializing2Initialized(Task task) {
251251

252252
void initialized2Running(Task task) {
253253
String chainTaskId = task.getChainTaskId();
254-
boolean condition1 = replicatesService.getNbReplicatesWithCurrentStatus(chainTaskId, ReplicateStatus.STARTING, ReplicateStatus.COMPUTED) > 0;
254+
255+
// We explicitly exclude START_FAILED as it could denote some serious issues
256+
// The task should not transition to `RUNNING` in this case.
257+
final ReplicateStatus[] acceptableStatus = new ReplicateStatus[]{
258+
ReplicateStatus.STARTED,
259+
ReplicateStatus.APP_DOWNLOADING,
260+
ReplicateStatus.APP_DOWNLOAD_FAILED,
261+
ReplicateStatus.APP_DOWNLOADED,
262+
ReplicateStatus.DATA_DOWNLOADING,
263+
ReplicateStatus.DATA_DOWNLOAD_FAILED,
264+
ReplicateStatus.DATA_DOWNLOADED,
265+
ReplicateStatus.COMPUTING,
266+
ReplicateStatus.COMPUTE_FAILED,
267+
ReplicateStatus.COMPUTED,
268+
ReplicateStatus.CONTRIBUTING,
269+
ReplicateStatus.CONTRIBUTE_FAILED,
270+
ReplicateStatus.CONTRIBUTED
271+
};
272+
final int nbReplicatesContainingStartingStatus = replicatesService.getNbReplicatesWithLastRelevantStatus(chainTaskId, acceptableStatus);
273+
boolean condition1 = nbReplicatesContainingStartingStatus > 0;
255274
boolean condition2 = task.getCurrentStatus().equals(INITIALIZED);
256275

257276
if (condition1 && condition2) {

src/test/java/com/iexec/core/replicate/ReplicateServiceTests.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,61 @@ public void shouldGetCorrectNbReplicatesWithMultipleStatus() {
259259

260260
}
261261

262+
@Test
263+
public void shouldGetCorrectNbReplicatesWithOneLastRelevantStatus() {
264+
Replicate replicate1 = new Replicate(WALLET_WORKER_1, CHAIN_TASK_ID);
265+
replicate1.updateStatus(STARTING, ReplicateStatusModifier.WORKER);
266+
replicate1.updateStatus(COMPUTED, ReplicateStatusModifier.WORKER);
267+
Replicate replicate2 = new Replicate(WALLET_WORKER_2, CHAIN_TASK_ID);
268+
replicate2.updateStatus(STARTING, ReplicateStatusModifier.WORKER);
269+
Replicate replicate3 = new Replicate(WALLET_WORKER_3, CHAIN_TASK_ID);
270+
replicate3.updateStatus(STARTING, ReplicateStatusModifier.WORKER);
271+
Replicate replicate4 = new Replicate(WALLET_WORKER_4, CHAIN_TASK_ID);
272+
replicate4.updateStatus(STARTING, ReplicateStatusModifier.WORKER);
273+
replicate4.updateStatus(WORKER_LOST, ReplicateStatusModifier.WORKER);
274+
275+
ReplicatesList replicatesList = new ReplicatesList(CHAIN_TASK_ID, Arrays.asList(replicate1, replicate2, replicate3, replicate4));
276+
277+
when(replicatesRepository.findByChainTaskId(CHAIN_TASK_ID)).thenReturn(Optional.of(replicatesList));
278+
279+
assertThat(replicatesService.getNbReplicatesWithLastRelevantStatus(CHAIN_TASK_ID, STARTING)).isEqualTo(3);
280+
assertThat(replicatesService.getNbReplicatesWithLastRelevantStatus(CHAIN_TASK_ID, COMPUTED)).isEqualTo(1);
281+
assertThat(replicatesService.getNbReplicatesWithLastRelevantStatus(CHAIN_TASK_ID, CONTRIBUTED)).isEqualTo(0);
282+
}
283+
284+
@Test
285+
public void shouldGetCorrectNbReplicatesWithMultipleLastReleveantStatus() {
286+
Replicate replicate1 = new Replicate(WALLET_WORKER_1, CHAIN_TASK_ID);
287+
replicate1.updateStatus(STARTING, ReplicateStatusModifier.WORKER);
288+
replicate1.updateStatus(COMPUTED, ReplicateStatusModifier.WORKER);
289+
Replicate replicate2 = new Replicate(WALLET_WORKER_2, CHAIN_TASK_ID);
290+
replicate2.updateStatus(STARTING, ReplicateStatusModifier.WORKER);
291+
Replicate replicate3 = new Replicate(WALLET_WORKER_3, CHAIN_TASK_ID);
292+
replicate3.updateStatus(STARTING, ReplicateStatusModifier.WORKER);
293+
Replicate replicate4 = new Replicate(WALLET_WORKER_4, CHAIN_TASK_ID);
294+
replicate4.updateStatus(STARTING, ReplicateStatusModifier.WORKER);
295+
replicate4.updateStatus(COMPUTED, ReplicateStatusModifier.WORKER);
296+
replicate4.updateStatus(CONTRIBUTED, ReplicateStatusModifier.WORKER);
297+
Replicate replicate5 = new Replicate(WALLET_WORKER_4, CHAIN_TASK_ID);
298+
replicate5.updateStatus(STARTING, ReplicateStatusModifier.WORKER);
299+
replicate5.updateStatus(RECOVERING, ReplicateStatusModifier.WORKER);
300+
301+
ReplicatesList replicatesList = new ReplicatesList(CHAIN_TASK_ID, Arrays.asList(replicate1, replicate2, replicate3, replicate4, replicate5));
302+
303+
when(replicatesRepository.findByChainTaskId(CHAIN_TASK_ID)).thenReturn(Optional.of(replicatesList));
304+
305+
int shouldBe2 = replicatesService.getNbReplicatesWithLastRelevantStatus(CHAIN_TASK_ID, COMPUTED, CONTRIBUTED);
306+
assertThat(shouldBe2).isEqualTo(2);
307+
308+
int shouldBe3 = replicatesService.getNbReplicatesWithLastRelevantStatus(CHAIN_TASK_ID, STARTING, COMPUTED);
309+
assertThat(shouldBe3).isEqualTo(4);
310+
311+
int shouldBe4 = replicatesService.getNbReplicatesWithLastRelevantStatus(CHAIN_TASK_ID, STARTING, COMPUTED,
312+
CONTRIBUTED);
313+
assertThat(shouldBe4).isEqualTo(5);
314+
315+
}
316+
262317
@Test
263318
public void shouldGetCorrectNbReplicatesContainingOneStatus() {
264319
Replicate replicate1 = new Replicate(WALLET_WORKER_1, CHAIN_TASK_ID);

src/test/java/com/iexec/core/task/TaskUpdateManagerTest.java

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,24 @@ public void shouldUpdateInitialized2Running() { // 1 RUNNING out of 2
409409
Task task = getStubTask(maxExecutionTime);
410410
task.changeStatus(INITIALIZED);
411411

412-
when(replicatesService.getNbReplicatesWithCurrentStatus(task.getChainTaskId(), ReplicateStatus.STARTING, ReplicateStatus.COMPUTED)).thenReturn(2);
412+
final ReplicateStatus[] acceptableStatus = new ReplicateStatus[]{
413+
ReplicateStatus.STARTED,
414+
ReplicateStatus.APP_DOWNLOADING,
415+
ReplicateStatus.APP_DOWNLOAD_FAILED,
416+
ReplicateStatus.APP_DOWNLOADED,
417+
ReplicateStatus.DATA_DOWNLOADING,
418+
ReplicateStatus.DATA_DOWNLOAD_FAILED,
419+
ReplicateStatus.DATA_DOWNLOADED,
420+
ReplicateStatus.COMPUTING,
421+
ReplicateStatus.COMPUTE_FAILED,
422+
ReplicateStatus.COMPUTED,
423+
ReplicateStatus.CONTRIBUTING,
424+
ReplicateStatus.CONTRIBUTE_FAILED,
425+
ReplicateStatus.CONTRIBUTED
426+
};
427+
428+
when(replicatesService.getNbReplicatesWithLastRelevantStatus(task.getChainTaskId(), acceptableStatus))
429+
.thenReturn(2);
413430
when(replicatesService.getNbReplicatesWithCurrentStatus(task.getChainTaskId(), ReplicateStatus.COMPUTED)).thenReturn(0);
414431
when(taskRepository.save(task)).thenReturn(task);
415432
when(taskService.getTaskByChainTaskId(CHAIN_TASK_ID)).thenReturn(Optional.of(task));
@@ -1420,9 +1437,25 @@ public void shouldWaitUpdateReplicateStatusFromUnsetToContributed() {
14201437
public void shouldUpdateTaskToRunningFromWorkersInRunning() {
14211438
Task task = getStubTask(maxExecutionTime);
14221439
task.changeStatus(INITIALIZED);
1440+
final ReplicateStatus[] acceptableStatus = new ReplicateStatus[]{
1441+
ReplicateStatus.STARTED,
1442+
ReplicateStatus.APP_DOWNLOADING,
1443+
ReplicateStatus.APP_DOWNLOAD_FAILED,
1444+
ReplicateStatus.APP_DOWNLOADED,
1445+
ReplicateStatus.DATA_DOWNLOADING,
1446+
ReplicateStatus.DATA_DOWNLOAD_FAILED,
1447+
ReplicateStatus.DATA_DOWNLOADED,
1448+
ReplicateStatus.COMPUTING,
1449+
ReplicateStatus.COMPUTE_FAILED,
1450+
ReplicateStatus.COMPUTED,
1451+
ReplicateStatus.CONTRIBUTING,
1452+
ReplicateStatus.CONTRIBUTE_FAILED,
1453+
ReplicateStatus.CONTRIBUTED
1454+
};
14231455

14241456
when(taskService.getTaskByChainTaskId(CHAIN_TASK_ID)).thenReturn(Optional.of(task));
1425-
when(replicatesService.getNbReplicatesWithCurrentStatus(CHAIN_TASK_ID, ReplicateStatus.STARTING, ReplicateStatus.COMPUTED)).thenReturn(3);
1457+
when(replicatesService.getNbReplicatesWithLastRelevantStatus(task.getChainTaskId(), acceptableStatus))
1458+
.thenReturn(3);
14261459
when(replicatesService.getNbReplicatesWithCurrentStatus(CHAIN_TASK_ID, ReplicateStatus.COMPUTED)).thenReturn(0);
14271460

14281461
taskUpdateManager.updateTask(task.getChainTaskId());
@@ -1434,9 +1467,25 @@ public void shouldUpdateTaskToRunningFromWorkersInRunning() {
14341467
public void shouldUpdateTaskToRunningFromWorkersInRunningAndComputed() {
14351468
Task task = getStubTask(maxExecutionTime);
14361469
task.changeStatus(INITIALIZED);
1470+
final ReplicateStatus[] acceptableStatus = new ReplicateStatus[]{
1471+
ReplicateStatus.STARTED,
1472+
ReplicateStatus.APP_DOWNLOADING,
1473+
ReplicateStatus.APP_DOWNLOAD_FAILED,
1474+
ReplicateStatus.APP_DOWNLOADED,
1475+
ReplicateStatus.DATA_DOWNLOADING,
1476+
ReplicateStatus.DATA_DOWNLOAD_FAILED,
1477+
ReplicateStatus.DATA_DOWNLOADED,
1478+
ReplicateStatus.COMPUTING,
1479+
ReplicateStatus.COMPUTE_FAILED,
1480+
ReplicateStatus.COMPUTED,
1481+
ReplicateStatus.CONTRIBUTING,
1482+
ReplicateStatus.CONTRIBUTE_FAILED,
1483+
ReplicateStatus.CONTRIBUTED
1484+
};
14371485

14381486
when(taskService.getTaskByChainTaskId(CHAIN_TASK_ID)).thenReturn(Optional.of(task));
1439-
when(replicatesService.getNbReplicatesWithCurrentStatus(CHAIN_TASK_ID, ReplicateStatus.STARTING, ReplicateStatus.COMPUTED)).thenReturn(4);
1487+
when(replicatesService.getNbReplicatesWithLastRelevantStatus(task.getChainTaskId(), acceptableStatus))
1488+
.thenReturn(4);
14401489
when(replicatesService.getNbReplicatesWithCurrentStatus(CHAIN_TASK_ID, ReplicateStatus.COMPUTED)).thenReturn(2);
14411490

14421491
taskUpdateManager.updateTask(task.getChainTaskId());

0 commit comments

Comments
 (0)