Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Processor creation

A processor in ProSA is an autonomous routine executed within its own thread(s). Processor interact with each other through internal TVF messages.

Creation

The Proc module contains everything you need to create a processor, along with an example processor and configuration.

To create a processor, use the proc macro, and implement the Proc trait.

Given a settings struct named MyProcSettings for your processor, your processor struct declaration would look like this:

#[proc(settings = MyProcSettings)]
pub struct MyProc { /* No members here */ }

The macro currently does not allow you to add members directly to your struct.

This is usually not an issue, as you can instantiate and use variables within internal_run() (the main loop of the processor).

You can still declare methods on your struct as needed:

#[proc]
impl MyProc
{
    fn internal_func() {
        // You can declare additional helper functions here
    }
}

Finally, implement the Proc trait.

Here's an example skeleton:

#[proc]
impl<A> Proc<A> for MyProc
where
    A: Adaptor + std::marker::Send + std::marker::Sync,
{
    async fn internal_run(&mut self, name: String) -> Result<(), Box<dyn ProcError + Send + Sync>> {
        // TODO: Initialize your adaptor here

        // Register the processor if ready to run
        self.proc.add_proc().await?;

        loop {
            if let Some(msg) = self.internal_rx_queue.recv().await {
                match msg {
                    InternalMsg::Request(msg) => {
                        // TODO: process the request
                    }
                    InternalMsg::Response(msg) => {
                        // TODO: process the response
                    }
                    InternalMsg::Error(err) => {
                        // TODO: process the error
                    }
                    InternalMsg::Command(_) => todo!(),
                    InternalMsg::Config => todo!(),
                    InternalMsg::Service(table) => self.service = table,
                    InternalMsg::Shutdown => {
                        adaptor.terminate();
                        self.proc.remove_proc(None).await?;
                        return Ok(());
                    }
                }
            }
        }
    }
}

The generic parameter A represents the adaptor type your processor uses. Specify in the where clause which traits your adaptor must implement (commonly, Adaptor plus Send and Sync)

Specific TVF

Sometimes, you may want your processor to handle only specific TVF objects, possibly to optimize data handling performance or to provide dedicated logic. In these cases, explicitly implement the Proc trait for your processor, parameterized by the specific TVF type:

#[proc]
impl<A> Proc<A> for MyProc<SimpleStringTvf>
where
    A: Adaptor + std::marker::Send + std::marker::Sync,
{
    async fn internal_run(&mut self, name: String) -> Result<(), Box<dyn ProcError + Send + Sync>> {
        // Custom handling for SimpleStringTvf
    }
}