Difference between revisions of "How to create a C++ gRPC application"

From epsciwiki
Jump to navigation Jump to search
Line 105: Line 105:
 
</blockquote>
 
</blockquote>
  
==='''If other include files and libraries need to be compiled with and linked against, modify cpp/loadBalancerControl/CMakefile.txt in accordance. Following are changes needed to include code using the ET system.===
+
==='''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.
+
* 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 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).
+
* 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.
 
* 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.
  
Line 113: Line 113:
 
<blockquote>
 
<blockquote>
 
<pre>
 
<pre>
project(LoadBalancerControl C CXX)
+
# 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()
  
# Targets greeter_[async_](client|server)
+
find_package(ET)
foreach(_target
+
if (NOT ET_FOUND)
  lbcontrol_client lbcontrol_server)
+
    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})
 
</pre>
 
</pre>
 
</blockquote>
 
</blockquote>

Revision as of 19:13, 19 December 2022

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.