router
router copied to clipboard
fix(http): correct Tower service usage and preserve backpressure
Summary
Fixed incorrect Tower service usage in the HTTP client that was breaking backpressure flow control. The service was consuming itself on each call instead of being reusable, which violates Tower's service patterns and could lead to connection issues.
Problem
The HTTP client service was incorrectly using Tower's call() method which consumes the service, making it unusable for subsequent requests. This breaks Tower's backpressure mechanism that services rely on for proper flow control. Without proper service reuse, each request created unnecessary overhead and could lead to connection problems when making requests to subgraph services.
Solution
Implemented proper Tower service patterns with concurrent caching:
- Added service caching in
HttpClientServiceFactoryusingDashMapfor lock-free concurrent access - Used
ServiceBuilderwith buffered cloning to maintain proper backpressure while enabling service reuse - Changed subgraph service from
call()tooneshot()for correct Tower service consumption - Added tests that cover cache hits, misses, and service isolation by name
Technical Details
The implementation ensures Tower services follow their intended patterns:
- Backpressure Preservation: Services are cached and reused rather than consumed, maintaining flow control through the service chain
- Concurrent Access:
DashMapprovides thread-safe caching without blocking or lock contention - Service Lifecycle: Buffered cloning allows multiple concurrent requests while preserving proper Tower service semantics
Review Strategy
- Service Lifecycle: Examine
HttpClientServiceFactory::create()method for proper caching and service creation logic - Tower Patterns: Verify the change from
call()tooneshot()in subgraph service interaction follows Tower conventions - Backpressure Flow: Check that buffered services properly propagate
poll_readysignals through the service chain - API Compatibility: Confirm constructor changes don't break existing
HttpClientServiceFactoryusage patterns - Test Coverage: Review
test_service_caching()for adequate validation of caching behavior
Checklist
Complete the checklist (and note appropriate exceptions) before the PR is marked ready-for-review.
- [ ] Changes are compatible[^1]
- [ ] Documentation[^2] completed
- [ ] Performance impact assessed and acceptable
- [ ] Metrics and logs are added[^3] and documented
- Tests added and passing[^4]
- [ ] Unit Tests
- [ ] Integration Tests
- [ ] Manual Tests
Exceptions
Note any exceptions here
Notes
[^1]: It may be appropriate to bring upcoming changes to the attention of other (impacted) groups. Please endeavour to do this before seeking PR approval. The mechanism for doing this will vary considerably, so use your judgement as to how and when to do this.
[^2]: Configuration is an important part of many changes. Where applicable please try to document configuration examples.
[^3]: A lot of (if not most) features benefit from built-in observability and debug-level logs. Please read this guidance on metrics best-practices.
[^4]: Tick whichever testing boxes are applicable. If you are adding Manual Tests, please document the manual testing (extensively) in the Exceptions.
@BrynCooke, please consider creating a changeset entry in /.changesets/. These instructions describe the process and tooling.
✅ Docs preview ready
The preview is ready to be viewed. View the preview
File Changes
0 new, 4 changed, 0 removed
* (developer-tools)/apollo-mcp-server/(latest)/command-reference.mdx
* (developer-tools)/apollo-mcp-server/(latest)/guides/index.mdx
* (developer-tools)/rover/ci-cd.mdx
* (developer-tools)/rover/getting-started.mdx
Build ID: 0ed039451fc5ac81a17258e2
URL: https://www.apollographql.com/docs/deploy-preview/0ed039451fc5ac81a17258e2
Oh, I didn't realise http_client_service is only for private plugins, maybe we don't need to mention it then 🙈
Before merging we need to check any plugin that uses http_client_service is not expecting the old way of working.