Skip to content

Conversation

bamboo
Copy link
Member

@bamboo bamboo commented Jun 21, 2024

Apply snappy compression to Configuration Cache entries

Compression and encryption are offloaded to a separate thread, utilizing a pool of byte buffers capped at a maximum memory working set of 16MB.

The resulting files are 1/5th of their original size. Storing might be marginally slower in some cases, but loading is as fast or faster in all tested scenarios.

Reviewing cheatsheet

Before merging the PR, comments starting with

  • ❌ ❓must be fixed
  • 🤔 💅 should be fixed
  • 💭 may be fixed
  • 🎉 celebrate happy things

@bamboo bamboo added a:feature A new functionality in:configuration-cache Configuration Caching a:performance-improvement Performance improvement potential labels Jun 21, 2024
@bamboo bamboo added this to the 8.10 RC1 milestone Jun 21, 2024
@bamboo bamboo self-assigned this Jun 21, 2024
@bamboo
Copy link
Member Author

bamboo commented Jun 21, 2024

@bot-gradle test APT

@bot-gradle
Copy link
Collaborator

I've triggered the following builds for you. Click here to see all build failures.

* Determines the maximum memory working set: [bufferCount] * [bufferCapacity].
* The default maximum working set is `32MB`.
*/
val bufferCount = System.getProperty("org.gradle.configuration-cache.internal.buffer-count", null)?.toInt()
Copy link
Member

@abstratt abstratt Jun 21, 2024

Choose a reason for hiding this comment

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

Is this right? 1 million buffers that are 32 bit long each? Normally, I'd expect the other way around.

Copy link
Member Author

Choose a reason for hiding this comment

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

Is this right? 1 million buffers that are 32 bit long each? Normally, I'd expect the other way around.

Yes, perhaps the term buffer is not the best choice here. A better analogy might be of a packet (like in UDP). These are used to quickly send the encoded information from the producer to the writer thread for compression >> encryption >> disk IO.

Copy link
Member Author

Choose a reason for hiding this comment

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

@abstratt Please take another look, I changed the code to the packet analogy.

Copy link
Member Author

@bamboo bamboo Jun 22, 2024

Choose a reason for hiding this comment

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

32 bit long

bytes

Copy link
Member

@mlopatkin mlopatkin left a comment

Choose a reason for hiding this comment

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

I now see that the graph walking in smaller builds is probably stuck on waiting for the writer thread to finish compression. We still may win something back by tweaking compression ratio, but I don't have better ideas.

} finally {
// in case of failure, this releases some memory until the
// producer realizes there was a failure
ready.clear()
Copy link
Member

Choose a reason for hiding this comment

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

🎉 neat!

@bamboo bamboo force-pushed the bamboo/cc/compress-in-parallel branch from 3827678 to 9ac5192 Compare June 23, 2024 15:26
}

def "configuration cache encryption enablement is #enabled if kind=#kind"() {
Assume.assumeTrue("Compression no longer exposes the raw data", enabled)
Copy link
Member Author

Choose a reason for hiding this comment

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

🤔 I'm not sure what to do with this test. @abstratt, do you think we still need it?

Copy link
Member

Choose a reason for hiding this comment

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

One thing we are losing here is the ability of detecting a regression where a bug introduced to CC effectively disabled encryption.

We would need to make compression optional (even if behind an internal option), so we could disable it for this test case. May be a good thing to have (for debugging compression performance in the field), and seems more or less trivial to implement, but I will not push for it.

@bamboo bamboo marked this pull request as ready for review June 24, 2024 14:33
@bamboo bamboo requested a review from a team as a code owner June 24, 2024 14:33
@bamboo bamboo requested review from abstratt and alllex and removed request for a team June 24, 2024 14:33
@bamboo
Copy link
Member Author

bamboo commented Jun 24, 2024

@bot-gradle test ACC

@bot-gradle
Copy link
Collaborator

I've triggered the following builds for you. Click here to see all build failures.

@bamboo bamboo force-pushed the bamboo/cc/compress-in-parallel branch 2 times, most recently from 61e4c1a to cb8df0c Compare June 24, 2024 19:06
Copy link
Member

@mlopatkin mlopatkin left a comment

Choose a reason for hiding this comment

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

LGTM with nits


private
fun flip(packet: Buffer) {
// packet.flip() is not available in Java 8
Copy link
Member

Choose a reason for hiding this comment

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

💅 I've just remembered the whole story here: Buffer flip() is in Java since NIO's inception, and therefore available for ByteBuffer as well. A covariant override ByteBuffer flip() is a new addition of Java 9, and it is what trips the compiler over. I guess, with the typing you have here packet.flip() should already work.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I can see that now.



private
typealias Packet = java.nio.ByteBuffer
Copy link
Member

Choose a reason for hiding this comment

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

🤔 TBH, I find the code with this alias less readable. As a Java developer I know what a ByteBuffer can do, but now have to jump an extra hop to connect the Packet name to it. I don't insist on changing this.

💅 I wonder if chunk is a better name for the pieces we're tossing around here, because a packet somewhat implies having metadata.

Copy link
Member Author

Choose a reason for hiding this comment

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

chunk seems like a better name indeed, thanks. I also agree about the alias.

@bamboo bamboo force-pushed the bamboo/cc/compress-in-parallel branch 2 times, most recently from 6991ec1 to d4385f1 Compare June 27, 2024 17:41
@bamboo bamboo force-pushed the bamboo/cc/compress-in-parallel branch from d4385f1 to 8305de5 Compare June 28, 2024 15:00
bamboo added 2 commits June 28, 2024 13:51
- Make it easier to run a specific set of benchmarks
@bamboo bamboo removed this from the 8.10 RC1 milestone Jul 16, 2024
Copy link
Contributor

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. If you don't want the stale bot to close it, then set a milestone for it.

@github-actions github-actions bot added the stale label Aug 15, 2024
Copy link
Contributor

This pull request has been automatically closed due to inactivity.

@github-actions github-actions bot closed this Aug 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:feature A new functionality a:performance-improvement Performance improvement potential in:configuration-cache Configuration Caching stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants