Skip to content

Commit 7e931e8

Browse files
bentshermanjorgeepditommaso
authored
Fix task progress percentage with failed tasks (#5868)
--------- Signed-off-by: Ben Sherman <bentshermann@gmail.com> Signed-off-by: jorgee <jorge.ejarque@seqera.io> Co-authored-by: jorgee <jorge.ejarque@seqera.io> Co-authored-by: Paolo Di Tommaso <paolo.ditommaso@gmail.com>
1 parent ccf5705 commit 7e931e8

File tree

6 files changed

+49
-34
lines changed

6 files changed

+49
-34
lines changed

modules/nextflow/src/main/groovy/nextflow/trace/AnsiLogObserver.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,8 +475,8 @@ class AnsiLogObserver implements TraceObserver {
475475
term.a(Attribute.INTENSITY_FAINT).a(", cached: $stats.cached").reset()
476476
if( stats.stored )
477477
term.a(", stored: $stats.stored")
478-
if( stats.failed )
479-
term.a(", failed: $stats.failed")
478+
if( stats.ignored )
479+
term.a(", ignored: $stats.ignored")
480480
if( stats.retries )
481481
term.a(", retries: $stats.retries")
482482
// Show red cross ('✘') or green tick ('✔') according to status

modules/nextflow/src/main/groovy/nextflow/trace/ProgressRecord.groovy

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class ProgressRecord implements Cloneable {
3838
int running // number of tasks whose execution started
3939
int succeeded // number of tasks whose execution completed successfully
4040
int cached // number of tasks whose execution
41-
int failed
41+
int failed // number of failed tasks -- includes ignored and retried
4242
int aborted
4343
int stored
4444
int ignored
@@ -61,13 +61,15 @@ class ProgressRecord implements Cloneable {
6161
this.taskName = processName
6262
}
6363

64+
// failed tasks that were not retried are included in the total count
6465
int getTotalCount() {
65-
pending+ submitted+ running+
66-
succeeded+ failed+ cached+ stored + aborted
66+
pending + submitted + running +
67+
succeeded + failed - retries + cached + stored + aborted
6768
}
6869

70+
// only failed tasks that were ignored are included in the completed count
6971
int getCompletedCount() {
70-
succeeded+ failed+ cached+ stored
72+
succeeded + ignored + cached + stored
7173
}
7274

7375
@Override

modules/nextflow/src/main/groovy/nextflow/trace/WorkflowStats.groovy

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ class WorkflowStats implements Cloneable {
9797
x >= 0 ? x : 0
9898
}
9999

100+
int getTotalCount() {
101+
gtz(succeededCount + cachedCount + ignoredCount + effectiveFailedCount + abortedCount)
102+
}
103+
100104
String getSucceedCountFmt() {
101105
INTEGER_FMT.format(gtz(succeededCount))
102106
}
@@ -114,23 +118,23 @@ class WorkflowStats implements Cloneable {
114118
}
115119

116120
float getSucceedPct() {
117-
int tot = gtz(succeededCount + cachedCount + ignoredCount + failedCount)
121+
int tot = getTotalCount()
118122
tot ? Math.round(succeededCount / tot * 10000.0 as float) / 100.0 as float : 0
119123
}
120124

121125
float getCachedPct() {
122-
def tot = gtz(succeededCount + cachedCount + ignoredCount + failedCount)
126+
int tot = getTotalCount()
123127
tot ? Math.round(gtz(cachedCount) / tot * 10000.0 as float) / 100.0 as float : 0
124128
}
125129

126130
float getIgnoredPct() {
127-
def tot = gtz(succeededCount + cachedCount + ignoredCount + failedCount)
131+
int tot = getTotalCount()
128132
tot ? Math.round(gtz(ignoredCount) / tot * 10000.0 as float) / 100.0 as float : 0
129133
}
130134

131-
float getFailedPct() {
132-
def tot = gtz(succeededCount + cachedCount + ignoredCount + failedCount)
133-
tot ? Math.round(gtz(failedCount) / tot * 10000.0 as float) / 100.0 as float : 0
135+
float getEffectiveFailedPct() {
136+
int tot = getTotalCount()
137+
tot ? Math.round(gtz(effectiveFailedCount) / tot * 10000.0 as float) / 100.0 as float : 0
134138
}
135139

136140
protected Duration makeDuration(long value) {
@@ -164,10 +168,15 @@ class WorkflowStats implements Cloneable {
164168
int getSucceededCount() { gtz(succeededCount) }
165169

166170
/**
167-
* @return Failed tasks count
171+
* @return Failed tasks count (includes ignored and retried)
168172
*/
169173
int getFailedCount() { gtz(failedCount) }
170174

175+
/**
176+
* @return "Effective" failed tasks count (excludes ignored and retried)
177+
*/
178+
int getEffectiveFailedCount() { gtz(failedCount - ignoredCount - retriesCount) }
179+
171180
/**
172181
* @return Ignored tasks count
173182
*/

modules/nextflow/src/main/resources/nextflow/trace/ReportTemplate.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ <h4>Workflow execution completed unsuccessfully!</h4>
145145
<div class="progress" style="height: 1.6rem; margin: 1.2rem auto; border-radius: 0.20rem;">
146146
<div style="width: ${workflow.stats.succeedPct}%" class="progress-bar bg-success" data-toggle="tooltip" data-placement="top" title="$workflow.stats.succeedCount tasks succeeded"><span class="text-truncate">&nbsp; $workflow.stats.succeedCount succeeded &nbsp;</span></div>
147147
<div style="width: ${workflow.stats.cachedPct}%" class="progress-bar bg-secondary" data-toggle="tooltip" data-placement="top" title="$workflow.stats.cachedCount tasks were cached"><span class="text-truncate">&nbsp; $workflow.stats.cachedCount cached &nbsp;</span></div>
148-
<div style="width: ${workflow.stats.ignoredPct}%" class="progress-bar bg-warning" data-toggle="tooltip" data-placement="top" title="$workflow.stats.ignoredCount tasks reported and error and were ignored"><span class="text-truncate">&nbsp; $workflow.stats.ignoredCount ignored &nbsp;</span></div>
149-
<div style="width: ${workflow.stats.failedPct}%" class="progress-bar bg-danger" data-toggle="tooltip" data-placement="top" title="$workflow.stats.failedCount tasks failed"><span class="text-truncate">&nbsp; $workflow.stats.failedCount failed &nbsp;</span></div>
148+
<div style="width: ${workflow.stats.ignoredPct}%" class="progress-bar bg-warning" data-toggle="tooltip" data-placement="top" title="$workflow.stats.ignoredCount tasks failed and were ignored"><span class="text-truncate">&nbsp; $workflow.stats.ignoredCount ignored &nbsp;</span></div>
149+
<div style="width: ${workflow.stats.effectiveFailedPct}%" class="progress-bar bg-danger" data-toggle="tooltip" data-placement="top" title="$workflow.stats.effectiveFailedCount tasks failed"><span class="text-truncate">&nbsp; $workflow.stats.effectiveFailedCount failed ($workflow.stats.retriesCount retries) &nbsp;</span></div>
150150
</div>
151151
</dl>
152152

modules/nextflow/src/test/groovy/nextflow/trace/ProgressRecordTest.groovy

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,30 +53,34 @@ class ProgressRecordTest extends Specification {
5353

5454
def 'should get counts' () {
5555
given:
56-
def PENDING =1
57-
def SUBMITTED =2
58-
def RUNNING =3
59-
def SUCCEEDED =4
60-
def FAILED =5
61-
def CACHED =6
62-
def STORED =7
63-
def ABORTED = 8
56+
def PENDING = 1
57+
def SUBMITTED = 2
58+
def RUNNING = 3
59+
def SUCCEEDED = 4
60+
def FAILED = 7
61+
def IGNORED = 5
62+
def RETRIES = 1
63+
def CACHED = 7
64+
def STORED = 8
65+
def ABORTED = 9
6466
and:
6567
def rec = new ProgressRecord(10, 'foo')
6668

6769
when:
68-
rec.pending =PENDING
69-
rec.submitted =SUBMITTED
70-
rec.running =RUNNING
71-
rec.succeeded =SUCCEEDED
72-
rec.failed =FAILED
73-
rec.cached =CACHED
74-
rec.stored =STORED
70+
rec.pending = PENDING
71+
rec.submitted = SUBMITTED
72+
rec.running = RUNNING
73+
rec.succeeded = SUCCEEDED
74+
rec.failed = FAILED
75+
rec.ignored = IGNORED
76+
rec.retries = RETRIES
77+
rec.cached = CACHED
78+
rec.stored = STORED
7579
rec.aborted = ABORTED
7680

7781
then:
78-
rec.getCompletedCount() == SUCCEEDED+ FAILED+ CACHED+ STORED
79-
rec.getTotalCount() == PENDING+ SUBMITTED+ RUNNING + SUCCEEDED+ FAILED+ CACHED+ STORED+ ABORTED
82+
rec.getCompletedCount() == SUCCEEDED + IGNORED + CACHED + STORED
83+
rec.getTotalCount() == PENDING + SUBMITTED + RUNNING + SUCCEEDED + FAILED - RETRIES + CACHED + STORED + ABORTED
8084
}
8185

8286

modules/nextflow/src/test/groovy/nextflow/trace/WorkflowStatsTest.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,13 @@ class WorkflowStatsTest extends Specification {
166166

167167
def 'should return task percents' () {
168168
given:
169-
def stats = new WorkflowStats(succeededCount: 20, cachedCount: 40, ignoredCount: 60, failedCount: 80)
169+
def stats = new WorkflowStats(succeededCount: 20, cachedCount: 40, ignoredCount: 60, failedCount: 140)
170170

171171
expect:
172172
stats.getSucceedPct() == 10.0f
173173
stats.getCachedPct() == 20.0f
174174
stats.getIgnoredPct() == 30.0f
175-
stats.getFailedPct() == 40.0f
175+
stats.getEffectiveFailedPct() == 40.0f
176176

177177
}
178178

0 commit comments

Comments
 (0)