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

Implement RemoteDownloader w/ --experimental_remote_downloader #10622

Conversation

jmillikin-stripe
Copy link
Contributor

@jmillikin-stripe jmillikin-stripe commented Jan 21, 2020

This is the Bazel client implementation of bazelbuild/proposals#160. It allows downloading of external dependencies to be delegated to a remote service.

TODOs:

  • Once Add Remote Asset API remote-apis#112 is merged, the vendored copy of bazelbuild/remote-apis should be updated. I've used a [WIP] placeholder for now.
  • If the general approach looks reasonable then I'll add tests. Currently I've been testing with an in-house implementation of the downloader server.

R: @buchgr @dslomov
CC: @EricBurnett @sstriker @ulfjack

@buchgr
Copy link
Contributor

buchgr commented Jan 21, 2020

Thanks for the PR. I think the code should rather live in the downloader package next to the http implementation. I don't really see a good reason for it being in the remote package. WDYT?

@jmillikin-stripe
Copy link
Contributor Author

Thanks for the PR. I think the code should rather live in the downloader package next to the http implementation. I don't really see a good reason for it being in the remote package. WDYT?

When I tried to do this I hit circular dependency problems -- quite a lot of dependency problems, actually, because of how large the java_library targets are here.

I could try moving it back but it might require creating shim interfaces for most of the remote execution utilities (e.g. the tracing metadata injector).

I could also try creating a RemoteDownloader in downloader/, and then a separate GrpcRemoteDownloader extends RemoteDownloader that implements some part of the interface. This seemed unnecessary given that there's no plan for an HttpRemoteDownloader.

@jin jin added the team-Remote-Exec Issues and PRs for the Execution (Remote) team label Jan 23, 2020
@buchgr
Copy link
Contributor

buchgr commented Jan 24, 2020

It's hard for me to say how bad the circular dependency problem is. I'd much prefer if this functionality was implemented outside of the remote module. If that means splitting up large java_library targets into smaller ones then that's fine with me. I think we should treat the Fetcher service and remote execution/caching as separate. Both make sense to be used without the other.

For the flag naming how about --external_dep_proxy or any other ideas?

@jmillikin-stripe
Copy link
Contributor Author

jmillikin-stripe commented Jan 24, 2020

I think we should treat the Fetcher service and remote execution/caching as separate.

The remote downloader has a hard dependency on the remote CAS. It's not possible to use --remote_downloader without --remote_cache (and there's a check in RemoteOptions to enforce this).

For the flag naming how about --external_dep_proxy or any other ideas?

I think that would be confusing, given that this is not a proxy. It's a service that is told to download some external resource (from repository_ctx.download()) and put it in the CAS.

@jmillikin-stripe jmillikin-stripe force-pushed the remote-downloader-impl branch 3 times, most recently from 8a3f5a8 to 33bb551 Compare January 28, 2020 05:42
@jmillikin-stripe
Copy link
Contributor Author

Done -- Rebased to master, un-WIP'd the remote-apis vendor commit, and relocated the GrpcRemoteDownloader to the downloader/ directory.

Does this look better? If so, I'll start on the tests.

@jmillikin-stripe jmillikin-stripe changed the title [WIP] Implement RemoteDownloader w/ --experimental_remote_downloader Implement RemoteDownloader w/ --experimental_remote_downloader Jan 31, 2020
@jmillikin-stripe
Copy link
Contributor Author

Timed out waiting for response. I've added a unit test GrpcRemoteDownloaderTest to DownloaderTestSuite, cribbing heavily from HttpDownloaderTest and GrpcCacheClientTest.

Also removing [WIP] since the TODOs are resolved.

return out;
}

