apple-oss-lab / servicetalk
apple/servicetalk
Reactive networking library on Netty. Architecture and build analysis by arcade-agent. Upstream: apple/servicetalk · Fork: arcade-agent/servicetalk
Scope: static analysis of the default branch plus GitHub metadata for open PRs and the 30 most recently merged PRs. Java sources only (9961 entities, tests excluded); Kotlin files are not parsed. This is an independent, unofficial analysis; it does not evaluate people.
Architecture baseline
9961entities
63021dependency edges
26components (package-based)
21smells
0.4313RCI (intra-edge ratio)
0.2201BasicMQ
Components
| Component | Entities |
|---|---|
| Http | 3038 |
| Concurrent | 2133 |
| Buffer | 896 |
| Transport | 807 |
| Grpc | 482 |
| Loadbalancer | 378 |
| Examples | 304 |
| Utils | 286 |
| Client | 243 |
| Opentracing | 211 |
| Encoding | 163 |
| Context | 151 |
| Dns | 150 |
| Opentelemetry | 129 |
| Data | 112 |
| Logging | 96 |
| Traffic | 81 |
| Serializer | 69 |
| Capacity | 54 |
| Tcp | 53 |
| Log4J2 | 34 |
| Serialization | 33 |
| Benchmark | 17 |
| Circuit | 15 |
| Router | 15 |
| Oio | 11 |
Architectural smells (21)
| Type | Severity | Description |
|---|---|---|
| Dependency Cycle | high | Circular dependency among 23 components: Buffer <-> Capacity <-> Client <-> Concurrent <-> Context <-> Data <-> Dns <-> Encoding <-> Examples <-> Grpc <-> Http <-> Loadbalancer <-> Log4J2 <-> Logging <-> Opentelemetry <-> Opentracing <-> Router <-> Serialization <-> Serializer <-> Tcp <-> Traffic <-> Transport <-> Utils |
| Concern Overload | high | Opentelemetry contains 129 entities but only 25 internal dependencies (0.19 per entity), suggesting multiple responsibilities. |
| Concern Overload | high | Tcp contains 53 entities but only 7 internal dependencies (0.13 per entity), suggesting multiple responsibilities. |
| Concern Overload | high | Traffic contains 81 entities but only 4 internal dependencies (0.05 per entity), suggesting multiple responsibilities. |
| Scattered Parasitic Functionality | high | 'Config' pattern is scattered across 8 components: Concurrent, Grpc, Http, Loadbalancer, Logging, Tcp, Transport, Utils |
| Scattered Parasitic Functionality | high | 'Exception' pattern is scattered across 12 components: Capacity, Client, Concurrent, Encoding, Grpc, Http, Loadbalancer, Serialization, Serializer, Traffic, Transport, Utils |
| Scattered Parasitic Functionality | high | 'Factory' pattern is scattered across 13 components: Buffer, Client, Concurrent, Context, Data, Dns, Encoding, Grpc, Http, Loadbalancer, Router, Serializer, Transport |
| Scattered Parasitic Functionality | high | 'Handler' pattern is scattered across 6 components: Buffer, Concurrent, Encoding, Http, Logging, Transport |
| Scattered Parasitic Functionality | high | 'Provider' pattern is scattered across 14 components: Client, Concurrent, Context, Data, Dns, Grpc, Http, Loadbalancer, Log4J2, Opentelemetry, Opentracing, Serialization, Traffic, Transport |
| Scattered Parasitic Functionality | high | 'Service' pattern is scattered across 5 components: Concurrent, Context, Examples, Grpc, Http |
| Scattered Parasitic Functionality | high | 'Utils' pattern is scattered across 15 components: Buffer, Capacity, Client, Concurrent, Context, Encoding, Examples, Grpc, Http, Oio, Opentracing, Router, Serializer, Transport, Utils |
| Link/Upstream Overload | high | Concurrent is depended on by 20 other components (80% of all components). |
| Concern Overload | medium | Log4J2 contains 34 entities but only 5 internal dependencies (0.15 per entity), suggesting multiple responsibilities. |
| Concern Overload | medium | Serialization contains 33 entities but only 9 internal dependencies (0.27 per entity), suggesting multiple responsibilities. |
| Scattered Parasitic Functionality | medium | 'Controller' pattern is scattered across 3 components: Client, Concurrent, Http |
| Scattered Parasitic Functionality | medium | 'Manager' pattern is scattered across 4 components: Http, Opentracing, Transport, Utils |
| Link/Upstream Overload | medium | Buffer is depended on by 14 other components (56% of all components). |
| Link/Upstream Overload | medium | Context is depended on by 13 other components (52% of all components). |
| Link/Upstream Overload | medium | Http is depended on by 13 other components (52% of all components). |
| Link/Upstream Overload | medium | Transport is depended on by 17 other components (68% of all components). |
| Link/Upstream Overload | medium | Utils is depended on by 15 other components (60% of all components). |
Build & CI audit (Gradle)
Same measure → report → fix methodology as mvn-perf, ported to Gradle (mvn-perf itself only hooks Maven). Each row cites where it was found.
| Check | State | Evidence |
|---|---|---|
| Gradle parallel + local build cache | on | gradle.properties: org.gradle.parallel=true, org.gradle.caching=true, configureondemand=true |
| Configuration cache | off | No reference anywhere in the repo |
| Remote build cache / Develocity | off | No reference anywhere in the repo |
| PR CI matrix | info | ci-prb.yml: JDK 8/11/17/21/25 on ubuntu, JDK 11 on self-hosted macOS, plus a Netty 4.1.x variant; each runs the full suite |
| JUnit class parallelism | off | junit-platform.properties: parallel.enabled=true but mode.default and mode.classes.default are same_thread |
| Workflow timeouts | off | No timeout-minutes in .github/workflows |
| Test sharding within a module | off | None found; a job runs one module's tests sequentially |
Measured
| Command | Wall | Result | Note |
|---|---|---|---|
./gradlew :servicetalk-buffer-api:test --profile | 165 s | BUILD SUCCESSFUL | Wall time includes wrapper/dependency download and daemon start; summed task time ≈ 22 s. Slowest tasks: :compileGroovy 18s; :servicetalk-buffer-api:test 3s; :servicetalk-buffer-api:compileTestJava 1s |
Single cold run on one laptop (macOS, JDK 25), no repetition: a data point, not a benchmark.
Pull requests (52)
Filter:
| # | Title | State | Kind | +/− |
|---|---|---|---|---|
| 3662 | http-netty: stop ClientEffectiveStrategyTest blaming late send events on the next request | open | test-only | +42/−60 |
| 3661 | loadbalancer-experimental-provider: align property names with OutlierDetectorConfig.Builder | merged | mixed | +85/−12 |
| 3660 | build(deps): bump github/codeql-action/analyze from 4.37.9 to 4.38.1 | open | ci-only | +1/−1 |
| 3659 | build(deps): bump github/codeql-action/init from 4.37.9 to 4.38.1 | open | ci-only | +1/−1 |
| 3658 | Housekeeping: replace repo-level CODE_OF_CONDUCT | merged | docs-only | +0/−62 |
| 3657 | AGENTS.md: collapse copyright years into a single range | merged | docs-only | +3/−3 |
| 3656 | Add a commit message skill for coding agents | merged | docs-only | +152/−3 |
| 3655 | http-router-jersey: document how to limit request payload sizes | open | mixed | +303/−2 |
| 3654 | Rename test classes to the *Test convention | merged | test-only | +12/−12 |
| 3653 | http: allow opting out of interrupt-on-cancel for blocking streaming … | open | mixed | +554/−38 |
| 3652 | loadbalancer: align outlier detector defaults with Envoy | merged | mixed | +229/−57 |
| 3651 | Use Hamcrest matchers that print the actual value in collection asserts | merged | test-only | +123/−97 |
| 3650 | Use assertThrows instead of try/fail/catch in tests | merged | test-only | +200/−444 |
| 3649 | http: score connections by outstanding requests for p2c selection | merged | mixed | +158/−25 |
| 3648 | ci: gate test reports on artifact origin and drop the quality reports | merged | ci-only | +6/−80 |
| 3646 | build(deps): bump actions/setup-java from 6.0.0 to 6.0.1 | merged | ci-only | +6/−6 |
| 3644 | loadbalancer: infer a forced core pool from minConnectionsPerHost | merged | mixed | +87/−15 |
| 3643 | loadbalancer: don't strand connections on hosts that can't grow their pool | merged | mixed | +157/−30 |
| 3642 | Add AGENTS.md and a testing skill for coding agents | merged | docs-only | +855/−0 |
| 3641 | loadbalancer: fix corePool connection selector crash on empty pool | merged | mixed | +145/−16 |
| 3640 | loadbalancer: properly honor the maxEjectionPercentage | merged | mixed | +162/−21 |
| 3639 | loadbalancer: release the health indicator when an expired host drains | merged | mixed | +47/−18 |
| 3638 | ThreadInterruptingCancellable: fix interrupt leak when onSubscribe throws | merged | mixed | +159/−9 |
| 3637 | concurrent-internal: fix ThreadInterruptingCancellable interrupt leak | merged | mixed | +175/−29 |
| 3636 | docs: java.net.preferIPv6Stack -> java.net.preferIPv6Addresses | merged | main-only | +2/−2 |
| 3634 | build(deps): bump github/codeql-action/init from 4.37.8 to 4.37.9 | merged | ci-only | +1/−1 |
| 3633 | build(deps): bump github/codeql-action/analyze from 4.37.8 to 4.37.9 | merged | ci-only | +1/−1 |
| 3630 | Remove MethodHandles from HTTP/2 codec builder | closed | main-only | +3/−88 |
| 3629 | Fix traffic resilience documentation links | merged | mixed | +1/−3 |
| 3628 | build(deps): bump github/codeql-action/analyze from 4.37.5 to 4.37.8 | merged | ci-only | +1/−1 |
| 3626 | build(deps): bump github/codeql-action/init from 4.37.5 to 4.37.8 | merged | ci-only | +1/−1 |
| 3625 | build(deps): bump actions/setup-java from 5.7.0 to 6.0.0 | merged | ci-only | +6/−6 |
| 3624 | build(deps): bump gradle-wrapper from 9.7.0 to 9.7.1 | merged | build-only | +2/−2 |
| 3622 | Fix flaky H2ResponseCancelTest | closed | test-only | +4/−1 |
| 3621 | Update tags for release | merged | mixed | +14/−14 |
| 3620 | examples: add virtual threads HTTP example and guide | merged | mixed | +373/−0 |
| 3606 | http-netty: fix connection acceptor context test race | merged | test-only | +28/−21 |
| 3601 | build(deps): bump gradle/actions/wrapper-validation from 6.2.0 to 6.3.0 | merged | ci-only | +1/−1 |
| 3596 | dns-discovery-netty: fix SRV resurrection during A-record backoff | open | mixed | +149/−35 |
| 3570 | opentelemetry-http: stabilize lifecycle cancellation test | merged | test-only | +14/−2 |
| 3535 | Try to fix the flaky ReplayPublisherTest.concurrentTTL test | merged | test-only | +42/−35 |
| 3521 | http-netty: fix flaky PayloadSizeLimitingHttpServiceFilterTest | merged | test-only | +15/−2 |
| 3506 | http-netty: Fix flaky noMaxActiveStreamsViolatedErrorAfterCancel() test | merged | test-only | +23/−18 |
| 3461 | Defer connectionEstablished observer callback and H2 auto-read until | open | mixed | +483/−30 |
| 3447 | opentelemetry-client: add ServiceTalk[Grpc|Http]Sender implementations | open | mixed | +3474/−0 |
| 3162 | http-netty: Add support for GC based message leak detection | open | mixed | +570/−101 |
| 2906 | Add `ContextMaps` to let users create various `ContextMap`s | open | mixed | +827/−146 |
| 2861 | Introduce a cache for Publishers that tracks subscriptions to manage the cache | open | mixed | +472/−0 |
| 2690 | Add Publisher.zip | open | mixed | +2872/−19 |
| 2571 | Streamline the creation of GRPC Exceptions | open | mixed | +39/−3 |
| 2384 | PublisherAsBlockingIterable LinkedBlockingQueue -> SpscBlockingQueue | open | mixed | +417/−4 |
| 2383 | Make `Single.concat(Publisher)` behavior consistent on cancel | open | mixed | +124/−54 |
Generated 2026-09-28 · arcade-agent baseline computed in 1.6 s.