perspective_server/local_session.rs
1// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7// ┃ Copyright (c) 2017, the Perspective Authors. ┃
8// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9// ┃ This file is part of the Perspective library, distributed under the terms ┃
10// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
13use perspective_client::Session;
14
15use crate::ffi;
16use crate::server::{Server, ServerError};
17
18/// A struct for implementing [`perspective_client::Session`] against an
19/// same-process [`Server`] instance.
20///
21/// See also [`perspective_client::ProxySession`] for implement the trait
22/// against an arbitrary remote transport.
23#[derive(Debug)]
24pub struct LocalSession {
25 pub(crate) id: u32,
26 pub(crate) server: Server,
27 pub(crate) closed: bool,
28}
29
30impl Drop for LocalSession {
31 fn drop(&mut self) {
32 if !self.closed {
33 tracing::error!("`Session` dropped without `Session::close`");
34 }
35 }
36}
37
38impl Session<ServerError> for LocalSession {
39 async fn handle_request(&self, request: &[u8]) -> Result<(), ServerError> {
40 let request = ffi::Request::from(request);
41 let responses = self.server.server.handle_request(self.id, &request);
42 for response in responses.iter_responses() {
43 let cb = self
44 .server
45 .callbacks
46 .read()
47 .await
48 .get(&response.client_id())
49 .cloned();
50
51 if let Some(f) = cb {
52 f(response.msg()).await?;
53 }
54 }
55
56 Ok(())
57 }
58
59 async fn poll(&self) -> Result<(), ServerError> {
60 let responses = self.server.server.poll(self.id);
61 for response in responses.iter_responses() {
62 let cb = self
63 .server
64 .callbacks
65 .read()
66 .await
67 .get(&response.client_id())
68 .cloned();
69
70 if let Some(f) = cb {
71 f(response.msg()).await?;
72 }
73 }
74
75 Ok(())
76 }
77
78 async fn close(mut self) {
79 self.closed = true;
80 self.server.server.close_session(self.id);
81 self.server
82 .callbacks
83 .write()
84 .await
85 .remove(&self.id)
86 .expect("Already closed");
87 }
88}