Moving code from gax-grpc to gax#359
Moving code from gax-grpc to gax#359garrettjonesgoogle merged 12 commits intogoogleapis:gax-httpjsonfrom
Conversation
6bec56a to
ebb2cf9
Compare
9db1edc to
ba3f3ad
Compare
Codecov Report
@@ Coverage Diff @@
## gax-httpjson #359 +/- ##
==================================================
+ Coverage 64.81% 70.37% +5.55%
- Complexity 541 624 +83
==================================================
Files 151 150 -1
Lines 3203 2994 -209
Branches 237 230 -7
==================================================
+ Hits 2076 2107 +31
+ Misses 1026 795 -231
+ Partials 101 92 -9
Continue to review full report at Codecov.
|
|
Can this be split at all? The individual bullets in the description sound reasonable, but I'm having great difficulty groking the 7000 line diff |
There was a problem hiding this comment.
(sorry, I had to modify your initial PR comment from bulleted list to numbered list, to reference the items here)
- Overall looks good to me.
- Cool!
- Please check the GrpcOperationApi class review comments for more details. Also OperationApi name is weird. What does it even mean? Is it an operation client? A wrapper around it? A bunch of transformers? "Api" suffix is too generic.
- The http/grpc difference is now mostly on channel level, I believe it is good.
- The descriptor looks like a class which encapsulates random transport-specific stuff. It doesn't look very pretty, but seems unavoidable, so I'm fine with it.
- Please check the header provider specific comments for more details. In general looks good, but I'm still not sure how well that would fit in header routing problem. In general we need a good way to create 2 types of headers: static (same for same client, not recalculated every time) and dynamic (different per request, recalculated for each request). For dynamic headers on the moment of creation there should be access to the corresponding parameter values (so we can put it in headers). Propagating that to such a low level can be problematic.
- Not really sure what your comment means here :).
| /** The settings used to create a Transport. */ | ||
| @BetaApi | ||
| public interface TransportProvider { | ||
| public interface OperationApi { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| @BetaApi | ||
| public final class FixedChannelProvider implements ChannelProvider { | ||
| private final ManagedChannel channel; | ||
| public class GrpcOperationSnapshot implements OperationSnapshot { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| import io.grpc.Status.Code; | ||
|
|
||
| /** Package-private for internal use. */ | ||
| class GrpcOperationTransformers { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
|
||
| public static Set<Code> getGrpcStatusCodes(Set<StatusCode> statusCodes) { | ||
| Set<Status.Code> returnCodes = new HashSet<>(); | ||
| for (StatusCode code : statusCodes) { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| exceptionContext.getResultFuture().setException(exceptionToThrow); | ||
| } | ||
|
|
||
| public ApiCallContext getDefaultCallContext() { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| initialContext = getClientContext(initialChannel, executor); | ||
| } | ||
|
|
||
| private static class ResponseTransformer implements ApiFunction<OperationSnapshot, Color> { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| public ApiFuture<OperationSnapshot> futureCall(RequestT request, ApiCallContext context) { | ||
| OperationSnapshot response = results[index]; | ||
| if (index < results.length - 1) { | ||
| index += 1; |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| case CANCELLED: | ||
| expectedClass = CancelledException.class; | ||
| break; | ||
| // case NOT_FOUND: |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| return CancelOperationRequest.newBuilder().setName(request).build(); | ||
| } | ||
| }, | ||
| new ApiFunction<Empty, Void>() { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| new ApiFunction<Operation, OperationSnapshot>() { | ||
| @Override | ||
| public OperationSnapshot apply(Operation operation) { | ||
| return GrpcOperationSnapshot.create(operation); |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
|
I have addressed feedback from @vam-google . PTAL if you want, or wait for a following update where I update docs & add tests. |
|
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed, please reply here (e.g.
|
|
CLAs look good, thanks! |
|
@vam-google I have updated docs & tests, PTAL |
|
I have created a diff PR for certain files as promised: #374 Note, it only include files that git didn't match up correctly; it doesn't include all files that were touched in the present PR. |
|
@pongad I would recommend doing multiple passes on this PR and focus on different things in those passes; it would be hard to split this PR apart because it involves code moves & renames, so any splits would result in code that wouldn't compile. One way to cut down on the lines to review is that you could completely skip gax-httpjson changes; they will mirror gax-grpc directly. Secondly, the most important thing to focus on is the surface under gax/ (transport-agnostic surfaces); prioritize reviewing that code. Lastly, the diff PR should help reviewing some files that git didn't match up for diffs. |
pongad
left a comment
There was a problem hiding this comment.
A couple nits, but otherwise I have no specific concern with this.
There's a lot of code here though, which makes me wonder if the callable stack was the right design for this problem. (Not blaming anyone; in fact I'm probably the one most responsible for it.) If we ever need to add a third transport, we should probably revisit the design.
| "TransportDescriptor.createDefaultCallContext not implemented"); | ||
| } | ||
|
|
||
| public ApiCallContext getCallContextWithDefault(ApiCallContext inputContext) { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
|
||
| @Override | ||
| public Map<String, String> getHeaders() { | ||
| return new HashMap<>(); |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
@pongad I believe the callable stack was the right design. We can't really revisit the design if we want a third transport because we're going GA before such a thing will even be considered. Register your concerns now w.r.t. supporting a third transport! |
|
@garrettjonesgoogle I don't have specific concerns about adding new transports. Not having worked on gax-java for a while, I find it difficult to think of specific action items. I'm sorry I'm not being helpful, but here's my "nebulous" concern. At the time of writing, gax-java master has 212 files and ~13,000 lines of code. At the same time, gax-go has 250 statements. I understand LOC isn't a good measure for quality or productivity, and to be fair, Java's job is harder (eg, Go can efficiently block; Java has to do things with executors). I don't think this should block GA, but there's something unsettling about the 52x size difference. Maybe this is just me being scared by seeing all this code at once... |
|
@vam-google , I have done the following:
As I mentioned in the diff PR, there is a test for the transformers at GrpcOperationTransformersTest . Is there anything else I'm missing? I'd like to merge this to the gax-httpjson branch and then do another PR with additional changes before I merge to master. |
vam-google
left a comment
There was a problem hiding this comment.
LGTM
(please push in a non-master branch)
This is just a work-in-progress PR, so I am just looking for feedback on overall design.I'd like validation on the following changes:GrpcCallableFactorytoCallableFactoryin gax.rpcOperationApiabstraction in gax.rpc, along with anOperationSnapshotabstraction3.1. Now that
OperationSnapshotis used throughout gax.rpc,OperationTis removed as a type parameterization3.2. Most of the operation implementation is moved up to gax.rpc
TransporttoTransportChannelandChannelProvidertoTransportChannelProvider; removedTransportProvider, and instead repurposed Instantiating(*)ChannelProvider to directly createTransportChannelobjects (eitherGrpcTransportChannelorHttpJsonTransportChannel), cutting out a layer of abstractionTransportDescriptorconcept, to allow for transport-specific logic to be supplied in various placesHeaderProvider, which lives at the gax.rpc level and can be shared by grpc & http/jsonTransportChannelProvider, changed the model of providing other providers, such that you can do provider.withX(X x), so now there is only a singlegetTransportChannel()method