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

Protobuf domains #280

Merged
merged 1 commit into from
Nov 1, 2021
Merged

Protobuf domains #280

merged 1 commit into from
Nov 1, 2021

Conversation

tegefaulkes
Copy link
Contributor

@tegefaulkes tegefaulkes commented Oct 29, 2021

Description

This PR addresses changes relating to adding subdomains to the proto definitions and importing useful google.protobuf types.

The new directory structure looks like this now. when using a message from a domain in a rpc you import it with import "domains/vaults.proto" and refer to the messages with domains.vaults.Vault.

schemas/
├── agent.proto
├── client.proto
├── domains
│   ├── common.proto
│   ├── gestalts.proto
│   ├── identities.proto
│   ├── keys.proto
│   ├── nodes.proto
│   ├── notifications.proto
│   ├── permissions.proto
│   ├── secrets.proto
│   ├── sessions.proto
│   └── vaults.proto
└── test.proto

Issues Fixed

Tasks

  • - Prototype by abstracting into subdirectories under src/proto/schemas, and integrate google's protobuf library by first referencing it and then just copying verbatim
    • - work out how to import google.protobuf messages.
    • - examine google.protobuf.Any usage.
    • - examine timestamp usage.
    • - examine struct usage.
  • - Create common domain types and common message types and share between Client.proto and Agent.proto

Final checklist

  • Domain specific tests
  • Full tests
  • Lint fixed
  • Squash and rebased
  • Sanity check the final build

@tegefaulkes tegefaulkes marked this pull request as draft October 29, 2021 01:44
@tegefaulkes
Copy link
Contributor Author

Right now I have the message subdomains in the same directory as the Agent.proto and Client.proto in proto/schema. Do we want to move them into their own sub directory like proto/schema/domains

Do we want to keep the agent and client specific messages separate. group them like vaultsAgent.proto, vaultsCommon.proto and vaultsClient.proto?

so we want to split the services into the domains as well? Currently the clientService is defined in Client.proto it could be split into the domain proto files such as the vaults rpc definitions in the vaults.proto.

@tegefaulkes tegefaulkes mentioned this pull request Oct 29, 2021
24 tasks
@tegefaulkes tegefaulkes force-pushed the protobuf_domains branch 2 times, most recently from 75a3627 to 5e25cd9 Compare October 29, 2021 03:45
@tegefaulkes tegefaulkes marked this pull request as ready for review October 29, 2021 06:41
src/agent/agentPB.ts Outdated Show resolved Hide resolved
@CMCDragonkai
Copy link
Member

CMCDragonkai commented Nov 1, 2021

Can you only copy in the google protos that we are actually using? For the google protos that we are not using, please delete them.

Also on this MR in the description, you should describe the new structure. Use tree src/proto/schemas and copy the output to the MR description. Makes it easier to show context.

Also give some annotations explaining why you did what you did. As in put them where.

@CMCDragonkai
Copy link
Member

CMCDragonkai commented Nov 1, 2021 via email

@tegefaulkes
Copy link
Contributor Author

Oh, so you're saying I should import the agentPb directly instead of through the index.ts?

@CMCDragonkai
Copy link
Member

Ok so I see what you did here...

├── google
│   └── protobuf
│       ├── any.proto
│       ├── api.proto
│       ├── descriptor.proto
│       ├── duration.proto
│       ├── empty.proto
│       ├── field_mask.proto
│       ├── struct.proto
│       ├── timestamp.proto
│       ├── type.proto
│       └── wrappers.proto

When we start using these, we can copy just the ones we want to use.

Which are all copied from: https://github.com/protocolbuffers/protobuf/tree/master/src/google/protobuf

So atm, none of them are being used, so we can push that to later increment of the #275.

@CMCDragonkai
Copy link
Member

I like the new structure. Now we can clearly see that src/proto/schemas/agent.proto and src/proto/schemas/client.proto are used for the services. However I would want to change the service name to AgentService instead of just Agent. This follows the style guide and why is given here: https://docs.buf.build/lint/rules/#service_suffix mainly to ensure no overlap in naming between message types and service types.