private static String authHeadersJson(Map<URI, Map<String, String>> authHeaders) {
Copy link
Contributor

Choose a reason for hiding this comment

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

How does this interact with the authentication methods from the remote module? Why do we want 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.

ctx.download() allows arbitrary HTTP headers to be passed to the HTTP library for authenticating with the remote endpoint. This is part of the netrc support added in ... v2.0? v2.1? Fairly recently.

This code implements that by passing it along to the remote download server, which is free to use (or ignore) that data. The download server would use it when the place being downloaded from (e.g. example.com) needs special headers such as HTTP Basic Auth.

"ReferenceCountedChannel.java",
"RemoteRetrier.java",
"RemoteRetrierUtils.java",
"Retrier.java",
Copy link
Contributor

Choose a reason for hiding this comment

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

That's surprising. Why do you need 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.

The RemoteRetrier class implements the logic of --remote_retries, which causes Bazel to retry failed gRPC calls sent to the remote executor/storage/downloader.

Copy link
Contributor

Choose a reason for hiding this comment

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

Let me be more clear: This target looks odd. Why do you need to exclude the sources? Is there a way to have more meaningful targets rather than one large one?

Copy link
Contributor Author

@jmillikin-stripe jmillikin-stripe Jan 31, 2020

Choose a reason for hiding this comment

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

I would personally prefer smaller targets, and I also think it looks weird, but this is all pre-existing weirdness in Bazel.

  • //src/main/java/com/google/devtools/build/lib/remote is a glob of every Java file in the directory.
  • Since there is now a dependency of RemoteModule -> downloader -> RemoteRetrier, we need to have at least some of the Java files in remote/ be a separate target.
  • Other most-but-not-all-srcs style targets handle this case with globs that exclude some source files.

If you feel like adjusting the remote/ directory to have finer-grained targets that sounds like a good idea to me. I would prefer to avoid doing any major surgery to the Bazel build graph as part of this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is some unfortunate tech debt I'm willing to punt on temporarily. If you have any ideas on how to improve the situation/would like to clean up this package (ie, enumerating all files in the srcs list) it'd be much appreciated.

@jmillikin-stripe
Copy link
Contributor Author

(rebased for #10679)

@laurentlb
Copy link
Contributor

@buchgr, do you think this PR can be merged in time for Bazel 2.2?

(@jmillikin-stripe asked for it in #10133 (comment))

@jmillikin-stripe
Copy link
Contributor Author

gentle ping @buchgr

Please let me know if this PR is too large to easily review, I can split some parts (like the remote-apis vendor update) into separate PRs if that would be better.

@buchgr
Copy link
Contributor

buchgr commented Feb 7, 2020

Sorry I haven't forgotten about it. I am currently overloaded with an internal project. We'll ship it in 2.2.

@jmillikin-stripe
Copy link
Contributor Author

I'm going to try splitting this up so it's easier to land incrementally, with the hopes of getting it into v2.3.

First subset is vendoring the updated remote-apis protos: #10818

import java.util.Map;
import java.util.Optional;

public class DownloaderDelegate implements Downloader {
Copy link
Contributor

Choose a reason for hiding this comment

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

This class needs documentation

Copy link
Contributor

Choose a reason for hiding this comment

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

This is still open...

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 - this makes it clear what's so special about this implementation. IIUC it's a wrapper around downloader that lets the implementation be swapped out?

}

@Override
public void download(
Copy link
Contributor

Choose a reason for hiding this comment

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

There's not enough documentation here. Minimum:

  • thread-safety (although that could also be covered in the interface)
  • deduplication
  • exceptions

return null;
}));
} catch (StatusRuntimeException e) {
throw new IOException(e);
Copy link
Contributor

Choose a reason for hiding this comment

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

I really really dislike the decision by upstream grpc-java to use runtime exceptions. It makes it much harder to make the error handling correct.

However, we also need a clear policy for Bazel on how to handle these exceptions. In many cases, StatusRuntimeException is already wrapping an IOException, so this ends up with an IOException -> StatusRuntimeException -> IOException chain, which makes it hard to debug. My preference would be to rethrow the inner IOException if there is one, and only wrap if not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I copied this exception handling from GrpcCacheClient, and I don't know enough about grpc-java to understand the exact issue you describe. Would it be possible for a Bazel dev to make the existing code act as you describe? Then I could copy it, and/or use a shared helper that does the right thing w.r.t. error handling.


public final class RemoteDownloaderFactory implements DownloaderFactory {

private volatile Downloader remoteDownloader;
Copy link
Contributor

Choose a reason for hiding this comment

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

Prefer synchronized over volatile. You almost never need it from a performance point of view, and it's much harder to reason about.

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 logic is copied from the existing delegate/factory stacks, such as RepositoryRemoteExecutorFactoryDelegate. To be honest I have no idea why this level of indirection is necessary, and would be happy to have some guidance (or, like, direct commits to this PR) from someone who writes Java regularly.

I tried using synchronized instead, but the build fails:

src/main/java/com/google/devtools/build/lib/remote/RemoteDownloaderFactory.java:24: error: modifier synchronized not allowed here
  private synchronized Downloader remoteDownloader;

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, sorry. The synchronized goes on all methods that access the field, like so:

private Downloader remoteDownloader;

public synchronized void init(Downloader remoteDownloader) {
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Yea, you can do something like...

@GuardedBy("this")
private Downloader remoteDownloader;

Then add "synchronized" to all methods using it. This'll also let you get rid of the whole "remoteDownloader0" thing.

The volatile pattern in other files was likely an oversight.

@@ -1589,7 +1597,8 @@ public BlazeRuntime build() throws AbruptExitException {
productName,
serverBuilder.getBuildEventArtifactUploaderMap(),
serverBuilder.getAuthHeadersProvidersMap(),
serverBuilder.getRepositoryRemoteExecutorFactory());
serverBuilder.getRepositoryRemoteExecutorFactory(),
serverBuilder.getDownloaderFactory());
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks wrong. This means it's not possible to have different Downloader factories for different builds in the same client. Shouldn't this be part of the CommandEnvironment instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't understand the question, but handling of the remote downloader should match that of the other remote capabilities (caching and execution). The calls to getRepositoryRemoteExecutorFactory() and getDownloaderFactory() belong together.

If they belong together somewhere else, could we do that separately? I'm very out of my depth when it comes to this level of the Bazel client architecture.

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 what ulf means is, assuming you're familiar with the client-server setup, the DownloaderFactory instance (and thus implementation) is tied to the lifetime of the server. It cannot be changed across different commands to the same server. I think this is fine since it's no worse than the current setup for other remote stuff, and there's only one impl.

@jmillikin-stripe jmillikin-stripe force-pushed the remote-downloader-impl branch from 0878448 to 0caf2c4 Compare March 2, 2020 02:22
@jmillikin-stripe
Copy link
Contributor Author

@ulfjack Thank you so much for the review! I've addressed most comments, but there are a few places where I either didn't understand the request (I don't write much Java), or where the issue was not introduced by my change.

@katre katre requested review from michajlo and removed request for ola-rozenfeld March 4, 2020 14:22
Copy link
Contributor

@ulfjack ulfjack left a comment

Choose a reason for hiding this comment

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

Note that I don't work at Google anymore, and I am spending most of my time starting my own company... providing a remote execution service and will also implement the remote asset API. However, it means that I can't currently promise any SLAs on reviews.

I think this is fine to merge. There are a few minor nits left, but they could also be addressed after the initial commit.

import java.util.Map;
import java.util.Optional;

public class DownloaderDelegate implements Downloader {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is still open...


public final class RemoteDownloaderFactory implements DownloaderFactory {

private volatile Downloader remoteDownloader;
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, sorry. The synchronized goes on all methods that access the field, like so:

private Downloader remoteDownloader;

public synchronized void init(Downloader remoteDownloader) {
}

Copy link
Contributor

@michajlo michajlo 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 conceptually everything seems fine - I trust that you understand the end-to-end goal here better than I and that you've been testing it locally. Most comments are around style and organization.

@@ -43,6 +43,7 @@ void download(
List<URL> urls,
Map<URI, Map<String, String>> authHeaders,
Optional<Checksum> checksum,
String canonicalId,
Copy link
Contributor

Choose a reason for hiding this comment

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

can you document what this is?

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 purpose and semantics of canonical_id is documented at https://docs.bazel.build/versions/master/skylark/lib/repository_ctx.html#download

Note that this field was originally present in the PR that added the Downloader interface. It got removed as part of the import into Google, and I just need back, because we have propagate this data to the backend somehow.

import java.util.Map;
import java.util.Optional;

public class DownloaderDelegate implements Downloader {
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 - this makes it clear what's so special about this implementation. IIUC it's a wrapper around downloader that lets the implementation be swapped out?

Map<String, String> clientEnv)
throws IOException, InterruptedException {
Downloader delegate = defaultDelegate;
Optional<DownloaderFactory> factory = delegateFactory;
Copy link
Contributor

Choose a reason for hiding this comment

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

i'm assuming this is in case delegateFactory changes mid-method? Is that actually expected? If so seems dubious... If not then just inline the call, which should simplify most of this method to...

Downloader delegate = delegateFactory.isPresent()
    ? delegateFactory.get().create().orElse(defaultDelegate)
    : defaultDelegate

"ReferenceCountedChannel.java",
"RemoteRetrier.java",
"RemoteRetrierUtils.java",
"Retrier.java",
Copy link
Contributor

Choose a reason for hiding this comment

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

This is some unfortunate tech debt I'm willing to punt on temporarily. If you have any ideas on how to improve the situation/would like to clean up this package (ie, enumerating all files in the srcs list) it'd be much appreciated.

import com.google.devtools.build.lib.bazel.repository.downloader.DownloaderFactory;
import java.util.Optional;

public final class RemoteDownloaderFactory implements DownloaderFactory {
Copy link
Contributor

Choose a reason for hiding this comment

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

add some quick javadoc explaining what's so interesting about this impl.

actual = hasher.hash();
}
if (!code.equals(actual)) {
throw new UnrecoverableHttpException(
Copy link
Contributor

Choose a reason for hiding this comment

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

This side-effect is unfortunately hidden, but I guess there's prior art for this.


@BeforeClass
public static void beforeEverything() {
retryService = MoreExecutors.listeningDecorator(Executors.newScheduledThreadPool(1));
Copy link
Contributor

Choose a reason for hiding this comment

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

why not put this in the before and after? Otherwise we can leak threads across tests within this test class

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I copy-pasted this from the existing downloader test case, and don't have enough context in Bazel to know whether there's a pre-existing bug here.

private static byte[] downloadBlob(
GrpcRemoteDownloader downloader, URL url, Optional<Checksum> checksum)
throws IOException, InterruptedException {
final List<URL> urls = ImmutableList.<URL>of(url);
Copy link
Contributor

Choose a reason for hiding this comment

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

Modern java should be smart enough that you can leave the "" out of "ImmutableList.of(...)", so rm it. Same for other occurrences where the compiler is fine with it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in forked PR #10914

}

private GrpcRemoteDownloader newDownloader(RemoteCacheClient cacheClient) throws IOException {
final RemoteOptions remoteOptions = Options.getDefaults(RemoteOptions.class);
Copy link
Contributor

Choose a reason for hiding this comment

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

btw, final shouldn't be necessary on most local variables, but it's not necessary to remove


getFromFuture(cacheClient.uploadBlob(contentDigest, ByteString.copyFromUtf8("wrong content")));

IOException e = assertThrows(UnrecoverableHttpException.class, () -> downloadBlob(
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix formatting to improve readability:

IOException e = assertThrows(
    UnrecoverableHttpException.class,
    () -> downloadBlob(
        downloader,
         ...,
         ...));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in forked PR #10914

@jmillikin-stripe
Copy link
Contributor Author

Per Dmitry's latest comment on #10742, it sounds like this has missed the merge window for v3.0. I am going to take the parts that the reviewer(s) seem happy with and them into a separate PR (#10914), in the hopes of trimming this one down further.

@katre
Copy link
Member

katre commented Mar 6, 2020

Left comments on #10914. What's remaining in this PR after that? Can you give a high-level description?

@jmillikin-stripe
Copy link
Contributor Author

After that PR is merged, this one would be just the plumbing of the new downloader into RemoteModule, BazelRuntime, and so on. I'm hopeful that since I'm just copying what Bazel is already doing, I can link each new code block to the existing code and thus simplify the reviewer's task.

bazel-io pushed a commit that referenced this pull request Mar 9, 2020
Extracted from #10622

Per discussion on that PR, there's still some unanswered questions about how exactly we plumb the new `Downloader` type into `RemoteModule`. And per #10742 (comment), it is unlikely that even heroic effort from me will get the full end-to-end functionality into v3.0.

Given this, to simplify the review, I'm taking some of the bits the reviewer is happy with and moving them to a separate PR. After merger, `GrpcRemoteDownloader` and its tests will exist in the source tree, but will not yet be available as CLI options.

R: @michajlo
CC: @adunham-stripe @dslomov @EricBurnett  @philwo @sstriker

Closes #10914.

PiperOrigin-RevId: 299908615
@katre
Copy link
Member

katre commented Mar 9, 2020

#10914 is now merged, do you want to rebase this and I will review the remainder?

@jmillikin-stripe
Copy link
Contributor Author

Rebased to master.

Per earlier comments, I've rewritten this final commit. Instead of using the existing design of RemoteRepositoryRemoteExecutorFactory as a reference, it passes around a Supplier<Downloader>.

I don't know if the new version is as idiomatic for Java, but I find it easier to follow. Please let me know if you'd prefer the previous way.

Copy link
Member

@katre katre left a comment

Choose a reason for hiding this comment

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

This looks fine overall, just one question.

repoContext,
cacheClient,
remoteOptions));
downloaderChannel.release();
Copy link
Member

Choose a reason for hiding this comment

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

Why the immediate release after the retain?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Trying to match the existing code. Ctrl+F new ByteStreamUploader( or new GrpcRemoteExecutor( for where I'm looking as examples.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the explanation. I'll import this today and try to cut a new RC of 3.0.0.

@bazel-io bazel-io closed this in 05de852 Mar 10, 2020
katre pushed a commit that referenced this pull request Mar 10, 2020
Extracted from #10622

Per discussion on that PR, there's still some unanswered questions about how exactly we plumb the new `Downloader` type into `RemoteModule`. And per #10742 (comment), it is unlikely that even heroic effort from me will get the full end-to-end functionality into v3.0.

Given this, to simplify the review, I'm taking some of the bits the reviewer is happy with and moving them to a separate PR. After merger, `GrpcRemoteDownloader` and its tests will exist in the source tree, but will not yet be available as CLI options.

R: @michajlo
CC: @adunham-stripe @dslomov @EricBurnett  @philwo @sstriker

Closes #10914.

PiperOrigin-RevId: 299908615
katre pushed a commit that referenced this pull request Mar 10, 2020
This is the Bazel client implementation of bazelbuild/proposals#160. It allows downloading of external dependencies to be delegated to a remote service.

TODOs:
- [x] Once bazelbuild/remote-apis#112 is merged, the vendored copy of `bazelbuild/remote-apis` should be updated. I've used a [WIP] placeholder for now.
- [x] If the general approach looks reasonable then I'll add tests. Currently I've been testing with an in-house implementation of the downloader server.

R: @buchgr @dslomov
CC: @EricBurnett @sstriker @ulfjack

Closes #10622.

PiperOrigin-RevId: 300116716
@jmillikin-stripe jmillikin-stripe deleted the remote-downloader-impl branch March 10, 2020 22:07
@jmillikin-stripe
Copy link
Contributor Author

@katre Thank you so much for your help! Both for the review, and for handling the cherry-pick.

I no longer have Peer Bonus access, but if you're ever in Tokyo I'll buy you lunch or something :P

@@ -160,6 +172,13 @@ public void beforeCommand(CommandEnvironment env) throws AbruptExitException {
boolean enableHttpCache = RemoteCacheClientFactory.isHttpCache(remoteOptions);
boolean enableGrpcCache = GrpcCacheClient.isRemoteCacheOptions(remoteOptions);
boolean enableRemoteExecution = shouldEnableRemoteExecution(remoteOptions);
boolean enableRemoteDownloader = shouldEnableRemoteDownloader(remoteOptions);

if (enableRemoteDownloader && !enableGrpcCache) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to require --remote_cache be set alongside --remote_executor are there any side effects which could arise from changing this to the below snippet?

if (enableRemoteDownloader && (!enableGrpcCache || !enableRemoteExecution)) {

Copy link
Contributor

Choose a reason for hiding this comment

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

Remote execution is not required to use remote downloads. Remote caching (specifically gRPC remote caching) is required, because that's where the downloads get placed.

Copy link
Contributor

Choose a reason for hiding this comment

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

However --remote_cache is not usually required for the use of --remote_executor. I assume bazel has some defaulting behaviour for the cache endpoint to be the executor endpoint. This enforces a flag requirement for the combination of these features.

Remote execution with the use of the remote downloader requires all 3 flags.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've opened #11913 to track this issue.

@purkhusid
Copy link

@jmillikin Is there any way to invalidate the Remote Downloader cache? I've tried using --remote_instance_name but it does not seem to affect the Remote Downloader cache.

@jmillikin
Copy link
Contributor

I think that would be a question for the author of your remote downloader implementation. The Bazel client only uses one RPC, which is approximately "download file and return the CAS checksum + size". Other RPCs for cache management and invalidation are implementation-specific.

@purkhusid
Copy link

@jmillikin Ok, but I wonder if it might be worth a feature request to make the Remote Assets API sensitive to the --remote_instance_name flag? That could be implemented as a client side feature, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes team-Remote-Exec Issues and PRs for the Execution (Remote) team
Projects
None yet
Development

Successfully merging this pull request may close these issues.