Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KTOR-7667: Enable Gradle configuration cache #4741

Merged
merged 4 commits into from
Mar 24, 2025
Merged

Conversation

osipxd
Copy link
Member

@osipxd osipxd commented Mar 19, 2025

Subsystem
Infrastructure

Motivation
KTOR-7667 Enable Gradle configuration cache

Solution
Finally, I've found a hackaround for KT-72933, and we can enable configuration cache 🎉
It will work only for tasks not involving MetadataDependencyTransformationTask.

Some benchmark results for scenario "Rerun :ktor-client:ktor-client-core:jvmTest after a change in JVM source set."
image
default - optimizations disabled
COD - configuration on demand enabled
CC - configuration cache enabled

Scenarios default and COD represent the case when there is no configuration cache that could be reused, let's call it "initial configuration".
Results show that configuration on demand significantly improves initial configuration configuration times and slightly improves storing and loading of configuration cache (because of smaller cache size)

Next steps:

  • KTOR-8332 Enable Gradle configuration cache for native tasks (as soon as KT-72933 is fixed)

@osipxd osipxd self-assigned this Mar 19, 2025
Copy link

coderabbitai bot commented Mar 19, 2025

Walkthrough

The changes update several Gradle build scripts and settings. In two build script files, OS retrieval logic in task conditions was refactored to improve readability. Additional logic was introduced in the Kotlin Native compilation configuration to disable the configuration cache on certain tasks. New files were added to handle configuration cache workarounds using reflection and to apply cache-related settings. Properties in the Gradle configuration were updated to enable cache features and isolated projects. Finally, a test server variable was moved into a local configuration scope, and the settings file was updated to enable a feature preview and include a new caching plugin.

Changes

File(s) Change Summary
build-logic/.../ktorbuild.kmp.gradle.kts
build-logic/.../ktorbuild.publish.gradle.kts
Refactored OS value retrieval by introducing a local variable (os) for use in onlyIf conditions, reducing repetitive calls to ktorBuild.os.get().
build-logic/.../ktorbuild/CInterop.kt Added imports and configuration changes for Kotlin Native compilation tasks; disables configuration cache for tasks matching a specific naming pattern using notCompatibleWithConfigurationCache as a workaround for KT-76147.
build-settings-logic/.../ConfigurationCacheWorkarounds.kt Introduced a new file with an internal object that uses reflection and the Unsafe class to manage and update fields excluded from Gradle's configuration cache, including a public method addIgnoredBeanFields.
build-settings-logic/.../ktorbuild.configuration-cache.settings.gradle.kts Added a new script to configure Gradle’s configuration cache settings and apply workarounds (e.g., marking specific tasks incompatible with the cache and adding bean fields to the ignored list).
gradle.properties Added new properties: org.gradle.configuration-cache=true, org.gradle.configuration-cache.parallel=true, and kotlin.kmp.isolated-projects.support=enable, to enable configuration cache and prepare for isolated projects.
ktor-test-server/.../test-server.gradle.kts Moved the declaration of testServerService from a top-level variable to a local scope within the test task configuration block.
settings.gradle.kts Updated the settings file to enable the stable configuration cache feature with enableFeaturePreview("STABLE_CONFIGURATION_CACHE") and added the caching plugin via id("ktorbuild.configuration-cache").

Possibly related PRs

  • KTOR-8344 Enable build cache for settings plugins #4745: The changes in the main PR and the retrieved PR are related as both involve modifications to the settings.gradle.kts file, specifically improving the configuration for build caching, although they focus on different aspects of the build process.

Suggested reviewers

  • bjhham
  • Mr3zee

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eeaaf33 and 21905d3.

