Repository navigation
Conversation
Signed-off-by: Meha Bhargava <meha.bhargava2@gmail.com>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Coverage variation | ✅ +0.14% coverage variation (-1.00%) |
| Diff coverage | ✅ 85.71% diff coverage (70.00%) |
Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (444f433) Report Missing Report Missing Report Missing Head commit (87ac7c0) 42868 (+31) 37291 (+89) 86.99% (+0.14%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>
Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#6741) 35 30 85.71% Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
1 Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
nscuro
left a comment
There was a problem hiding this comment.
Thanks for the PR!
The heartbeating itself looks good, but I think we can make the deadline portion a bit cleaner, such that it can work for all activities.
In ActivityTaskWorker, task execution is offloaded to a (virtual) thread:
The Future returned by the above submit is then "awaited" via Future#get, and the task's outcome is recorded via engine.onTaskEvent:
Future#get accepts a timeout via Future#get(long, TimeUnit). This is where the deadline should go. The invocation will throw a TimeoutException if the deadline is exceeded. When this happens, we cancel the Future, which will interrupt its thread.
Something like this:
final Duration executionTimeout = activityMetadata.executionTimeout();
try {
final Object activityResult = executionTimeout != null
? future.get(executionTimeout.toMillis(), TimeUnit.MILLISECONDS)
: future.get();
// ...
} catch (TimeoutException e) {
future.cancel(/* interruptIfRunning */ true);
// Report failure, computeRetryAt, etc.
} catch (ExecutionException e) {
// ...
} catch (InterruptedException e) {
// ...
}The benefit is that interruption will also work when the activity is blocked on I/O (e.g. DB queries) and activity doesn't have to actively check "did I exceed my deadline?"
Signed-off-by: Meha Bhargava <meha.bhargava2@gmail.com>
…tion properties if not set by users Signed-off-by: Meha Bhargava <meha.bhargava2@gmail.com>
Signed-off-by: Meha Bhargava <meha.bhargava2@gmail.com>
|
@mehab In light of #6795 I've been thinking about solving the heartbeating differently. As it is right now, heartbeating needs to be invoked manually so I've been thinking to do heartbeats automatically in the background instead, so the manual invocations would disappear entirely. The work in this PR around execution timeouts already solves one part of your problem (activities running too long), so I think it's worth shipping that in isolation, and handle the heartbeating part separately. So my suggestion would be:
The heartbeating would then be an immediate follow-up. WDYT? |
|
Sounds good @nscuro i will check it on tuesday and complete the changes as you suggest with automated heartbeats. The solution is definitely cleaner than heartbeat tracking by all activities manually. |
Signed-off-by: Meha Bhargava <meha.bhargava2@gmail.com>
nscuro
left a comment
There was a problem hiding this comment.
Thanks!
FYI I updated title and description of the PR to reflect the final state, not what was originally proposed.
|
Thanks niklas 😊 |
* changes for issue number: 6740 created upstream Signed-off-by: Meha Bhargava <meha.bhargava2@gmail.com> * addressed reiew comments on PR Signed-off-by: Meha Bhargava <meha.bhargava2@gmail.com> * conig get value is not optional. Its default value comes from application properties if not set by users Signed-off-by: Meha Bhargava <meha.bhargava2@gmail.com> * fixed breaking test Signed-off-by: Meha Bhargava <meha.bhargava2@gmail.com> * addressed pr review comments Signed-off-by: Meha Bhargava <meha.bhargava2@gmail.com> --------- Signed-off-by: Meha Bhargava <meha.bhargava2@gmail.com> (cherry picked from commit 14ba4e3) Signed-off-by: nscuro <nscuro@protonmail.com>
Description
Adds an optional per-attempt execution timeout to dex activities, and enables it for policy evaluation.
Activities may now be registered with an
executionTimeoutin addition to their lock timeout.ActivityTaskWorkerenforces it: when a single attempt exceeds the timeout, the execution is cancelled (thread interrupt) and the task fails, to be retried according to its retry policy, or terminally once attempts are exhausted.The timeout is opt-in. Activities registered without one behave exactly as before. It is enabled for
eval-project-policieswith a default of 10 minutes, configurable viadt.dex.engine.activity.eval-project-policies.execution-timeout-ms, so that an expensive or pathological policy can no longer occupy a worker indefinitely.Addressed Issue
Relates to: #6740
Additional Details
Test case provided for replicating the scenario where no heartbeat and lock time out results in another pod picking up the same task.
https://github.com/mehab/dependency-track/blob/feature/policy-eval-heartbeat-max-duration/apiserver/src/test/java/org/dependencytrack/policy/PolicyEvaluationLockThrashTest.java#L81
Checklist
docs/adr/