@CMCDragonkai
Copy link
Member

I'm going to change it to agent_service.proto and AgentService correspondingly.

The package is supposed to have the version specifiers as per the #249. Let me check what they should be.

@CMCDragonkai
Copy link
Member

I noticed that domains.common.EchoMessage can be used by TestService.

Also because we are regenerating the code, we should be deleting the src/proto/js so that the old files aren't left there.

@CMCDragonkai
Copy link
Member

From #249 (comment)

Because the package name is meant to follow the directory structure. It would mean that schemas should have a sub directory. Maybe something like:

agent/v1/agent_service.proto
client/v1/client_service.proto

Of course that would imply that we have 2 different versions. So instead we might do something like:

polykey/v1/agent_service.proto
polykey/v1/client_service.proto
polykey/v1/test_service.proto

And instead of domains, I reckon we can use types as the directory since they are just different types.
That would ensures that our package name is polykey.v1

@CMCDragonkai
Copy link
Member

Also the package name should be the directory, but not contain the name of the file. This follows golang packaging/file hierarchy.

@CMCDragonkai
Copy link
Member

This means all proto files part of the same package is part of the same namespace. So when referring to them, you just use types.EchoMessage and types.VaultMessage instead of types.vaults.VaultMessage or types.common.EchoMessage. Again this is standard in golang where protobuf is part of the same ecosystem.

@CMCDragonkai
Copy link
Member

Note that imports are all like this now:

import "polykey/v1/types/nodes.proto";
import "polykey/v1/types/identities.proto";

Which means one has to refer to them using the full package name: polykey.v1.types.Node.

@CMCDragonkai
Copy link
Member

Oh it seems you can use the same types within the same package. That means you don't really need to import right?

@CMCDragonkai
Copy link
Member

I see that the List was reused twice as a message name. That's why you created separate packages for each file. But according to the style guide, the packages are meant to be different directories. I reckon here it's better to differentiate the 2 list types and not conflict in the same namespace. So all proto files within the same package are in the same namespace and package corresponds to directory name here.

@CMCDragonkai
Copy link
Member

From a naming standard pov, the messages are more freeform. However specific kinds of messages should have Request and Response suffix. See: https://docs.buf.build/lint/rules/#rpc_request_standard_name-rpc_response_standard_name-rpc_request_response_unique But I'll leave this out for now.

Right now I need to ensure that all our types are not conflicting with each other.

@CMCDragonkai
Copy link
Member

So we'll drop the Message suffix. But we will need to add wrapper types for Request and Response suffixes.

@CMCDragonkai
Copy link
Member

Ok to preserve what @tegefaulkes did, I will instead do something like:

schemas/polykey/v1/agent_service.proto
schemas/polykey/v1/client_service.proto
schemas/polykey/v1/test_service.proto
schemas/polykey/v1/vaults/vaults.proto
schemas/polykey/v1/secrets/secrets.proto

This means we have a package like polykey.v1.secrets.Rename. Then the directory here means the protofiles.

That way it expands more cleanly and less need to to write the prefix/suffix within each file.

@CMCDragonkai
Copy link
Member

Updated to:

»» ~/Projects/js-polykey/src/proto
 ♖ tree .              ⚡(protobuf_domains) pts/2 23:05:40
