Skip to main content

sark_core/manifold/server/app/
mod.rs

1//! Static application binding for HTTP server carriers.
2
3use dope_core::driver::{
4    self,
5    schedule::{app, clock, ready},
6};
7use o3::{buffer::resident, depot::capacity};
8use resident::bound;
9use sark_http::field::metadata::section::rules;
10
11use crate::manifold::{
12    schedule,
13    server::{self, drain, timing},
14};
15
16mod error;
17pub use error::Error;
18
19/// Cold-path resource requirements supplied by one application.
20#[derive(Clone, Copy, PartialEq, Eq)]
21pub struct Layout {
22    streams: usize,
23    bytes: usize,
24}
25
26impl Layout {
27    pub const fn new(streams: usize, bytes: usize) -> Self {
28        Self { streams, bytes }
29    }
30
31    pub const fn streams(self) -> usize {
32        self.streams
33    }
34
35    pub const fn bytes(self) -> usize {
36        self.bytes
37    }
38}
39
40/// Exact carrier capacities available to one application connection.
41#[derive(Clone, Copy, PartialEq, Eq)]
42pub struct Capacity {
43    streams: capacity::Count,
44    data: u32,
45}
46
47impl Capacity {
48    pub const fn new(streams: capacity::Count, data: u32) -> Self {
49        Self { streams, data }
50    }
51
52    pub const fn streams(self) -> capacity::Count {
53        self.streams
54    }
55
56    pub const fn data(self) -> u32 {
57        self.data
58    }
59}
60
61/// Borrowed resources for one application admission turn.
62pub struct Turn<'a, 'work, 'borrow, 'd, O> {
63    owner: O,
64    work: app::Work<'work, 'd>,
65    wake: ready::Target<'d>,
66    driver: &'a mut driver::Context<'borrow, 'd>,
67}
68
69impl<'a, 'work, 'borrow, 'd, O> Turn<'a, 'work, 'borrow, 'd, O> {
70    pub fn new(
71        owner: O,
72        work: app::Work<'work, 'd>,
73        wake: ready::Target<'d>,
74        driver: &'a mut driver::Context<'borrow, 'd>,
75    ) -> Self {
76        Self {
77            owner,
78            work,
79            wake,
80            driver,
81        }
82    }
83
84    pub fn owner(&self) -> O
85    where
86        O: Copy,
87    {
88        self.owner
89    }
90
91    pub const fn work(&self) -> app::Work<'work, 'd> {
92        self.work
93    }
94
95    pub const fn wake(&self) -> ready::Target<'d> {
96        self.wake
97    }
98
99    pub fn driver(&mut self) -> &mut driver::Context<'borrow, 'd> {
100        self.driver
101    }
102}
103
104/// Header plan and resource layout known before a carrier is constructed.
105pub trait Spec {
106    type Failure;
107    type Fields: rules::Policy;
108    type Egress<'d>: bound::Bound;
109
110    fn layout(&self) -> Layout;
111}
112
113/// Binds an exact-lifetime application to one concrete carrier and owner.
114pub trait Bind<'d, C, O>: Spec<Egress<'d>: 'd> + Sized
115where
116    C: server::Connection,
117{
118    type App: Application<
119            'd,
120            C,
121            O,
122            Fields = Self::Fields,
123            Failure = Self::Failure,
124            Egress<'d> = Self::Egress<'d>,
125        >;
126    type Error;
127
128    fn bind(self) -> Result<Self::App, Self::Error>;
129}
130
131/// Monomorphized semantic runtime driven by a protocol-specific host.
132pub trait Application<'d, C, O>: Spec<Egress<'d>: 'd>
133where
134    C: server::Connection,
135{
136    type State;
137    type Timing;
138    type Build;
139
140    fn state(&self, capacity: Capacity) -> Result<Self::State, Self::Build>;
141
142    fn drive<H>(
143        &mut self,
144        state: &mut Self::State,
145        carrier: &mut C,
146        turn: &mut Turn<'_, '_, '_, 'd, O>,
147        egress: schedule::Egress,
148        context: &mut H,
149        protocol: impl FnMut(
150            &mut H,
151            &mut C,
152            &mut drain::Events<'_, 'd>,
153            &Self::State,
154        ) -> Result<Option<server::Event<C>>, C::Error>,
155        notify: impl FnMut(&mut H, schedule::Wake<C::Key>),
156        finish: impl FnOnce(&mut H, &mut C),
157        report: impl FnMut(&mut H, Error<C::Error, Self::Failure>),
158    ) -> Result<drain::Progress, Error<C::Error, Self::Failure>>;
159
160    fn close(&mut self, state: &mut Self::State, carrier: &mut C, owner: O);
161
162    fn selected(state: &Self::State, event: &server::Event<C>) -> bool;
163
164    fn wake(state: &mut Self::State, wake: schedule::Wake<C::Key>) -> bool;
165
166    /// Records released egress capacity without executing application work.
167    fn released(state: &mut Self::State);
168
169    fn activity(state: &Self::State) -> schedule::Quiescence;
170}
171
172/// Deadline query implemented only by applications with timed state.
173pub trait Timed<'d, C, O>: Application<'d, C, O, Timing = timing::On>
174where
175    C: server::Connection,
176{
177    fn deadline(&self, state: &Self::State) -> Option<clock::Deadline<'d>>;
178}