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

Adds DefaultCacheStorage#write. #879

Merged
merged 30 commits into from
Sep 10, 2018
Merged

Conversation

coollog
Copy link
Contributor

@coollog coollog commented Aug 24, 2018

Part of #637

DefaultCacheStorage - storage engine implementation with just write implemented so far
DefaultCacheStorageFiles - resolves files used in the cache storage directory
DefaultCacheStorageWriter - the logic behind DefaultCacheStorage#write

@coollog coollog requested a review from a team August 29, 2018 15:42
@coollog coollog changed the title Adds DefaultCacheStorage#save. Adds DefaultCacheStorage#write. Aug 29, 2018

private final DefaultCacheStorageWriter defaultCacheStorageWriter;

private DefaultCacheStorage(Path cacheDirectory) {
Copy link
Member

Choose a reason for hiding this comment

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

Would we want to pass in defaultCacheStorageWriter so we can mock this out? Perhaps in withDirectory?

}

@Override
public CacheEntry write(CacheWrite cacheWrite) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

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

I don't know where CacheWrite came from? Perhaps an earlier PR? But it's naming is confusing. I would expect it to be "CacheLayerMetadata" or something

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, it used be called CacheWriteEntry and CacheEntry used to be CacheReadEntry. CacheWrite is intended to be the interface for cache writes and CacheLayerMetadata might give a sense of being the layer metadata read out from the cache. Perhaps it should be called CacheWriteData instead?

* @throws IOException if an I/O exception occurs
*/
CacheEntry write(CacheWrite cacheWrite) throws IOException {
Path temporaryLayerFile = Files.createTempFile(null, null);
Copy link
Member

Choose a reason for hiding this comment

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

I would expect this write to happen in the cache directory? I feel like mv is not free in Windows (but renames are?)

@coollog coollog requested a review from a team September 5, 2018 18:19
* ...
* }</pre>
*
* Layers entires are stored in their own directories under the {@code layers/} directory. Each
Copy link
Contributor

Choose a reason for hiding this comment

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

entires entries

* @return the selector file
*/
Path getSelectorFile(DescriptorDigest selector) {
return getSelectorDirectory(selector);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is getSelectorDirectory necessary, or can its logic just go here?

import java.util.zip.GZIPOutputStream;

/** Writes to the default cache storage engine. */
class DefaultCacheStorageWriter {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think since this class only contains one write method that's used only in DefaultCacheStorage, we could move that logic there instead of adding this extra class. Although I'm not sure what the plan is for reusing this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is broken out so that it can be independently worked on in relation to the reading methods (listDigests, retrieve, select) as part of a DefaultCacheStorageReader. This will help keep the reading and writing logic separate, componentized, and independently-testable.

Path layerFile = defaultCacheStorageFiles.getLayerFile(layerDigest, layerDiffId);
Files.createDirectories(layerFile.getParent());
try {
Files.move(temporaryLayerFile, layerFile);
Copy link
Contributor

Choose a reason for hiding this comment

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

Could moving this file while we have an output stream open on it cause problems? Can we close the output stream earlier?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The file is actually closed on line 62, which is definitely not clear here. I'll try to think of a way to make this more readable.

@coollog
Copy link
Contributor Author

coollog commented Sep 6, 2018

Incorporated new proposals to account for atomicity of writes from #878 (comment). This changes the write to only produce a layer directory at the intended location in full. This way, cache reads never see an incomplete layer directory.

@@ -52,5 +57,27 @@ public static void copy(ImmutableList<Path> sourceFiles, Path destDir) throws IO
}
}

/**
* Acquires an exclusive lock on the {@code file} and opens an {@link OutputStream} to write to
Copy link
Member

Choose a reason for hiding this comment

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

I think should make our intentions a little more clear here on why we're locking. They are an assertion rather than concurrency management feature?

@coollog coollog requested a review from a team September 10, 2018 17:50
Copy link
Member

@loosebazooka loosebazooka left a comment

Choose a reason for hiding this comment

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

I think it'd be nice to see an actual analysis of the performance when we switch to the new caching.

@coollog
Copy link
Contributor Author

coollog commented Sep 10, 2018

Definitely. We'll do a side-by-side comparison with cache once ncache is working.

@coollog coollog merged commit 411da83 into master Sep 10, 2018
@coollog coollog deleted the ncache-3-defaultcachestorage branch September 10, 2018 20:17
coollog added a commit that referenced this pull request Sep 10, 2018
commit 411da83
Author: Q Chen <[email protected]>
Date:   Mon Sep 10 16:17:22 2018 -0400

     Adds DefaultCacheStorage#write. (#879)

commit 56d818a
Author: Chanseok Oh <[email protected]>
Date:   Fri Sep 7 12:39:22 2018 -0400

    Restart Docker for Mac to fix clock skew in VM (#951)

commit 0b2e09a
Author: Chanseok Oh <[email protected]>
Date:   Thu Sep 6 16:09:28 2018 -0400

    Lower verbosity of insecure registry failover (#945)

try (CountingDigestOutputStream compressedDigestOutputStream =
new CountingDigestOutputStream(
new BufferedOutputStream(FileOperations.newLockingOutputStream(temporaryLayerFile)))) {
Copy link
Member

Choose a reason for hiding this comment

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

Sorry I missed this, but it doesn't seem necessary to use locking outputstream on temporary files. Shouldn't their uniqueness be provided by guava?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh yes, that's true. Will change this in #898

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants