Skip to content

fix(plugin): record execution history for every plugin job run #111

Closed

Description

@fronzec

Problem Description

Execution history in job_executions_audit is incomplete. JobExecutionAuditListener (batchjobs/plugins/listener/JobExecutionAuditListener.java) is a @Component that writes an audit row in beforeJob, but no job registers it with .listener(...), so it never runs. The only writer is JobsManagerService.saveAudit, called after a synchronous single-job run completes (JobsManagerService.java:246); asynchronous runs write no row.

Since #94 / PR #105, DELETE refuses definitions with execution history (409 JobDeleteConflictException). With incomplete history that guard is inconsistent: a definition that only ran asynchronously can be deleted, while one with a single completed synchronous run can never be deleted.

Proposed Solution

Record execution history for every plugin job execution through one path. Options to evaluate:

  • Attach JobExecutionAuditListener to every dynamically loaded plugin job from the host (for example when the job is registered), and remove the after-run saveAudit path so rows are not duplicated.
  • Remove the unused listener and record history for both synchronous and asynchronous launches in JobsManagerService.

Acceptance Criteria

  • Every plugin job execution, synchronous or asynchronous, writes exactly one job_executions_audit row.
  • Unused audit code is removed, or the listener is wired; there is a single writer.
  • Tests cover synchronous and asynchronous launches and assert one row per execution.
  • The delete history guard behaves the same regardless of how the job was launched.

Affected Area

Plugin lifecycle: job execution audit history

Out of Scope

Additional Context

Found while preparing #107 and #108. The premise of #107 was based on the listener writing history at job start; see the correction comment there. #110 describes the race as an execution starting between the history check and the commit; with the current code, the row is written when a synchronous run completes, so the race window is a synchronous run completing during the delete.

Activity

  1. added a commit that references this issue on Oct 17, 2026
    691f343
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions