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}