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

feat: add interface abstraction primitives #577

Merged
merged 32 commits into from
Apr 26, 2021

Conversation

software-dov
Copy link
Contributor

Nomenclature within this commit:

  • The current generated client is referred to as a 'transport'.
    Similarly, the WIP rest+json client will also be a 'transport'.
  • The new internal-only interface is the 'transport interface'.
  • The new client type whose only responsibility is to embed a
    transport interface is a 'new-style client'.

Two new types are defined: an interface intended to abstract out the
mechanism of network communication and serialization (the transport interface),
and a wrapper struct that embeds the interface.

The transport interface cannot be user visible because methods will be
added to it if the API defines new methods. This is a non-breaking
change in the API but is technically a breaking change to the user; if
they defined a type that previously satisfied the contract of the
interface, the type would no longer satisfy the interface.

The workaround is to make the transport interface not user visible and
to embed the interface in a struct. The transports and transport
interface are generated concurrently, so there is no risk of breaking
the interface contract. Adding methods to the new-style client is a
non-breaking change becasuse it is a struct.
This is similar to the PIMPL idiom in C++.

TODO:

  • Add factory function(s) for the new-style client to take an injected
    transport + auth.
  • Tweak documentation, samples, and integration tests to prefer
    new-style clients instead of directly using transports.
  • Write out rest+json transport.

Includes moderately substantial refactors as implementation details.

@software-dov software-dov requested review from a team as code owners March 31, 2021 20:39
@google-cla google-cla bot added the cla: yes This human has signed the Contributor License Agreement. label Mar 31, 2021
@noahdietz
Copy link
Collaborator

Is this truly ready for review? Should we make this a draft PR for the time being?

@software-dov
Copy link
Contributor Author

Yes, this is complete module the test failures. The TODOs are caveat notes about subsequent PRs.

@noahdietz
Copy link
Collaborator

Yes, this is complete module the test failures. The TODOs are caveat notes about subsequent PRs.

Ok! You can also download the linting report from the failing GitHub Actions. It includes govet, golint and gofmt.

@software-dov
Copy link
Contributor Author

You can also download the linting report from the failing GitHub Actions

That is incredibly useful. Wow, I wish I'd known this when doing the python m-gen CI conversion. Thanks!

@noahdietz
Copy link
Collaborator

Would you mind opening a draft PR on gapic-showcase with the client regenerated using your changes? Like googleapis/gapic-showcase#649. This will be useful for reviewing the changes in a "real" client.

In gapic-generator-go, run make install. Then in gapic-showcase, run go run ./util/cmd/compile_protos, only check in the changes to client/ and open it as a Draft PR please.

@software-dov
Copy link
Contributor Author

@software-dov software-dov requested a review from noahdietz April 1, 2021 22:07
showcase/go.mod Outdated Show resolved Hide resolved
Nomenclature within this commit:
* The current generated client is referred to as a 'transport'.
  Similarly, the WIP rest+json client will also be a 'transport'.
* The new internal-only interface is the 'transport interface'.
* The new client type whose only responsibility is to embed a
transport interface is a 'new-style client'.

Two new types are defined: an interface intended to abstract out the
mechanism of network communication and serialization (the transport interface),
and a wrapper struct that embeds the interface.

The transport interface cannot be user visible because methods will be
added to it if the API defines new methods. This is a non-breaking
change in the API but is technically a breaking change to the user; if
they defined a type that previously satisfied the contract of the
interface, the type would no longer satisfy the interface.

The workaround is to make the transport interface not user visible and
to embed the interface in a struct. The transports and transport
interface are generated concurrently, so there is no risk of breaking
the interface contract. Adding methods to the new-style client is a
non-breaking change becasuse it is a struct.
This is similar to the PIMPL idiom in C++.

TODO:
* Add factory function(s) for the new-style client to take an injected
transport + auth.
* Tweak documentation, samples, and integration tests to prefer
new-style clients instead of directly using transports.
* Write out rest+json transport.

Includes moderately substantial refactors as implementation details.
software-dov added a commit to software-dov/gapic-showcase that referenced this pull request Apr 14, 2021
@software-dov software-dov requested review from tbpg and noahdietz April 22, 2021 21:01
@software-dov software-dov requested a review from noahdietz April 22, 2021 21:15
Copy link
Collaborator

@noahdietz noahdietz left a comment

Choose a reason for hiding this comment

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

Once the Operation helpers are added to the generated interface, this should be backwards compat and lgtm. I want @tbpg or @codyoss to sign off. If that happens 4/23, i will be OOO and @vchudnov-g is my proxy :)

@software-dov software-dov requested review from noahdietz and tbpg April 23, 2021 21:20
Copy link
Member

@codyoss codyoss left a comment

Choose a reason for hiding this comment

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

This LGTM, thanks @software-dov for all of your hard work on this! I will let someone from your team have final signoff. I think there is still on unresolved comment on the draft PR.

@software-dov software-dov requested a review from codyoss April 26, 2021 16:52
@software-dov
Copy link
Contributor Author

@noahdietz has pointed out that changing the name of the default client options thunk will break Spanner: https://github.com/googleapis/google-cloud-go/blob/master/spanner/apiv1/spanner_client_options.go#L24
This is a manageable change, though; when we regenerate Spanner, the build will fail, and we will just fix that when it happens. This comment is just a reminder of that eventuality.

@codyoss

Copy link
Collaborator

@noahdietz noahdietz left a comment

Choose a reason for hiding this comment

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

changing the name of the default client options thunk will break Spanner: https://github.com/googleapis/google-cloud-go/blob/master/spanner/apiv1/spanner_client_options.go#L24
This is a manageable change, though; when we regenerate Spanner, the build will fail, and we will just fix that when it happens. This comment is just a reminder of that eventuality.

Thanks @software-dov I think this is reasonable especially because I agree that the default client option helper(s) should probably be transport-specific.

Copy link
Contributor

@tbpg tbpg left a comment

Choose a reason for hiding this comment

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

LGTM. Would be good to run apidiff on regenerated APIs before we release new versions to be extra careful.

@software-dov software-dov merged commit a2f0ccc into googleapis:master Apr 26, 2021
@software-dov software-dov deleted the pimpl-interface branch April 26, 2021 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants