Skip to content

Commit 9f12900

Browse files
authored
Add retry mechanism and set command status to FAILURE after all attempts failed (#134)
1 parent dcb8a50 commit 9f12900

File tree

4 files changed

+30
-26
lines changed

4 files changed

+30
-26
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.
88

99
- Label REST API with `v1` version. (#132)
1010

11+
### Bug Fixes
12+
13+
- Add retry mechanism and set command status to `FAILURE` after all attempts failed. (#134)
14+
1115
### Quality
1216

1317
- Remove `/tasks/{chainTaskId}` endpoint, the adapter must only call `initialize` and `finalize` **PoCo** methods. (#130)

src/main/java/com/iexec/blockchain/command/generic/CommandEngine.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2023 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2020-2024 IEXEC BLOCKCHAIN TECH
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,6 +27,8 @@
2727
@Slf4j
2828
public abstract class CommandEngine<C extends Command<A>, A extends CommandArgs> {
2929

30+
private static final int MAX_ATTEMPTS = 5;
31+
3032
private final CommandBlockchain<A> blockchainService;
3133
private final CommandStorage<C, A> updaterService;
3234
private final QueueService queueService;
@@ -88,24 +90,24 @@ public void triggerBlockchainCommand(A args) {
8890
chainObjectId, args);
8991
return;
9092
}
93+
int attempt = 0;
9194
log.info("Processing command [chainObjectId:{}, commandArgs:{}]",
9295
chainObjectId, args);
93-
TransactionReceipt receipt;
94-
try {
95-
receipt = blockchainService.sendBlockchainCommand(args);
96-
} catch (Exception e) {
97-
log.error("Something wrong happened while triggering blockchain " +
98-
"command [chainObjectId:{}, commandArgs:{}]",
99-
chainObjectId, args, e);
100-
//TODO Update to proper status: PROCESSING_FAILED or FAILURE
101-
return;
96+
TransactionReceipt receipt = null;
97+
while (attempt < MAX_ATTEMPTS && receipt == null) {
98+
attempt++;
99+
try {
100+
receipt = blockchainService.sendBlockchainCommand(args);
101+
} catch (Exception e) {
102+
log.error("Something wrong happened while triggering command [chainObjectId:{}, commandArgs:{}, attempt:{}]",
103+
chainObjectId, args, attempt, e);
104+
}
102105
}
103106
if (receipt == null) {
104107
log.error("Triggering blockchain command failed " +
105108
"(received null receipt after blockchain send) " +
106-
"[chainObjectId:{}, commandArgs:{}]",
107-
chainObjectId, args);
108-
return;
109+
"[chainObjectId:{}, commandArgs:{}, attempt:{}]",
110+
chainObjectId, args, attempt);
109111
}
110112
updaterService.updateToFinal(chainObjectId, receipt);
111113
}

src/main/java/com/iexec/blockchain/command/generic/CommandStorage.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.iexec.blockchain.command.generic;
1818

1919
import com.iexec.blockchain.api.CommandStatus;
20-
import lombok.NonNull;
2120
import lombok.extern.slf4j.Slf4j;
2221
import org.web3j.protocol.core.methods.response.TransactionReceipt;
2322

@@ -88,26 +87,25 @@ public boolean updateToProcessing(String chainObjectId) {
8887
* @param receipt blockchain receipt
8988
*/
9089
public void updateToFinal(String chainObjectId,
91-
@NonNull TransactionReceipt receipt) {
92-
Optional<C> localCommand = commandRepository
90+
TransactionReceipt receipt) {
91+
final C command = commandRepository
9392
.findByChainObjectId(chainObjectId)
94-
.filter(command -> command.getStatus() == CommandStatus.PROCESSING);
95-
if (localCommand.isEmpty()) {
93+
.filter(cmd -> cmd.getStatus() == CommandStatus.PROCESSING)
94+
.orElse(null);
95+
if (command == null) {
96+
log.error("No entry was found in database, could not update to final state");
9697
return;
9798
}
98-
C command = localCommand.get();
9999

100-
CommandStatus status;
101-
if (receipt.isStatusOK()) {
102-
status = CommandStatus.SUCCESS;
100+
if (receipt != null && receipt.isStatusOK()) {
101+
command.setStatus(CommandStatus.SUCCESS);
103102
log.info("Success command with transaction receipt [chainObjectId:{}, command:{}, receipt:{}]",
104103
chainObjectId, command.getClass().getSimpleName(), receipt);
105104
} else {
106-
status = CommandStatus.FAILURE;
105+
command.setStatus(CommandStatus.FAILURE);
107106
log.info("Failure after transaction sent [chainObjectId:{}, command:{}, receipt:{}]",
108107
chainObjectId, command.getClass().getSimpleName(), receipt);
109108
}
110-
command.setStatus(status);
111109
command.setTransactionReceipt(receipt);
112110
command.setFinalDate(Instant.now());
113111
commandRepository.save(command);

src/test/java/com/iexec/blockchain/command/task/initialize/TaskInitializeTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2021-2023 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2021-2024 IEXEC BLOCKCHAIN TECH
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -123,7 +123,7 @@ void shouldNotTriggerInitializeTaskSinceReceiptIsNull() throws Exception {
123123
.thenReturn(null);
124124

125125
taskInitializeService.triggerBlockchainCommand(args);
126-
verify(updaterService, times(0))
126+
verify(updaterService)
127127
.updateToFinal(CHAIN_TASK_ID, null);
128128
}
129129

0 commit comments

Comments
 (0)