Files
tech-log-backend/docs/superpowers/plans/2026-07-28-httpclient-total-deadline.md

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.