Skip to content

feat(api): task handler interceptors for cross-cutting concerns (#278) - #313

Draft
emaarco wants to merge 4 commits into
developfrom
emaarco/system-instruction-phase-1
Draft

emaarco wants to merge 4 commits into
developfrom
emaarco/system-instruction-phase-1

Conversation

@emaarco

@emaarco emaarco commented Sep 16, 2026

Copy link
Copy Markdown
Member

Why

Illustrates the interceptor idea for issue #278: cross-cutting concerns (logging, tracing, audit) around every service-task execution, for both registration paths — @ProcessEngineWorker (worker-lib) and manual TaskSubscriptionApi.subscribeForTask(...) — without bean-replacement or AOP.

This is Phase 1 only (the Spring-free core). Draft to make the concept tangible for discussion.

What

New Spring-free core types (api, dev.bpmcrafters.processengineapi.task, @since 1.7):

  • TaskHandlerInterceptor — intercept(context, chain)
  • TaskHandlerInterceptorContext — immutable (taskInformation, payload, taskDescriptionKey, taskType)
  • TaskHandlerInterceptorChain — proceed()

api-impl:

  • InterceptingTaskHandler wraps a TaskHandler in a recursive chain (delegate runs last).
  • AbstractTaskSubscriptionApiImpl gains an optional interceptors: List<TaskHandlerInterceptor> = emptyList() (@JvmOverloads) and wraps cmd.action only when interceptors are present — empty list = unchanged behaviour, zero overhead.

Design notes

  • No Spring in the API. Types + chain execution live in the core; Spring wiring belongs to the adapter starters (Phase 2, separate PRs).
  • Neutral name TaskHandlerInterceptor (not ServiceTaskInterceptor) — it intercepts the TaskHandler of a subscription and applies to EXTERNAL and USER alike; the TaskType is in the context for filtering.
  • Semantics: the interceptor runs in the delivery thread, inside the delivery's try/catch, so an interceptor exception leads to failure handling / retry just like a handler exception.

Not in this PR

  • Phase 2: adapter-starter wiring via ObjectProvider<TaskHandlerInterceptor> (orderedStream()), one PR per adapter repo, after an api release.
  • Phase 3: process-engine-worker needs no code change (goes through subscribeForTask), just a doc note.

Verification

./mvnw clean verify green; new unit tests cover ordering, context content, skipped proceed(), and exception propagation.

Introduce TaskHandlerInterceptor, TaskHandlerInterceptorContext and
TaskHandlerInterceptorChain in the Spring-free core so cross-cutting
concerns (logging, tracing, audit) can wrap every task delivery for
both registration paths (@ProcessEngineWorker and manual subscribe).

AbstractTaskSubscriptionApiImpl optionally wraps the subscription
action in an InterceptingTaskHandler; an empty interceptor list keeps
the current behaviour unchanged.

Refs #278
@codecov

codecov Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.67347% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 53.86%. Comparing base (06b6b3e) to head (c50d8dc).
⚠️ Report is 8 commits behind head on develop.

Files with missing lines Patch % Lines
...afters/processengineapi/task/TaskHandlerOutcome.kt 0.00% 6 Missing ⚠️
...sengineapi/impl/task/TaskHandlerOutcomeRecorder.kt 80.00% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             develop     #313      +/-   ##
=============================================
+ Coverage      50.65%   53.86%   +3.20%     
- Complexity        80      104      +24     
=============================================
  Files             40       45       +5     
  Lines            458      505      +47     
  Branches           9       11       +2     
=============================================
+ Hits             232      272      +40     
- Misses           221      226       +5     
- Partials           5        7       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Interceptors receive a TaskHandlerOutcome from chain.proceed(), so a handler
that fails the task or completes it by BPMN error itself is no longer seen as
a normal return. Adds ACTIVITY_INSTANCE_ID as meta key.

Refs #278

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant