60 lines
3.3 KiB
Markdown
60 lines
3.3 KiB
Markdown
# HTTP Client Total Deadline Implementation Plan
|
|
|
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this
|
|
> plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. Repository policy is
|
|
> human-only, so no step stages or commits changes.
|
|
|
|
**Goal:** Enforce `CallBudget` across the legacy HTTP logical call, including retry wait and blocking
|
|
I/O, and cancel the executing task when the absolute monotonic deadline wins.
|
|
|
|
**Architecture:** Preserve the current migration facade but inject a bounded executor owned by each
|
|
client. Every call intersects the caller budget with the configured maximum, passes the same
|
|
absolute deadline to retry policy, waits through `Future.get(remaining)`, and cancels on timeout or
|
|
shutdown. This is R1 cancellation evidence, not Apache pool or hard-wire-cancellation R2 evidence.
|
|
|
|
**Tech Stack:** Java 21 virtual-thread executor, Spring RestClient/JDK HttpClient, Resilience4j,
|
|
JUnit loopback HTTP server.
|
|
|
|
---
|
|
|
|
### Task 1: Add deadline execution and explicit timeout vocabulary
|
|
|
|
**Files:**
|
|
- Create: `src/adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/OutboundCallDeadlineExceededException.java`
|
|
- Create: `src/adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/OutboundCallExecutor.java`
|
|
- Test: `src/adapter/outbound/httpclient/src/test/java/dev/caskeleton/adapter/outbound/httpclient/OutboundCallExecutorTest.java`
|
|
|
|
- [x] Write failing tests proving an expired budget does not start work, a running task is
|
|
interrupted on expiry, and completion wins before the deadline.
|
|
- [x] Confirm RED.
|
|
- [x] Implement absolute monotonic remaining-time calculation, `Future.get`, cancellation and
|
|
exact exception mapping.
|
|
- [x] Confirm GREEN.
|
|
|
|
### Task 2: Connect the budget to buffered and streaming calls
|
|
|
|
**Files:**
|
|
- Modify: `src/adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/OutboundHttpClient.java`
|
|
- Modify: `src/adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/OutboundRetryPolicy.java`
|
|
- Test: `src/adapter/outbound/httpclient/src/test/java/dev/caskeleton/adapter/outbound/httpclient/OutboundHttpClientDeadlineTest.java`
|
|
|
|
- [x] Write a failing loopback test where response delay exceeds the budget and confirm bounded
|
|
return; record that JDK-provider server-side hard close is not proven by this lane.
|
|
- [x] Write a failing test proving a shorter caller budget wins and retry cannot start after expiry.
|
|
- [x] Confirm RED.
|
|
- [x] Add overloads accepting `CallBudget`; existing methods create a configured maximum budget.
|
|
Intersect budgets once and use the same deadline for retry and blocking execution.
|
|
- [x] Confirm GREEN and run the complete HTTP leaf tests.
|
|
|
|
### Task 3: Record provider limits and verify
|
|
|
|
**Files:**
|
|
- Modify: `src/adapter/outbound/httpclient/README.md`
|
|
- Modify: `src/adapter/outbound/httpclient/CLAUDE.md`
|
|
- Modify: `docs/superpowers/specs/2026-07-27-httpclient-production-capability-design.md`
|
|
|
|
- [x] Record active logical-call deadline/cancellation as implemented.
|
|
- [x] Keep explicit pool lease, Apache exact provider, DNS rebinding, TLS/auth/proxy and R2 hard
|
|
cancellation evidence unimplemented.
|
|
- [x] Run the HTTP leaf check and architecture/public-path gates.
|