Worker

Since we have two methods, we will add a struct to perform remote calls of these methods from a worker thread. Add the Action enumeration to the code:

enum Action {
StartRollCall,
MarkItself,
}

It has two variants: StartRollCall to perform the remote start_roll_call method call, and the MarkItself variant to call the remote mark_itself method.

Now we can add a function to spawn a worker in a separate thread. If we will perform outgoing calls immediately in incoming method handlers, we can block the execution, because we have a ring of microservices and blocking one microservice will block the whole ring's interaction.

No blocking is an important property of a reactive microservice. The microservices have to process all calls in parallel or asynchronously, but never block execution for a long time. They should work like actors in the actors model we have discussed.

Look at the spawn_worker function:

fn spawn_worker() -> Result<Sender<Action>, Error> {
let (tx, rx) = channel();
let next: SocketAddr = env::var("NEXT")?.parse()?;
thread::spawn(move || {
let remote = Remote::new(next);
let mut in_roll_call = false;
for action in rx.iter() {
match action {
Action::StartRollCall => {
if !in_roll_call {
if remote.start_roll_call().is_ok() {
debug!("ON");
in_roll_call = true;
}
} else {
if remote.mark_itself().is_ok() {
debug!("OFF");
in_roll_call = false;
}
}
}
Action::MarkItself => {
if in_roll_call {
if remote.mark_itself().is_ok() {
debug!("OFF");
in_roll_call = false;
}
} else {
debug!("SKIP");
}
}
}
}
});
Ok(tx)
}

This function creates a channel and spawns a new thread with a routine that processes all received messages from a channel. We create the Remote instance with the address extracted from the NEXT environment variable.

There is a flag that shows that the start_roll_call method has been called. We set it to true when the StartRollCall message is received and the start_roll_call method of the remote server is called. If the flag is already set to true and the routine received the StartRollCall message, the thread will call the mark_itself remote method. In other words, we will call the start_roll_call methods of all running service instances. When all services set the flag to true, we will call the mark_itself methods of all services.

Let's start a server and run a ring of services.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.210.205