.
├── js
│   └── polykey
│       └── v1
│           ├── agent_service_grpc_pb.d.ts
│           ├── agent_service_grpc_pb.js
│           ├── agent_service_pb.d.ts
│           ├── agent_service_pb.js
│           ├── client_service_grpc_pb.d.ts
│           ├── client_service_grpc_pb.js
│           ├── client_service_pb.d.ts
│           ├── client_service_pb.js
│           ├── gestalts
│           │   ├── gestalts_grpc_pb.js
│           │   ├── gestalts_pb.d.ts
│           │   └── gestalts_pb.js
│           ├── identities
│           │   ├── identities_grpc_pb.js
│           │   ├── identities_pb.d.ts
│           │   └── identities_pb.js
│           ├── keys
│           │   ├── keys_grpc_pb.js
│           │   ├── keys_pb.d.ts
│           │   └── keys_pb.js
│           ├── nodes
│           │   ├── nodes_grpc_pb.js
│           │   ├── nodes_pb.d.ts
│           │   └── nodes_pb.js
│           ├── notifications
│           │   ├── notifications_grpc_pb.js
│           │   ├── notifications_pb.d.ts
│           │   └── notifications_pb.js
│           ├── permissions
│           │   ├── permissions_grpc_pb.js
│           │   ├── permissions_pb.d.ts
│           │   └── permissions_pb.js
│           ├── secrets
│           │   ├── secrets_grpc_pb.js
│           │   ├── secrets_pb.d.ts
│           │   └── secrets_pb.js
│           ├── sessions
│           │   ├── sessions_grpc_pb.js
│           │   ├── sessions_pb.d.ts
│           │   └── sessions_pb.js
│           ├── test_service_grpc_pb.d.ts
│           ├── test_service_grpc_pb.js
│           ├── test_service_pb.d.ts
│           ├── test_service_pb.js
│           ├── utils
│           │   ├── utils_grpc_pb.js
│           │   ├── utils_pb.d.ts
│           │   └── utils_pb.js
│           └── vaults
│               ├── vaults_grpc_pb.js
│               ├── vaults_pb.d.ts
│               └── vaults_pb.js
└── schemas
    └── polykey
        └── v1
            ├── agent_service.proto
            ├── client_service.proto
            ├── gestalts
            │   └── gestalts.proto
            ├── identities
            │   └── identities.proto
            ├── keys
            │   └── keys.proto
            ├── nodes
            │   └── nodes.proto
            ├── notifications
            │   └── notifications.proto
            ├── permissions
            │   └── permissions.proto
            ├── secrets
            │   └── secrets.proto
            ├── sessions
            │   └── sessions.proto
            ├── test_service.proto
            ├── utils
            │   └── utils.proto
            └── vaults
                └── vaults.proto

26 directories, 55 files

@CMCDragonkai
Copy link
Member

The usage of polykey/v1 means that if a breaking change occurs, we will create polykey/v2 and always the new proto files there. Only changes need to be created there, but the service files will always need to be copied over. But files that aren't changed, they can be kept the same.

For example if permissions.proto is breaking change, then we would have:

src/schemas/polykey/v2/permissions/permissions.proto
src/schemas/polykey/v2/agent_service.proto
src/schemas/polykey/v2/client_service.proto
src/schemas/polykey/v2/test_service.proto

But of course we should limit such changes, and try to make things as backwards compatible as possible.

@CMCDragonkai
Copy link
Member

If I copy back in the google proto. There's actually some missing proto files. The original globbing wasn't working. So with the new globstar it is now working, so there's some extra google proto to bring in.

By removing the types.proto and api.proto this solves the problems such that it works now. So for now I'm leaving:

»» ~/Projects/js-polykey/src/proto/schemas/google/protobuf
 ♜ tree .                                   ⚡(protobuf_domains) pts/2 23:16:00
.
├── any.proto
├── descriptor.proto
├── duration.proto
├── empty.proto
├── field_mask.proto
├── struct.proto
├── timestamp.proto
└── wrappers.proto

0 directories, 8 files

In case we need it for the future completion of #249.

@CMCDragonkai
Copy link
Member

Now to update all the src code with the proper imports.

@CMCDragonkai
Copy link
Member

All code swapped over. Ran lintfix.

The last thing to do is to run tests.

If the relevant tests pass for this, then merging time.

All other MRs need to rebase on top. @emmacasolin can you help rebase the CLI retry MR https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/213 cause this makes some big changes to the import paths.

@scottmmorris you'll have to rebase for #266.

@CMCDragonkai
Copy link
Member

All tests pass. Except of course for nodes being dealt with here #274.

@CMCDragonkai CMCDragonkai merged commit 4be28e0 into master Nov 1, 2021
@CMCDragonkai CMCDragonkai deleted the protobuf_domains branch November 1, 2021 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Creating .proto definition subdomains.
2 participants