pub struct Unit { /* private fields */ }
Expand description
The Unit application context.
This object wraps the libunit
library, which talks to the Unit server over
shared memory and a unix socket in order to receive data about requests.
This object is not Send
nor Sync
, and cannot be sent to other
threads.
However, multiple objects of this type may be created; additional Unit
objects will automatically be linked to the first through a global mutex,
and will be able to receive and process requests in other threads.
The first context is internally wrapped in an Arc
, shared among all
instances Unit
and will be deallocated when the last Unit
object is
dropped.
Implementations§
Source§impl Unit
impl Unit
Sourcepub fn new() -> Result<Self, UnitInitError>
pub fn new() -> Result<Self, UnitInitError>
Create a new Unit context capable of receiving and handling requests on the current thread.
If called after a previous Unit
was constructed but already received
a QUIT event from the Unit server, this will return a no-op Unit
instance whose Unit::run
method will immediately return.
If called after a previous Unit
failed to initialize, this will
return the same initialization failure.
Examples found in repository?
More examples
5fn main() {
6 let mut unit = Unit::new().unwrap();
7
8 unit.set_request_handler(|req: Request| {
9 let headers = &[("Content-Type", "text/plain")];
10 let body = "Hello world!\n";
11 req.send_response(200, headers, body)?;
12
13 Ok(())
14 });
15
16 unit.run();
17}
7fn main() {
8 let mut unit = Unit::new().unwrap();
9
10 unit.set_request_handler(HttpHandler::new(|req: Request<Vec<u8>>| {
11 let body = format!("Hello world!\n\nBody length: {}\n", req.body().len());
12
13 // The Unit server redirects stdout/stderr to the server log.
14 eprintln!("Received reqest for: {}", req.uri().path());
15
16 if req.uri().path() == "/panic" {
17 // The HttpHandler converts panics into 501 errors. This imposes an
18 // UnwindSafe restriction on the request handler.
19 panic!("The /panic path panics!")
20 }
21
22 let response = Response::builder()
23 .header("Content-Type", "text/plain")
24 .body(body.into_bytes())
25 .unwrap();
26
27 Ok(response)
28 }));
29
30 unit.run();
31}
29fn worker(thread_id: i32, global_visits: Arc<AtomicI32>) {
30 let mut unit = Unit::new().unwrap();
31
32 // Thread state, available through a mutable, unique reference.
33 let mut thread_visits = 0;
34
35 unit.set_request_handler(move |req: Request| {
36 if req.path() == "/panic" {
37 // This library supports safely forwarding panics through the FFI.
38 panic!("The /panic path panics!")
39 }
40
41 let headers = &[("Content-Type", "text/plain")];
42 let body = "Hello world!\n";
43 req.send_response(200, headers, body)?;
44 thread_visits += 1;
45 global_visits.fetch_add(1, Ordering::Release);
46
47 req.send_chunk_with_buffer(4096, |buf| {
48 writeln!(
49 buf,
50 "Thread {} visits: {} (global visits: {})",
51 thread_id,
52 thread_visits,
53 global_visits.load(Ordering::Acquire),
54 )
55 .unwrap();
56 Ok(())
57 })?;
58
59 Ok(())
60 });
61
62 unit.run();
63}
Sourcepub fn set_request_handler(&mut self, f: impl UnitService + 'static)
pub fn set_request_handler(&mut self, f: impl UnitService + 'static)
Set a request handler for the Unit application.
The handler must be an object that implements the UnitService
trait.
This trait is automatically implemented for functions or lambda
functions that take a Request
object and return a
UnitResult<()>
.
Examples found in repository?
More examples
5fn main() {
6 let mut unit = Unit::new().unwrap();
7
8 unit.set_request_handler(|req: Request| {
9 let headers = &[("Content-Type", "text/plain")];
10 let body = "Hello world!\n";
11 req.send_response(200, headers, body)?;
12
13 Ok(())
14 });
15
16 unit.run();
17}
7fn main() {
8 let mut unit = Unit::new().unwrap();
9
10 unit.set_request_handler(HttpHandler::new(|req: Request<Vec<u8>>| {
11 let body = format!("Hello world!\n\nBody length: {}\n", req.body().len());
12
13 // The Unit server redirects stdout/stderr to the server log.
14 eprintln!("Received reqest for: {}", req.uri().path());
15
16 if req.uri().path() == "/panic" {
17 // The HttpHandler converts panics into 501 errors. This imposes an
18 // UnwindSafe restriction on the request handler.
19 panic!("The /panic path panics!")
20 }
21
22 let response = Response::builder()
23 .header("Content-Type", "text/plain")
24 .body(body.into_bytes())
25 .unwrap();
26
27 Ok(response)
28 }));
29
30 unit.run();
31}
29fn worker(thread_id: i32, global_visits: Arc<AtomicI32>) {
30 let mut unit = Unit::new().unwrap();
31
32 // Thread state, available through a mutable, unique reference.
33 let mut thread_visits = 0;
34
35 unit.set_request_handler(move |req: Request| {
36 if req.path() == "/panic" {
37 // This library supports safely forwarding panics through the FFI.
38 panic!("The /panic path panics!")
39 }
40
41 let headers = &[("Content-Type", "text/plain")];
42 let body = "Hello world!\n";
43 req.send_response(200, headers, body)?;
44 thread_visits += 1;
45 global_visits.fetch_add(1, Ordering::Release);
46
47 req.send_chunk_with_buffer(4096, |buf| {
48 writeln!(
49 buf,
50 "Thread {} visits: {} (global visits: {})",
51 thread_id,
52 thread_visits,
53 global_visits.load(Ordering::Acquire),
54 )
55 .unwrap();
56 Ok(())
57 })?;
58
59 Ok(())
60 });
61
62 unit.run();
63}
Sourcepub fn run(&mut self)
pub fn run(&mut self)
Enter the main event loop, handling requests on this thread until the Unit server exits or requests a restart.
This may be executed in parallel with other threads that call
Unit::run()
Examples found in repository?
More examples
5fn main() {
6 let mut unit = Unit::new().unwrap();
7
8 unit.set_request_handler(|req: Request| {
9 let headers = &[("Content-Type", "text/plain")];
10 let body = "Hello world!\n";
11 req.send_response(200, headers, body)?;
12
13 Ok(())
14 });
15
16 unit.run();
17}
7fn main() {
8 let mut unit = Unit::new().unwrap();
9
10 unit.set_request_handler(HttpHandler::new(|req: Request<Vec<u8>>| {
11 let body = format!("Hello world!\n\nBody length: {}\n", req.body().len());
12
13 // The Unit server redirects stdout/stderr to the server log.
14 eprintln!("Received reqest for: {}", req.uri().path());
15
16 if req.uri().path() == "/panic" {
17 // The HttpHandler converts panics into 501 errors. This imposes an
18 // UnwindSafe restriction on the request handler.
19 panic!("The /panic path panics!")
20 }
21
22 let response = Response::builder()
23 .header("Content-Type", "text/plain")
24 .body(body.into_bytes())
25 .unwrap();
26
27 Ok(response)
28 }));
29
30 unit.run();
31}
29fn worker(thread_id: i32, global_visits: Arc<AtomicI32>) {
30 let mut unit = Unit::new().unwrap();
31
32 // Thread state, available through a mutable, unique reference.
33 let mut thread_visits = 0;
34
35 unit.set_request_handler(move |req: Request| {
36 if req.path() == "/panic" {
37 // This library supports safely forwarding panics through the FFI.
38 panic!("The /panic path panics!")
39 }
40
41 let headers = &[("Content-Type", "text/plain")];
42 let body = "Hello world!\n";
43 req.send_response(200, headers, body)?;
44 thread_visits += 1;
45 global_visits.fetch_add(1, Ordering::Release);
46
47 req.send_chunk_with_buffer(4096, |buf| {
48 writeln!(
49 buf,
50 "Thread {} visits: {} (global visits: {})",
51 thread_id,
52 thread_visits,
53 global_visits.load(Ordering::Acquire),
54 )
55 .unwrap();
56 Ok(())
57 })?;
58
59 Ok(())
60 });
61
62 unit.run();
63}