How to create a C++ gRPC application
Jump to navigation
Jump to search
- Setup some environmental variables (assuming bash)
export GRPC_INSTALL_DIR=/daqfs/gRPC/installation export PATH="$GRPC_INSTALL_DIR/bin:$PATH" export LD_LIBRARY_PATH="$GRPC_INSTALL_DIR/lib:$LD_LIBRARY_PATH"
- Start by copying the hello world example and compiling it (official instructions here). The compilation steps differ slightly between examples.
cd <my_gRPC_dir> mkdir ejfat cd ejfat mkdir cpp protos cp /daqfs/gRPC/grpc/examples/protos/helloworld.proto protos/. cp -r /daqfs/gRPC/grpc/examples/cpp/cmake cpp/. cp -r /daqfs/gRPC/grpc/examples/cpp/helloworld cpp/. cd cpp/helloworld mkdir -p cmake/build cd cmake/build cmake -DCMAKE_PREFIX_PATH=$GRPC_INSTALL_DIR -DBUILD_SHARED_LIBS=ON ../.. make -j 4
Now that it compiles, as an example, implement ERSAP backend reassembler communication of fifo fill percentage to load-balancer control plane
- Rename a few files and directories, from helloworld to loadBalancerControl (or whatever you want)
cd <my_gRPC_dir>/ejfat mv protos/helloworld.proto protos/loadBalancerControl.proto mv cpp/helloworld cpp/loadBalancerControl mv cpp/loadBalancerControl/greeter_server.cc cpp/loadBalancerControl/lbcontrol_server.cc mv cpp/loadBalancerControl/greeter_client.cc cpp/loadBalancerControl/lbcontrol_client.cc
- Start by modifying loadBalancerControl.proto to define the message and the communication API. Make it look like the following and don't worry about option and package statements.
// The ERSAP backend state reporting service definition. service BackendState { // Sends a request to get the backend's state rpc GetState (StateRequest) returns (StateReply) {} } // The get-state request message containing the LB control plane's name. message StateRequest { string name = 1; } // The response message containing the backend's current state message StateReply { int32 bufferCount = 1; // number of backend's buffers or fifo entries int32 bufferSize = 2; // size in bytes of each buffer or fifo entry int32 fillPercent = 3; // % of fifo entries that are filled with unprocessed data int32 pidError = 4; // PID loop error term in percentage of fifo entries }
- Next modify both the client and server files: cpp/loadBalancerControl/lbcontrol_server.cc and lbcontrol_client.cc. These files need to implement the API using the messages defined in the previous step.
- Next modify several lines in the cpp/loadBalancerControl/CMakefile.txt in order to reflect file/directory name changes. Get the proto file path correct.
project(LoadBalancerControl C CXX) include(../cmake/common.cmake) # Proto file get_filename_component(hw_proto "../../protos/loadBalancerControl.proto" ABSOLUTE) get_filename_component(hw_proto_path "${hw_proto}" PATH) # Generated sources set(hw_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/loadBalancerControl.pb.cc") set(hw_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/loadBalancerControl.pb.h") set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/loadBalancerControl.grpc.pb.cc") set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/loadBalancerControl.grpc.pb.h") . . . # Targets greeter_[async_](client|server) foreach(_target lbcontrol_client lbcontrol_server)
If other include files and libraries need to be compiled with and linked against, you'll need to make changes. Following are changes needed to include code using the ET system.
- Copy the cmake/Modules/FindET.cmake file from github's ejfat repository (ersap branch) into the cpp/cmake/Modules directory so cmake can find things.
- Set the "CODA" environmental variable (used by FindEt.cmake) which should point to a CODA installation directory with ET headers and shared library. (If you do things differently, you'll need to modify FindET.cmake).
- Finally you'll need to edit the cpp/loadBalancerControl/CMakefile.txt file so it can use FindET.cmake to find the ET includes and libs.
# ET includes and libs list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Modules) # Finding ET libs and includes involve looking at CODA install directory if (DEFINED ENV{CODA}) message(STATUS "CODA = " $ENV{CODA}) else() message(FATAL_ERROR "Set the \"CODA\" env var so that ET libs and includes can be found!") endif() find_package(ET) if (NOT ET_FOUND) message( FATAL_ERROR "Et cannot be found" ) endif() # Include generated *.pb.h files include_directories("${CMAKE_CURRENT_BINARY_DIR}" "${ET_INCLUDE_DIRS}") # hw_grpc_proto add_library(hw_grpc_proto ${hw_grpc_srcs} ${hw_grpc_hdrs} ${hw_proto_srcs} ${hw_proto_hdrs}) target_link_libraries(hw_grpc_proto ${ET_LIBRARY} ${_REFLECTION} ${_GRPC_GRPCPP} ${_PROTOBUF_LIBPROTOBUF})
- Now recompile
cd cpp/loadBalancerControl rm -fr cmake mkdir -p cmake/build cd cmake/build cmake -DCMAKE_PREFIX_PATH=$GRPC_INSTALL_DIR -DBUILD_SHARED_LIBS=ON ../.. make -j 4
The application in this case is the reporting to the control plane of the fill level of an ERSAP backend reassembler's fifo.