-
Notifications
You must be signed in to change notification settings - Fork 14
RustBasicService
Anson edited this page Jan 8, 2026
·
1 revision
This example is a reimplementation of example 4 in Rust. There's really not much to say here, as in the previous example the code is very similar to the code in the C++ version.
For the provider, we first set up the request listener:
struct MultiplicationServiceProvider {}
impl GravityServiceProvider for MultiplicationServiceProvider {
fn request(&mut self, _service_id: &str, data_product: &GravityDataProduct) -> GravityDataProduct {
//Just to be safe. In theory this can never happen unless this class is registered with more than one serviceID types.
if data_product.data_product_id() != "Multiplication" {
SpdLog::error("Request is not for multiplication!");
return GravityDataProduct::with_id("BadRequest");
}
// Get the params for this result
let mut params = MultiplicationOperandsPB::new();
data_product.populate_message(&mut params);
SpdLog::warn(format!(
"Request Received: {} x {}",
params.multiplicand_a(),
params.multiplicand_b()));
// Do the calculation
let result = params.multiplicand_a() * params.multiplicand_b();
// Return the results to the requestor
let mut result_pb = MultiplicationResultPB::new();
result_pb.set_result(result);
let result_gdp = GravityDataProduct::with_id("MultiplicationResult");
result_gdp.set_data(&result_pb);
result_gdp
}
}Once that's done, we can register it:
let msp = MultiplicationServiceProvider {};
gn.register_service(
//This identifies the Service to the service directory so that others can
// make a request to it.
"Multiplication",
//Assign a transport type to the socket (almost always tcp, unless you are only
//using the gravity data product between two processes on the same computer).
GravityTransportType.TCP,
//Give an instance of the multiplication service trait to be called when a request is made for multiplication.
// Note that this is not a token, but you are directly giving the GravityNode ownership of the GravityServiceProvider
msp);And for the requester, we setup the response listener:
struct MultiplicationRequestor {}
//After multiplication is requested, this trait object may be called with the result.
impl GravityRequestor for MultiplicationRequestor {
fn request_filled(&mut self, _service_id: &str, request_id: &str, response: &GravityDataProduct) {
// Parse the message into a protobuf
let mut result = MultiplicationResultPB::new();
response.populate_message(&mut result);
// Write the answer
SpdLog::warn(format!(
"Asynchronous response received: {} = {}", request_id, result.result()
));
let mut data = GOT_ASYNC.lock().expect("Something already has this");
*data = true;
}
fn request_timeout(&mut self, _: &str, _: &str) {
}
}And then we make the asynchronous request that uses the listener:
/////////////////////////////
// Set up the first multiplication request
let requestor = gn.tokenize_requestor(MultiplicationRequestor {});
let mult_request1 = GravityDataProduct::with_id("Multiplication");
let mut params1 = MultiplicationOperandsPB::new();
params1.set_multiplicand_a(8);
params1.set_multiplicand_b(2);
mult_request1.set_data(¶ms1);
// Make an asynchronous request
while gn.request_async_with_request_id(
"Multiplication", // Service name
&mult_request1, // Request
&requestor, // token representing the object with the callback
"8 x 2" // string identifying which request this is
) != GravityReturnCode::SUCCESS {
SpdLog::warn("request to Multiplication servicec failed, retrying...");
std::thread::sleep(time::Duration::from_millis(1000));
}And lastly, we make the synchronous request against the same service:
/////////////////////////////////////////
// Set up the second multiplication request
let mult_request2 = GravityDataProduct::with_id("Multiplication");
let mut params2 = MultiplicationOperandsPB::new();
params2.set_multiplicand_a(5);
params2.set_multiplicand_b(7);
mult_request2.set_data(¶ms2);
// Make a synchronous request for multiplication
// Returns Option<GravityDataProduct>
let mult_sync = gn.request_sync_with_timeout(
"Multiplication", // Service name
&mult_request2, // Request
1000); // Timeout in milliseconds
match mult_sync {
None => SpdLog::error("Request returned None"),
Some( gdp ) => {
let mut result = MultiplicationResultPB::new();
gdp.populate_message(&mut result);
SpdLog::warn(format!(
"Synchronous response received: 5 x 7 = {}", result.result()
));
}
}