Repository navigation
Conversation
This comment has been minimized.
This comment has been minimized.
🟢 Java Benchmark SLOs — All performance SLOs passed
PR vs. master results
Commit: Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion. |
bric3
left a comment
There was a problem hiding this comment.
I find this exploration interesting, but as is this implementation can't go in, it goes against some Gradle best practices. Moreover I'm concerned about the maintainability of non-standard things ; this doesn't mean it can't be done properly, but we need to work toward a design that aligns properly with best-practices.
There's another PR that explored the using S3 as build cache which showed "spectacular" improvements, with less changes. See
| project(childPath) { | ||
| tasks.register("allTests") { | ||
| dependsOn(testTasks) | ||
| } |
There was a problem hiding this comment.
question: Should instrumentationCheck support running tests when -PskipTests is absent?
check_inst intentionally passes -PskipTests; test_inst uses instrumentationTest, which selects the children's allTests. I compared all eight JVM 11 test jobs in parent pipeline 144164571 and PR pipeline 144239586: both recorded 29,385 tests, including 22,747 passed and 6,638 skipped. The 40 Akka HTTP and 12 WebFlux suite report inventories also matched. This observation does not establish lost coverage in the actual pipeline.
For a direct instrumentationCheck -Pslot=5/8 invocation without -PskipTests, the WebFlux parent check is selected, but its main tests are assigned to other slots. Those slots never select the tests through this aggregate because the children only register allTests. If this entry point should retain its test-running behaviour, child check aliases would restore selection. Otherwise this is a non-blocking question about the aggregate's contract.
The relevant root selection is here:
| if (rootProject.providers.gradleProperty("slot").isPresent()) { | ||
| tasks.named("allTests") { | ||
| setDependsOn([]) | ||
| } |
There was a problem hiding this comment.
issue: This kinda break the model of declaring aggregating tasks.
I.e. clearing these dependencies replaces automatic suite discovery with a fixed list. A newly added suite can therefore run locally but be omitted from sharded CI until this list is updated. I understand this happens only when there's a slot property but this looks like it's changing the task contract under the hood.
The WebFlux split has the same issue.
| ciAkkaTestShards.each { childName, testTasks -> | ||
| def childPath = ":dd-java-agent:instrumentation:akka:akka-http:akka-http-10.0:$childName" | ||
| testTasks.each { testTask -> | ||
| ciShardProjectPaths[testTask.get().path] = childPath |
There was a problem hiding this comment.
issue: This reealizes a test task early breaking the Gradle's task configuration best practices.
This loop runs during every build configuration, including unrelated invocations like help, the call to .get() eagerly configures each test task just to read its path. If that's the only thing needed then TaskProvider.name is available without realisation. The same change applies to other modified project in this PR stack.
| ciShardProjectPaths[testTask.get().path] = childPath | |
| ciShardProjectPaths[project.path + ':' + testTask.name] = childPath |
| 'akka-http-version-102-tests': [tasks.named('version102Scala213Test')], | ||
| ] | ||
|
|
||
| def ciShardProjectPaths = rootProject.extensions.extraProperties.get('ciShardProjectPaths') as Map |
There was a problem hiding this comment.
issue: While Gradle support storing objects there, using extra properties is most likely the wrong approach, which is presently the case.
Possibly I would rather go toward a build service.
In this case there is two concrete problems
- This is shared a mutable state whose initialization depends on another project's configuration.
- The map is created only by the JDBC instrumentation project from I could see, while others like this one read it directly. This creates a hidden ordering assumption. And I believe this could break in various ways. E.g. configuration caching.
- Also, generally speaking, modifying another project (from a project) is an anti-pattern.
| testClassesDirs = sourceSets.test.output.classesDirs | ||
| classpath = sourceSets.test.runtimeClasspath | ||
| setIncludes(includes) | ||
| onlyIf("CI sharding is enabled") { rootProject.providers.gradleProperty("slot").isPresent() } |
There was a problem hiding this comment.
suggestion: Could we capture the sharding flag locally during task configuration and read that value or provider in onlyIf?
This predicate reads rootProject through the build script at execution time. A small Gradle 9.8 fixture fails to store the configuration cache with that pattern; a locally captured provider stores and reuses it. The new root-map predicate in the CI plugin also reads project objects at execution time.
This extends an existing configuration-cache limitation rather than introducing a new failure in the current CI pipeline, but it would be useful to keep the new wiring compatible as that work progresses.
| tasks.register("allTests") { | ||
| dependsOn(testTasks) | ||
| } |
There was a problem hiding this comment.
suggestion (non-blocking): Could we give the new child aggregates a verification group and a description?
The 32 child allTests tasks across the stack have neither. Adding this metadata in the shared registration code would make their purpose visible in Gradle task listings.
| tasks.register("allTests") { | |
| dependsOn(testTasks) | |
| } | |
| tasks.register("allTests") { | |
| group = "verification" | |
| description = "Runs the tests assigned to this CI shard." | |
| dependsOn(testTasks) | |
| } |
| @@ -0,0 +1 @@ | |||
| // CI-only virtual project; its allTests task is registered by the parent project. | |||
There was a problem hiding this comment.
suggestion (non-blocking): I'm really not keep on having virtual projects, but if we go this way, could we use build.gradle.kts for the new child build files if these scheduling projects remain?
Also for all the other 32 comment-only build files, so there is no Groovy logic to migrate in them. This follows Gradle's recommendation for new build scripts; the existing module scripts can remain as they are.
Summary
144209984and rebalance the eight instrumentation shardsStack
CI Visibility measurements
Pipeline
144209984completed successfully and provided coverage-complete weights:The full pipeline took 62m03s because the unrelated
linux-java-spring-petclinic-startup-paralleljob took 46m21s, compared with 13m50s in the parent run. The instrumentation shards finished much earlier.Validation
./gradlew spotlessApply --no-daemon./gradlew help -Pslot=1/8 --no-daemon