router icon indicating copy to clipboard operation
router copied to clipboard

fix(http): correct Tower service usage and preserve backpressure

Open BrynCooke opened this issue 5 months ago • 4 comments

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 HttpClientServiceFactory using DashMap for lock-free concurrent access
  • Used ServiceBuilder with buffered cloning to maintain proper backpressure while enabling service reuse
  • Changed subgraph service from call() to oneshot() 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: DashMap provides 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() to oneshot() in subgraph service interaction follows Tower conventions
  • Backpressure Flow: Check that buffered services properly propagate poll_ready signals through the service chain
  • API Compatibility: Confirm constructor changes don't break existing HttpClientServiceFactory usage 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 avatar Jun 15 '25 22:06 BrynCooke

@BrynCooke, please consider creating a changeset entry in /.changesets/. These instructions describe the process and tooling.

github-actions[bot] avatar Jun 15 '25 22:06 github-actions[bot]

✅ 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

apollo-librarian[bot] avatar Jun 15 '25 22:06 apollo-librarian[bot]

Oh, I didn't realise http_client_service is only for private plugins, maybe we don't need to mention it then 🙈

goto-bus-stop avatar Jun 16 '25 09:06 goto-bus-stop

Before merging we need to check any plugin that uses http_client_service is not expecting the old way of working.

BrynCooke avatar Jun 17 '25 09:06 BrynCooke