📒 Files selected for processing (9)
  • build-logic/src/main/kotlin/ktorbuild.kmp.gradle.kts (1 hunks)
  • build-logic/src/main/kotlin/ktorbuild.publish.gradle.kts (1 hunks)
  • build-logic/src/main/kotlin/ktorbuild/CInterop.kt (2 hunks)
  • build-settings-logic/src/main/kotlin/ConfigurationCacheWorkarounds.kt (1 hunks)
  • build-settings-logic/src/main/kotlin/ktorbuild.configuration-cache.settings.gradle.kts (1 hunks)
  • build-settings-logic/src/main/kotlin/ktorbuild.develocity.settings.gradle.kts (1 hunks)
  • gradle.properties (2 hunks)
  • ktor-test-server/src/main/kotlin/test-server.gradle.kts (1 hunks)
  • settings.gradle.kts (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • build-settings-logic/src/main/kotlin/ktorbuild.develocity.settings.gradle.kts
🚧 Files skipped from review as they are similar to previous changes (8)
  • build-logic/src/main/kotlin/ktorbuild.publish.gradle.kts
  • build-settings-logic/src/main/kotlin/ktorbuild.configuration-cache.settings.gradle.kts
  • build-logic/src/main/kotlin/ktorbuild/CInterop.kt
  • build-settings-logic/src/main/kotlin/ConfigurationCacheWorkarounds.kt
  • settings.gradle.kts
  • build-logic/src/main/kotlin/ktorbuild.kmp.gradle.kts
  • ktor-test-server/src/main/kotlin/test-server.gradle.kts
  • gradle.properties

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@osipxd osipxd force-pushed the osipxd/configuration-cache branch from f312b4c to 22e82df Compare March 20, 2025 12:10
@osipxd osipxd marked this pull request as ready for review March 20, 2025 12:31
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
build-logic/src/main/kotlin/ktorbuild/CInterop.kt (1)

67-71: Add clarifying inline commentary on the workaround.

The workaround marking certain tasks as incompatible with the configuration cache is valid. For maintainability, consider adding a direct reference comment to the KT-76147 or linking the issue for future context. This ensures that the reasoning behind the compatibility limitation is clear to other contributors.

build-settings-logic/src/main/kotlin/ConfigurationCacheWorkarounds.kt (1)

8-35: Reflection-based field replacement: handle potential security or tight coupling.

Reflection with private fields can break if internal implementations in Gradle or the JVM change. Make sure to provide clear warnings or guard checks if the reflection fails. Regularly test to ensure that future Gradle updates do not break this.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e31697 and 22e82df.

📒 Files selected for processing (8)
  • build-logic/src/main/kotlin/ktorbuild.kmp.gradle.kts (1 hunks)
  • build-logic/src/main/kotlin/ktorbuild.publish.gradle.kts (1 hunks)
  • build-logic/src/main/kotlin/ktorbuild/CInterop.kt (2 hunks)
  • build-settings-logic/src/main/kotlin/ConfigurationCacheWorkarounds.kt (1 hunks)
  • build-settings-logic/src/main/kotlin/ktorbuild.configuration-cache.settings.gradle.kts (1 hunks)
  • gradle.properties (2 hunks)
  • ktor-test-server/src/main/kotlin/test-server.gradle.kts (1 hunks)
  • settings.gradle.kts (2 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
build-logic/src/main/kotlin/ktorbuild.publish.gradle.kts (1)
build-logic/src/main/kotlin/ktorbuild/internal/publish/PublishTasks.kt (1) (1)
  • isAvailableForPublication (30-44)
🔇 Additional comments (11)
ktor-test-server/src/main/kotlin/test-server.gradle.kts (1)

7-12: Limit Variable Scope for Test Server Service
Moving the declaration of testServerService inside the tasks.withType<AbstractTestTask>().configureEach block properly limits its scope to only where it’s needed. This improves clarity and helps prevent unintended misuse elsewhere in the build script.

build-logic/src/main/kotlin/ktorbuild.publish.gradle.kts (1)

60-62: Refactor OS Retrieval for Improved Readability
Extracting ktorBuild.os.get() into a local variable (os) within the onlyIf block reduces redundant calls and enhances readability. This straightforward change aligns with the broader refactoring effort observed elsewhere.

settings.gradle.kts (2)

5-6: Enable Stable Configuration Cache Feature Preview
The addition of enableFeaturePreview("STABLE_CONFIGURATION_CACHE") activates the stable configuration cache feature in Gradle, which is in line with the objective of this PR. Please ensure that your build environment supports this feature preview.


15-15: Add Ktorbuild Configuration Cache Plugin
Including the ktorbuild.configuration-cache plugin integrates the cache-related settings into the build. Confirm that this plugin is compatible with your existing build tools and that its behavior meets the overall caching objectives.

build-logic/src/main/kotlin/ktorbuild.kmp.gradle.kts (1)

60-71: Refine Native Test Task Conditions with Local OS Variable
For the native targets, extracting the operating system value into a local variable (os) and using it to conditionally enable tasks (e.g., "linkDebugTestLinuxX64", "linkDebugTestLinuxArm64", "linkDebugTestMingwX64") improves both efficiency and readability. This guarantees that tests run only on appropriate hosts.

build-settings-logic/src/main/kotlin/ktorbuild.configuration-cache.settings.gradle.kts (1)

1-24: Introduce Configuration Cache Workaround Script
This new script adeptly applies a workaround for KT-72933 by:
• Ignoring specific bean fields that lead to out-of-memory issues.
• Marking tasks associated with MetadataDependencyTransformationTask as incompatible with the configuration cache.

The implementation is clear and well-commented. Please verify that the workaround aligns with the latest Gradle configuration cache limitations and that no downstream tasks are unintentionally affected.

build-logic/src/main/kotlin/ktorbuild/CInterop.kt (1)

11-15: Imports look appropriate for new Kotlin Native compilation logic.

These additions properly set up the project to detect and manage KotlinNativeCompile tasks via withType. They appear necessary and do not introduce any obvious issues.

gradle.properties (2)

59-61: Keep the TODO and remove once isolated projects are fully enabled.

Using kotlin.kmp.isolated-projects.support=enable is a good preparatory step. The inline TODO note is a helpful reminder to remove this once the Gradle feature matures. No further changes needed here.


46-47:

❓ Verification inconclusive

Confirm tasks remain safe under parallel configuration cache.

Enabling both configuration cache and parallel execution can surface concurrency-related pitfalls in plugin or task implementations. Please verify that all relevant tasks and plugins are thread-safe to avoid unexpected issues.


🏁 Script executed:

#!/bin/bash
# This script gathers tasks that implement parallelizable changes.
# We'll look for tasks referencing concurrency or shared states.

rg -A 3 "implements.*Parallel" 
rg -A 3 "shared.*state"

Length of output: 2285


Parallel Configuration Cache: Please Verify Thread-Safety of Custom Tasks

The grep searches only revealed expected shared state handling in the Ktor client modules (e.g., in HttpResponsePipeline.kt and HttpRequestPipeline.kt). No additional unsafe implementations were detected from searching for "implements.*Parallel".

  • Confirm that any custom tasks or plugins that aren’t part of these well-reviewed libraries are also thread-safe.
  • Revisit any tasks using shared mutable state to ensure proper synchronization is in place.
build-settings-logic/src/main/kotlin/ConfigurationCacheWorkarounds.kt (2)

37-43:

❓ Verification inconclusive

Double-check concurrency implications of mutating static fields.

The setFinalStatic approach is unusual and can be risky in multi-threaded builds. Currently, the code attempts a safe fallback if the direct field replacement fails, but consider locking mechanisms or verifying that parallel builds won't cause intermediate inconsistent states.


🏁 Script executed:

#!/bin/bash
#!/bin/bash
# Attempt to locate concurrent usage or references to setFinalStatic in this codebase.
rg -A 5 "setFinalStatic"

Length of output: 1461


Double-check concurrency implications:
After verifying the usage of setFinalStatic across the codebase, no explicit locking or synchronization mechanisms were found around its invocation. The fallback for modifying array elements is also unsynchronized. Please ensure that these operations are safe from race conditions during parallel builds or concurrent access, or consider adding appropriate locking where necessary.


5-7:

❓ Verification inconclusive

Use of sun.misc.Unsafe raises portability concerns.

While Unsafe is powerful, it can cause compatibility issues on newer Java versions and alternative JVMs. Consider verifying that the usage is supported in all deployment environments.


🏁 Script executed:

#!/bin/bash
# Check if this codebase references additional internal or JDK-specific APIs that could be removed or replaced.
rg -A 5 "sun\.misc\.Unsafe"

Length of output: 694


Action Required: Verify Compatibility of Internal Unsafe API Usage

The file build-settings-logic/src/main/kotlin/ConfigurationCacheWorkarounds.kt (around lines 5–7) imports and uses sun.misc.Unsafe. This internal API could lead to portability and compatibility issues on newer Java versions or alternative JVMs. Please verify that its usage is supported in all of your target deployment environments. If possible, consider alternatives or document the environment constraints explicitly.

@@ -43,6 +43,8 @@ doctor.enableTaskMonitoring=false
org.gradle.daemon=true
org.gradle.caching=true
org.gradle.parallel=true
org.gradle.configuration-cache=true
org.gradle.configuration-cache.parallel=true
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably we should also enable "configuration-on-demand" by default, but I'm not sure about it as this mode might silently break something. I would propose enabling this property locally and after couple of weeks we will add it here if everything goes okay.

org.gradle.configureondemand =true

Copy link
Contributor

@bjhham bjhham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bjhham
Copy link
Contributor

bjhham commented Mar 20, 2025

You might have broken some tests by making the build run twice as fast... 😅

@osipxd osipxd force-pushed the osipxd/configuration-cache branch from 22e82df to 009b5f3 Compare March 21, 2025 11:54
@osipxd osipxd force-pushed the osipxd/configuration-cache branch from 009b5f3 to eeaaf33 Compare March 21, 2025 16:43
@osipxd osipxd force-pushed the osipxd/configuration-cache branch from eeaaf33 to 21905d3 Compare March 21, 2025 17:01
@osipxd osipxd enabled auto-merge (squash) March 24, 2025 11:58
@osipxd osipxd merged commit c438c2b into main Mar 24, 2025
17 of 18 checks passed
@osipxd osipxd deleted the osipxd/configuration-cache branch March 24, 2025 12:49
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