Skip to content
This repository was archived by the owner on Sep 26, 2023. It is now read-only.

Moving code from gax-grpc to gax#359

Merged
garrettjonesgoogle merged 12 commits intogoogleapis:gax-httpjsonfrom
garrettjonesgoogle:gax-httpjson
Oct 9, 2017
Merged

Moving code from gax-grpc to gax#359
garrettjonesgoogle merged 12 commits intogoogleapis:gax-httpjsonfrom
garrettjonesgoogle:gax-httpjson

Conversation

@garrettjonesgoogle
Copy link
Copy Markdown
Contributor

@garrettjonesgoogle garrettjonesgoogle commented Aug 25, 2017

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:

  1. Overall, I tried to move logic up from grpc/httpjson to gax.rpc
  2. Moved most of the implementation of GrpcCallableFactory to CallableFactory in gax.rpc
  3. Created an OperationApi abstraction in gax.rpc, along with an OperationSnapshot abstraction
    3.1. Now that OperationSnapshot is used throughout gax.rpc, OperationT is removed as a type parameterization
    3.2. Most of the operation implementation is moved up to gax.rpc
  4. Renamed Transport to TransportChannel and ChannelProvider to TransportChannelProvider; removed TransportProvider, and instead repurposed Instantiating(*)ChannelProvider to directly create TransportChannel objects (either GrpcTransportChannel or HttpJsonTransportChannel), cutting out a layer of abstraction
  5. Created new TransportDescriptor concept, to allow for transport-specific logic to be supplied in various places
  6. Moved header logic out of Instantiating(*)ChannelProvider into a new HeaderProvider, which lives at the gax.rpc level and can be shared by grpc & http/json
  7. In the new TransportChannelProvider, changed the model of providing other providers, such that you can do provider.withX(X x), so now there is only a single getTransportChannel() method

@garrettjonesgoogle garrettjonesgoogle force-pushed the gax-httpjson branch 2 times, most recently from 6bec56a to ebb2cf9 Compare September 5, 2017 18:31
@codecov-io
Copy link
Copy Markdown

codecov-io commented Sep 5, 2017

Codecov Report

Merging #359 into gax-httpjson will increase coverage by 5.55%.
The diff coverage is 74.45%.

Impacted file tree graph

@@                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
Impacted Files Coverage Δ Complexity Δ
...oogle/api/gax/httpjson/ManagedHttpJsonChannel.java 0% <ø> (ø) 0 <0> (ø) ⬇️
...om/google/api/gax/rpc/ApiResultRetryAlgorithm.java 90.9% <ø> (ø) 7 <0> (?)
...m/google/api/gax/httpjson/ApiMethodDescriptor.java 0% <ø> (ø) 0 <0> (ø) ⬇️
...m/google/api/gax/httpjson/HttpJsonCallContext.java 40.9% <ø> (ø) 5 <0> (ø) ⬇️
...ogle/api/gax/httpjson/HttpJsonCallableFactory.java 0% <ø> (-38.6%) 0 <0> (-6)
...m/google/api/gax/httpjson/HttpJsonCallOptions.java 81.81% <ø> (ø) 4 <0> (ø) ⬇️
...ogle/api/gax/httpjson/HttpJsonHeaderEnhancers.java 0% <ø> (ø) 0 <0> (ø) ⬇️
...java/com/google/api/gax/rpc/OperationCallable.java 100% <ø> (ø) 6 <0> (ø) ⬇️
...oogle/api/gax/rpc/EntryPointOperationCallable.java 100% <ø> (ø) 5 <0> (ø) ⬇️
...a/com/google/api/gax/grpc/GrpcCallableFactory.java 80% <ø> (-5.9%) 4 <0> (-11)
... and 83 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7d720bb...d913a3f. Read the comment docs.

@pongad
Copy link
Copy Markdown
Contributor

pongad commented Sep 8, 2017

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

Copy link
Copy Markdown
Contributor

@vam-google vam-google left a comment

Choose a reason for hiding this comment

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

(sorry, I had to modify your initial PR comment from bulleted list to numbered list, to reference the items here)

  1. Overall looks good to me.
  2. Cool!
  3. 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.
  4. The http/grpc difference is now mostly on channel level, I believe it is good.
  5. 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.
  6. 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.
  7. 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.

@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.

import io.grpc.Status.Code;

/** Package-private for internal use. */
class GrpcOperationTransformers {

This comment was marked as spam.

This comment was marked as spam.


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.

exceptionContext.getResultFuture().setException(exceptionToThrow);
}

public ApiCallContext getDefaultCallContext() {

This comment was marked as spam.

This comment was marked as spam.

initialContext = getClientContext(initialChannel, executor);
}

private static class ResponseTransformer implements ApiFunction<OperationSnapshot, Color> {

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

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.

case CANCELLED:
expectedClass = CancelledException.class;
break;
// case NOT_FOUND:

This comment was marked as spam.

This comment was marked as spam.

return CancelOperationRequest.newBuilder().setName(request).build();
}
},
new ApiFunction<Empty, Void>() {

This comment was marked as spam.

This comment was marked as spam.

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.

@garrettjonesgoogle
Copy link
Copy Markdown
Contributor Author

  1. Header routing problem: my implementation is for static headers. I think we can make an additive change later for dynamic headers (which you would need).
  2. Look at the withExecutor() and withHeaders() methods on TransportChannelProvider, and see if it makes sense to you.

@garrettjonesgoogle
Copy link
Copy Markdown
Contributor Author

I have addressed feedback from @vam-google . PTAL if you want, or wait for a following update where I update docs & add tests.

@googlebot
Copy link
Copy Markdown

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. I signed it!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If your company signed a CLA, they designated a Point of Contact who decides which employees are authorized to participate. You may need to contact the Point of Contact for your company and ask to be added to the group of authorized contributors. If you don't know who your Point of Contact is, direct the project maintainer to go/cla#troubleshoot.
  • In order to pass this check, please resolve this problem and have the pull request author add another comment and the bot will run again.

@googlebot
Copy link
Copy Markdown

CLAs look good, thanks!

@garrettjonesgoogle
Copy link
Copy Markdown
Contributor Author

@vam-google I have updated docs & tests, PTAL

@garrettjonesgoogle garrettjonesgoogle changed the title WIP moving code from gax-grpc to gax Moving code from gax-grpc to gax Sep 30, 2017
@garrettjonesgoogle
Copy link
Copy Markdown
Contributor Author

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.

@garrettjonesgoogle
Copy link
Copy Markdown
Contributor Author

@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.

Copy link
Copy Markdown
Contributor

@pongad pongad left a comment

Choose a reason for hiding this comment

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

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.

This comment was marked as spam.


@Override
public Map<String, String> getHeaders() {
return new HashMap<>();

This comment was marked as spam.

This comment was marked as spam.

@garrettjonesgoogle
Copy link
Copy Markdown
Contributor Author

@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!

@pongad
Copy link
Copy Markdown
Contributor

pongad commented Oct 4, 2017

@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...

@garrettjonesgoogle
Copy link
Copy Markdown
Contributor Author

@vam-google , I have done the following:

  • Added initialFuture back to OperationFuture
  • Moved the Fake* classes to src/test

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.

Copy link
Copy Markdown
Contributor

@vam-google vam-google left a comment

Choose a reason for hiding this comment

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

LGTM
(please push in a non-master branch)

@garrettjonesgoogle garrettjonesgoogle merged commit bfdfd55 into googleapis:gax-httpjson Oct 9, 2017
garrettjonesgoogle added a commit to garrettjonesgoogle/gax-java that referenced this pull request Oct 18, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants