We have already created functions that create app instances of actix in Chapter 11, Involving Concurrency with Actors and Actix Crate. Return to that chapter if you don't remember how to attach handlers and a state to an application, and look at the main function, as follows:
fn main() -> Result<(), Error> {
env_logger::init();
let mut sys = System::new("rabbit-actix-server");
let tasks = Arc::new(Mutex::new(IndexMap::new()));
let addr = QueueActor::new(
ServerHandler {
tasks: tasks.clone(),
},
&mut sys,
)?;
let state = State {
tasks: tasks.clone(),
addr,
};
server::new(move || {
App::with_state(state.clone())
.middleware(middleware::Logger::default())
.resource("/", |r| r.f(index_handler))
.resource("/task", |r| {
r.method(http::Method::POST).with_async(upload_handler);
})
.resource("/tasks", |r| r.method(http::Method::GET).with_async(tasks_handler))
})
.bind("127.0.0.1:8080")
.unwrap()
.start();
let _ = sys.run();
Ok(())
}
This function creates a System instance with a new method that returns a SystemRunner instance, which we will use to start QueueActor with ServerHandler inside. Then, it creates a State instance with the address of the spawned actor and fills the App object with all the necessary handlers.
When we start a SystemRunner, it creates an actor and connects to RabbitMQ to create all the necessary queues and starts consuming the responses.
We are ready to test this example.