Skip to content

Refactor into multi-package mono-repo - #7

Merged
jarlah merged 1 commit into
mainfrom
refactor/multi-package-mono-repo
Apr 6, 2026
Merged

Refactor into multi-package mono-repo#7
jarlah merged 1 commit into
mainfrom
refactor/multi-package-mono-repo

Conversation

@sillychipmunk

@sillychipmunk sillychipmunk commented Apr 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Extract generic tower-hs core library with protocol-agnostic Service/Middleware abstractions and middleware (retry, timeout, circuit breaker, filter, hedge, test doubles)
  • Add generic middleware to tower-hs:
    • Tower.Middleware.Tracing — configurable OTel spans with request/response/error attribute hooks
    • Tower.Middleware.Logging — timed logging with user-provided formatter
    • Tower.Middleware.Validate — generic response validation
    • Tower.Middleware.Transform — generic request transformation (withMapRequest, withMapRequestPure)
  • Refactor http-tower-hs into a thin HTTP wrapper depending on tower-hs — SetHeader, RequestId, Validate, Tracing, Logging all use generic building blocks
  • Add servant-tower-hs with:
    • Adapter bridging tower-hs middleware to servant's ClientMiddleware type
    • Servant-specific middleware: SetHeader, RequestId, Validate, Tracing, Logging (operating on servant's Request/Response types, also built on generic building blocks)
    • Integration tests combining generic + servant-specific middleware in one stack
    • OTel tracing integration tests with in-memory exporter + real warp server
  • Add Redis testcontainer integration test in tower-hs proving generic middleware works with non-HTTP services
  • Add standalone example apps in examples/:
    • example-http-client — HTTP client with combined generic + HTTP middleware
    • example-servant-client — Servant client with combined generic + servant middleware
    • example-generic-redis — Redis client demonstrating non-HTTP use case
  • Hackage readiness: per-package LICENSE, README.md, CHANGELOG.md, extra-doc-files, version bounds on tower-hs dep, Paths_* for OTel libraryVersion
  • Rename HttpError to TransportError for protocol-agnostic naming
  • Add shared Tower.Error.Testing module with Eq ServiceError instance (eliminates 9 orphan instances)
  • Network.HTTP.Tower re-exports everything for backwards compatibility

Test plan

  • stack test tower-hs — 55 tests passing (including 6 Redis Docker integration tests)
  • stack test http-tower-hs — 44 tests passing
  • stack test servant-tower-hs — 29 tests passing (including OTel tracing + combined middleware stack)
  • stack test — all 128 tests passing
  • stack sdist — all 3 packages produce clean tarballs with zero warnings
  • stack run example-http-client — works
  • CI workflow runs successfully on all GHC versions (9.6.6, 9.8.4, 9.10.1)

@sillychipmunk
sillychipmunk force-pushed the refactor/multi-package-mono-repo branch from 76c8f06 to 6c953bd Compare April 6, 2026 08:07
@sillychipmunk
sillychipmunk requested a review from jarlah April 6, 2026 08:07
Comment thread README.md
@sillychipmunk
sillychipmunk force-pushed the refactor/multi-package-mono-repo branch from 6c953bd to e404eda Compare April 6, 2026 08:28
@jarlah

jarlah commented Apr 6, 2026

Copy link
Copy Markdown
Owner

Add test in tower-hs for using the middlewares for something else like database health queries
Edit: Done

@sillychipmunk
sillychipmunk force-pushed the refactor/multi-package-mono-repo branch 3 times, most recently from 9b35220 to 5a74a8b Compare April 6, 2026 09:48
Comment thread servant-tower-hs/src/Servant/Tower/Middleware/Tracing.hs Outdated
@jarlah

jarlah commented Apr 6, 2026

Copy link
Copy Markdown
Owner

Also need to check if all packages are ready for Hackage. And, if they are independently useful. Im considering an examples folder for tower-hs, servant and http. How it will actually look like using the three libraries
edit: done

@sillychipmunk
sillychipmunk force-pushed the refactor/multi-package-mono-repo branch 2 times, most recently from 4129f42 to b60eb0c Compare April 6, 2026 10:54
…nt-tower-hs

Extract a generic tower-hs core library from the monolithic http-tower-hs
package, and add a servant-tower-hs adapter with servant-native middleware.

tower-hs (generic core):
- Service/Middleware abstractions, ServiceError (HttpError -> TransportError)
- Middleware: Retry, Timeout, CircuitBreaker, Filter, Hedge, TestDouble
- Logging: generic timed logging with user-provided formatter
- Tracing: configurable OTel spans with request/response/error attribute hooks
- Validate: generic response validation
- Transform: withMapRequest/withMapRequestPure for request transformation
- Tower.Error.Testing: shared Eq instance (eliminates 9 orphan instances)

http-tower-hs (HTTP wrapper, depends on tower-hs):
- Client, SetHeader, RequestId, FollowRedirect, Validate, Logging, Tracing
- All built on generic tower-hs building blocks (Validate, Transform, Tracing, Logging)
- Network.HTTP.Tower re-exports everything for backwards compatibility

servant-tower-hs (servant adapter + middleware):
- Adapter bridging tower-hs middleware to servant's ClientMiddleware type
- Servant-native middleware: SetHeader, RequestId, Validate, Tracing, Logging
- Also built on generic tower-hs building blocks
- Integration tests with real warp server + in-memory OTel exporter

Infrastructure:
- Multi-package stack.yaml and cabal.project
- CI updated for all three packages (build, test, hlint)
- 122 tests passing (49 + 44 + 29)
@sillychipmunk
sillychipmunk force-pushed the refactor/multi-package-mono-repo branch from b60eb0c to cf12717 Compare April 6, 2026 11:05
@jarlah
jarlah merged commit 192db93 into main Apr 6, 2026
5 checks passed
@jarlah
jarlah deleted the refactor/multi-package-mono-repo branch April 6, 2026 11:12
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.

2 participants