forked from BigfootDev/flatbuffers
* grpc callbackService support added Signed-off-by: shankeleven <shashanksati11@gmail.com> * tests: regenerate C++ gRPC golden with --grpc-callback-api (CallbackService & async_ reactor APIs); update formatting and method placement --------- Signed-off-by: shankeleven <shashanksati11@gmail.com> Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
102 lines
3.9 KiB
Markdown
102 lines
3.9 KiB
Markdown
GRPC implementation and test
|
|
|
|
NOTE: files in `src/` are shared with the GRPC project, and maintained there
|
|
(any changes should be submitted to GRPC instead). These files are copied
|
|
from GRPC, and work with both the Protobuf and FlatBuffers code generator.
|
|
|
|
`tests/` contains a GRPC specific test, you need to have built and installed
|
|
the GRPC libraries for this to compile. This test will build using the
|
|
`FLATBUFFERS_BUILD_GRPCTEST` option to the main FlatBuffers CMake project.
|
|
|
|
## Building Flatbuffers with gRPC
|
|
|
|
### Linux
|
|
|
|
1. Download, build and install gRPC. See [instructions](https://github.com/grpc/grpc/tree/master/src/cpp).
|
|
* Lets say your gRPC clone is at `/your/path/to/grpc_repo`.
|
|
* Install gRPC in a custom directory by running `make install prefix=/your/path/to/grpc_repo/install`.
|
|
2. `export GRPC_INSTALL_PATH=/your/path/to/grpc_repo/install`
|
|
3. `export PROTOBUF_DOWNLOAD_PATH=/your/path/to/grpc_repo/third_party/protobuf`
|
|
4. `mkdir build ; cd build`
|
|
5. `cmake -DFLATBUFFERS_BUILD_GRPCTEST=ON -DGRPC_INSTALL_PATH=${GRPC_INSTALL_PATH} -DPROTOBUF_DOWNLOAD_PATH=${PROTOBUF_DOWNLOAD_PATH} ..`
|
|
6. `make`
|
|
|
|
For Bazel users:
|
|
|
|
```shell
|
|
$bazel test src/compiler/...
|
|
```
|
|
|
|
## Running FlatBuffer gRPC tests
|
|
|
|
### Linux
|
|
|
|
1. `export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${GRPC_INSTALL_PATH}/lib`
|
|
2. `make test ARGS=-V`
|
|
|
|
For Bazel users:
|
|
|
|
```shell
|
|
$bazel test tests/...
|
|
```
|
|
|
|
## C++ Callback API Generation
|
|
|
|
FlatBuffers gRPC C++ code generation now optionally supports the modern gRPC Callback API.
|
|
|
|
To enable generation of a `CallbackService` skeleton alongside the existing `Service` and async mixins, invoke `flatc` with both `--grpc` and `--grpc-callback-api`:
|
|
|
|
```shell
|
|
flatc --cpp --grpc --grpc-callback-api your_service.fbs
|
|
```
|
|
|
|
This adds (guarded by `#if defined(GRPC_CALLBACK_API_NONEXPERIMENTAL)`) a class:
|
|
|
|
```cpp
|
|
class YourService::CallbackService : public ::grpc::Service { /* reactor virtuals */ };
|
|
```
|
|
|
|
Each RPC shape maps to the appropriate reactor return type:
|
|
|
|
- Unary -> `::grpc::ServerUnaryReactor*` Method(...)
|
|
- Client streaming -> `::grpc::ServerReadReactor<Request>*`
|
|
- Server streaming -> `::grpc::ServerWriteReactor<Response>*`
|
|
- Bidi streaming -> `::grpc::ServerBidiReactor<Request, Response>*`
|
|
|
|
Default generated implementations return `nullptr`; override in your derived class and return a reactor instance you manage (see gRPC docs for lifecycle patterns).
|
|
|
|
If your gRPC library predates the stable callback API macro, the code inside the guard will be skipped (no breaking changes). Ensure you build against a recent gRPC (1.38+; verify current minimum in grpc repo) to use this feature.
|
|
|
|
### Client Callback Stubs
|
|
|
|
When `--grpc-callback-api` is supplied, the generated C++ client stub gains native callback / reactor based async methods in addition to the existing synchronous / generic async flavors, guarded by the same macro. For each RPC named `Foo`:
|
|
|
|
Unary:
|
|
|
|
```
|
|
void async_Foo(::grpc::ClientContext*, const Request&, Response*, std::function<void(::grpc::Status)>);
|
|
void async_Foo(::grpc::ClientContext*, const Request&, Response*, ::grpc::ClientUnaryReactor*);
|
|
```
|
|
|
|
Client streaming:
|
|
|
|
```
|
|
::grpc::ClientWriteReactor<Request>* async_Foo(::grpc::ClientContext*, Response*, ::grpc::ClientWriteReactor<Request>*);
|
|
```
|
|
|
|
Server streaming:
|
|
|
|
```
|
|
::grpc::ClientReadReactor<Response>* async_Foo(::grpc::ClientContext*, const Request&, ::grpc::ClientReadReactor<Response>*);
|
|
```
|
|
|
|
Bidirectional streaming:
|
|
|
|
```
|
|
::grpc::ClientBidiReactor<Request, Response>* async_Foo(::grpc::ClientContext*, ::grpc::ClientBidiReactor<Request, Response>*);
|
|
```
|
|
|
|
These map directly onto the native gRPC callback API factories (e.g. `CallbackUnaryCall`, `ClientCallbackWriterFactory::Create`, etc.) and do not spawn threads. Override the appropriate reactor callbacks per gRPC's documentation to drive I/O.
|
|
|
|
If your build uses an older gRPC lacking the non-experimental macro, these symbols will not be emitted, preserving backwards compatibility.
|