Skip to content

Commit 42e4247

Browse files
authored
fix: msg_id for internal message and allow custom trace_id (#46)
* fix: msg_id for internal message and allow custom trace_id * feat: Add ServiceError code to help for metrics Signed-off-by: Jeremy HERGAULT <jeremy.hergault@worldline.com>
1 parent 84b0b63 commit 42e4247

8 files changed

Lines changed: 63 additions & 57 deletions

File tree

prosa/examples/proc.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ where
3838
.add_service_proc(vec![String::from("PROC_TEST")])
3939
.await?;
4040
let mut interval = time::interval(time::Duration::from_secs(4));
41-
let mut msg_id: u64 = 0;
4241
let mut pending_msgs: PendingMsgs<RequestMsg<M>, M> = Default::default();
4342
loop {
4443
tokio::select! {
@@ -80,17 +79,15 @@ where
8079
tvf.put_string(2, String::from("request"));
8180

8281
let stub_service_name = String::from("STUB_TEST");
83-
if let Some(service) = self.service.get_proc_service(&stub_service_name, msg_id) {
82+
if let Some(service) = self.service.get_proc_service(&stub_service_name) {
8483
debug!("The service is find: {:?}", service);
85-
service.proc_queue.send(InternalMsg::Request(RequestMsg::new(msg_id, stub_service_name, tvf.clone(), self.proc.get_service_queue()))).await.unwrap();
86-
msg_id += 1;
84+
service.proc_queue.send(InternalMsg::Request(RequestMsg::new(stub_service_name, tvf.clone(), self.proc.get_service_queue()))).await.unwrap();
8785
}
8886

8987
let proc_service_name = String::from("PROC_TEST");
90-
if let Some(service) = self.service.get_proc_service(&proc_service_name, msg_id) {
88+
if let Some(service) = self.service.get_proc_service(&proc_service_name) {
9189
debug!("The service is find: {:?}", service);
92-
service.proc_queue.send(InternalMsg::Request(RequestMsg::new(msg_id, proc_service_name, tvf, self.proc.get_service_queue()))).await.unwrap();
93-
msg_id += 1;
90+
service.proc_queue.send(InternalMsg::Request(RequestMsg::new(proc_service_name, tvf, self.proc.get_service_queue()))).await.unwrap();
9491
}
9592
},
9693
Some(msg) = pending_msgs.pull(), if !pending_msgs.is_empty() => {

prosa/src/core/msg.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use std::{
2-
sync::Arc,
2+
sync::{Arc, atomic},
33
time::{Duration, SystemTime},
44
};
55

66
use prosa_utils::msg::tvf::Tvf;
77
use tokio::sync::mpsc;
8-
use tracing::span;
98
use tracing::{Level, Span, event};
9+
use tracing::{info_span, span};
1010

1111
use crate::core::error::BusError;
1212

@@ -139,6 +139,8 @@ where
139139
P: FnOnce(&mut M) -> bool;
140140
}
141141

142+
pub(crate) static ATOMIC_INTERNAL_MSG_ID: atomic::AtomicU64 = atomic::AtomicU64::new(0);
143+
142144
/// ProSA request message that define a data message that need to be process by a processor
143145
#[derive(Debug)]
144146
pub struct RequestMsg<M>
@@ -206,16 +208,30 @@ where
206208
M: Sized + Clone + Tvf,
207209
{
208210
/// Method to create a new RequestMessage
209-
pub fn new(
210-
id: u64,
211+
pub fn new(service: String, data: M, response_queue: mpsc::Sender<InternalMsg<M>>) -> Self {
212+
let begin_time = SystemTime::now();
213+
let span = info_span!("prosa::Msg", service = service);
214+
RequestMsg {
215+
id: ATOMIC_INTERNAL_MSG_ID.fetch_add(1, atomic::Ordering::Relaxed),
216+
service,
217+
data: Some(data),
218+
begin_time,
219+
span,
220+
response_queue,
221+
}
222+
}
223+
224+
/// Method to create a new RequestMessage with a specific trace Id
225+
pub fn new_with_trace_id(
211226
service: String,
212227
data: M,
213228
response_queue: mpsc::Sender<InternalMsg<M>>,
229+
trace_id: tracing::span::Id,
214230
) -> Self {
215231
let begin_time = SystemTime::now();
216-
let span = span!(Level::INFO, "prosa::Msg", service = service);
232+
let span = info_span!(parent: trace_id, "prosa::Msg", service = service);
217233
RequestMsg {
218-
id,
234+
id: ATOMIC_INTERNAL_MSG_ID.fetch_add(1, atomic::Ordering::Relaxed),
219235
service,
220236
data: Some(data),
221237
begin_time,
@@ -389,18 +405,6 @@ impl<M> ErrorMsg<M>
389405
where
390406
M: Sized + Clone + Tvf,
391407
{
392-
/// Method to create a new ErrorMsg
393-
pub fn new(id: u64, service: String, span: Span, data: Option<M>, err: ServiceError) -> Self {
394-
ErrorMsg {
395-
id,
396-
service,
397-
span,
398-
error_time: SystemTime::now(),
399-
data,
400-
err,
401-
}
402-
}
403-
404408
/// Getter of the service error
405409
pub fn get_err(&self) -> &ServiceError {
406410
&self.err

prosa/src/core/service.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::core::msg;
2+
13
use super::{
24
msg::InternalMsg,
35
proc::{ProcBusParam, ProcParam},
@@ -6,6 +8,7 @@ use prosa_utils::msg::tvf::{Tvf, TvfError};
68
use std::{
79
collections::HashMap,
810
fmt::{self, Debug},
11+
sync::atomic,
912
};
1013
use thiserror::Error;
1114
use tokio::sync::mpsc;
@@ -47,10 +50,13 @@ where
4750
/// Method to get a processor that respond to the service
4851
///
4952
/// Call by the processor to send a transaction to a processor that give the corresponding service
50-
pub fn get_proc_service(&self, name: &str, msg_id: u64) -> Option<&ProcService<M>> {
53+
pub fn get_proc_service(&self, name: &str) -> Option<&ProcService<M>> {
5154
if let Some(services) = self.table.get(name) {
5255
match services.len() {
53-
2.. => services.get(msg_id as usize % services.len()),
56+
2.. => services.get(
57+
msg::ATOMIC_INTERNAL_MSG_ID.load(atomic::Ordering::Relaxed) as usize
58+
% services.len(),
59+
),
5460
1 => services.first(),
5561
_ => None,
5662
}
@@ -231,6 +237,22 @@ pub enum ServiceError {
231237
ProtocolError(String),
232238
}
233239

240+
impl ServiceError {
241+
/// Method to get the error code of the service error
242+
/// - 0: No error
243+
/// - 1: Unable to reach service
244+
/// - 2: Timeout
245+
/// - 3: Protocol error
246+
pub fn get_code(&self) -> u8 {
247+
match self {
248+
ServiceError::NoError(_) => 0,
249+
ServiceError::UnableToReachService(_) => 1,
250+
ServiceError::Timeout(_, _) => 2,
251+
ServiceError::ProtocolError(_) => 3,
252+
}
253+
}
254+
}
255+
234256
impl From<TvfError> for ServiceError {
235257
fn from(err: TvfError) -> Self {
236258
match err {

prosa/src/event/pending.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ where
260260
/// let mut pending_msg: PendingMsgs<RequestMsg<SimpleStringTvf>, SimpleStringTvf> = Default::default();
261261
/// let mut msg: Option<RequestMsg<SimpleStringTvf>> = pending_msg.pull().await;
262262
/// assert!(msg.is_none());
263-
/// pending_msg.push(RequestMsg::new(1, String::from("service"), tvf, queue), Duration::from_millis(200));
263+
/// pending_msg.push(RequestMsg::new(String::from("service"), tvf, queue), Duration::from_millis(200));
264264
/// msg = pending_msg.pull().await;
265265
/// assert!(msg.is_some());
266266
/// println!("Timeout message {:?}", msg);
@@ -344,8 +344,8 @@ mod tests {
344344
assert_eq!(1, pending_timer.len());
345345
},
346346
InternalMsg::Service(table) => {
347-
if let Some(service) = table.get_proc_service("TEST", 1) {
348-
service.proc_queue.send(InternalMsg::Request(RequestMsg::new(1, String::from("TEST"), Default::default(), self.proc.get_service_queue().clone()))).await.unwrap();
347+
if let Some(service) = table.get_proc_service("TEST") {
348+
service.proc_queue.send(InternalMsg::Request(RequestMsg::new(String::from("TEST"), Default::default(), self.proc.get_service_queue().clone()))).await.unwrap();
349349
}
350350
},
351351
_ => return Err(BusError::ProcComm(self.get_proc_id(), 0, String::from("Wrong message"))),
@@ -380,10 +380,10 @@ mod tests {
380380
assert_eq!(1, pending_msg.len());
381381
},
382382
InternalMsg::Service(table) => {
383-
if let Some(service) = table.get_proc_service("TEST", 1) {
383+
if let Some(service) = table.get_proc_service("TEST") {
384384
let mut msg: SimpleStringTvf = Default::default();
385385
msg.put_string(1, "good");
386-
service.proc_queue.send(InternalMsg::Request(RequestMsg::new(1, String::from("TEST"), msg, self.proc.get_service_queue().clone()))).await.unwrap();
386+
service.proc_queue.send(InternalMsg::Request(RequestMsg::new(String::from("TEST"), msg, self.proc.get_service_queue().clone()))).await.unwrap();
387387
}
388388
},
389389
_ => return Err(BusError::ProcComm(self.get_proc_id(), 0, String::from("Wrong message"))),

prosa/src/inj/proc.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@ where
212212
// Create a message regulator
213213
let mut regulator = self.settings.get_regulator();
214214
let mut next_transaction = Some(adaptor.build_transaction());
215-
let mut msg_id: u64 = 0;
216215

217216
// Wait for service table
218217
while !self.service.exist_proc_service(&self.settings.service_name) {
@@ -231,17 +230,15 @@ where
231230

232231
// Send first transaction
233232
self.service
234-
.get_proc_service(&self.settings.service_name, msg_id)
233+
.get_proc_service(&self.settings.service_name)
235234
.unwrap()
236235
.proc_queue
237236
.send(InternalMsg::Request(RequestMsg::new(
238-
msg_id,
239237
self.settings.service_name.clone(),
240238
next_transaction.take().unwrap(),
241239
self.proc.get_service_queue(),
242240
)))
243241
.await?;
244-
msg_id += 1;
245242
regulator.notify_send_transaction();
246243

247244
loop {
@@ -250,17 +247,16 @@ where
250247
self.process_internal(name.as_str(), msg, &mut adaptor, &mut regulator, &mut next_transaction, &meter_trans_duration).await?;
251248
}
252249
_ = regulator.tick() => {
253-
if let Some(service) = self.service.get_proc_service(&self.settings.service_name, msg_id) {
250+
if let Some(service) = self.service.get_proc_service(&self.settings.service_name) {
254251
let trans = if let Some(transaction) = next_transaction.take() {
255-
RequestMsg::new(msg_id, self.settings.service_name.clone(), transaction, self.proc.get_service_queue())
252+
RequestMsg::new(self.settings.service_name.clone(), transaction, self.proc.get_service_queue())
256253
} else {
257-
RequestMsg::new(msg_id, self.settings.service_name.clone(), adaptor.build_transaction(), self.proc.get_service_queue())
254+
RequestMsg::new(self.settings.service_name.clone(), adaptor.build_transaction(), self.proc.get_service_queue())
258255
};
259256

260257
debug!(name: "inj_proc", target: "prosa::inj::proc", parent: trans.get_span(), proc_name = name, service = self.settings.service_name, request = format!("{:?}", trans.get_data()));
261258
service.proc_queue.send(InternalMsg::Request(trans)).await?;
262259

263-
msg_id += 1;
264260
regulator.notify_send_transaction();
265261
}
266262
},

prosa/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ mod tests {
9393
request: M,
9494
) -> MaybeAsync<Result<M, ServiceError>> {
9595
assert!(!request.is_empty());
96-
COUNTER.fetch_add(1, Ordering::Relaxed);
96+
COUNTER.fetch_add(1, Ordering::SeqCst);
9797
Ok(request.clone()).into()
9898
}
9999
}
@@ -126,7 +126,7 @@ mod tests {
126126
main_task.await.unwrap();
127127

128128
// Check exchanges messages
129-
let nb_trans = COUNTER.load(Ordering::Relaxed) as u64;
129+
let nb_trans = COUNTER.load(Ordering::SeqCst) as u64;
130130
let estimated_trans = WAIT_TIME.as_secs() * 5;
131131
assert!(nb_trans > (estimated_trans - 2) && nb_trans < (estimated_trans + 2));
132132
// Should have a coherent number of transaction with the regulator

prosa_book/src/ch03-05-service.md

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,6 @@ After that, you are free to call any services.
165165
// Register the processor
166166
self.proc.add_proc().await?;
167167
168-
// Need to have a unique message id when you send a message
169-
let mut msg_id = 0;
170-
171168
// Wait for the service table before sending messages to a service
172169
loop {
173170
if let Some(msg) = self.internal_rx_queue.recv().await {
@@ -192,16 +189,13 @@ After that, you are free to call any services.
192189
}
193190
194191
// Attempt to send a message if the service is available
195-
if let Some(service) = self.service.get_proc_service("SERVICE_NAME", msg_id) {
192+
if let Some(service) = self.service.get_proc_service("SERVICE_NAME") {
196193
let trans = RequestMsg::new(
197-
msg_id,
198194
String::from("SERVICE_NAME"),
199195
M::default(),
200196
self.proc.get_service_queue()
201197
);
202198
service.proc_queue.send(InternalMsg::Request(trans)).await?;
203-
204-
msg_id += 1;
205199
}
206200
}
207201
@@ -228,9 +222,6 @@ The logic is similar to single senders, but you specify the queue when sending m
228222
// Register the processor
229223
self.proc.add_proc().await?;
230224
231-
// Need to have a unique message id when you send a message
232-
let mut msg_id = 0;
233-
234225
// Create a queue for subtask communication
235226
let (tx_queue, mut rx_queue) = tokio::sync::mpsc::channel(2048);
236227
let tx_msg_queue = tx_queue.clone();
@@ -265,16 +256,13 @@ The logic is similar to single senders, but you specify the queue when sending m
265256
}
266257
267258
// Attempt to send a message if the service is available
268-
if let Some(service) = self.service.get_proc_service("SERVICE_NAME", msg_id) {
259+
if let Some(service) = self.service.get_proc_service("SERVICE_NAME") {
269260
let trans = RequestMsg::new(
270-
msg_id,
271261
String::from("SERVICE_NAME"),
272262
M::default(),
273263
tx_msg_queue.clone()
274264
);
275265
service.proc_queue.send(InternalMsg::Request(trans)).await?;
276-
277-
msg_id += 1;
278266
}
279267
})
280268

prosa_book/src/ch03-06-events.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ There are three important methods you need to use for this object:
3333
.add_service_proc(vec![String::from("PROC_TEST")])
3434
.await?;
3535
let mut interval = time::interval(time::Duration::from_secs(4));
36-
let mut msg_id: u64 = 0;
3736
let mut pending_msgs: PendingMsgs<RequestMsg<M>, M> = Default::default();
3837
loop {
3938
tokio::select! {

0 commit comments

Comments
 (0)