1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//! Hyper runtime glue: an executor and a timer backed by runite.
//!
//! Hyper 1.x is runtime-agnostic: beyond the transport traits (implemented for
//! [`TcpStream`](crate::net::TcpStream) — and, on Unix, `net::unix::UnixStream`
//! — under this same `hyper` feature), some of its machinery needs a way to
//! *spawn* internal futures and a way to *sleep*:
//!
//! - HTTP/2 (client and server) multiplexes streams onto one connection and
//! spawns per-stream futures through a [`hyper::rt::Executor`] —
//! [`RuniteExecutor`] here.
//! - Timed options — `http1::Builder::header_read_timeout`, HTTP/2 keep-alive,
//! and friends — need a [`hyper::rt::Timer`]; without one they panic at
//! runtime with "no timer configured". [`RuniteTimer`] provides it.
//!
//! Both are zero-sized handles onto the *current runtime thread*: hyper calls
//! them from within connection tasks that already run on this thread's event
//! loop, so everything a connection spawns or schedules stays local, in keeping
//! with the event-loop-per-thread model.
//!
//! # Examples
//!
//! Serving HTTP/2 with hyper on a runite thread:
//!
//! ```no_run
//! use runite::hyper_rt::{RuniteExecutor, RuniteTimer};
//!
//! # async fn example(stream: runite::net::TcpStream) -> Result<(), Box<dyn std::error::Error>> {
//! let service = hyper::service::service_fn(|_req| async {
//! Ok::<_, std::convert::Infallible>(hyper::Response::new(String::from("hi")))
//! });
//!
//! hyper::server::conn::http2::Builder::new(RuniteExecutor)
//! .timer(RuniteTimer)
//! .serve_connection(stream, service)
//! .await?;
//! # Ok(())
//! # }
//! ```
use Future;
use Pin;
use ;
use ;
use ;
use crate;
/// A [`hyper::rt::Executor`] that spawns hyper's internal futures onto the
/// current runite thread.
///
/// Hyper's connection machinery (most importantly the per-stream futures of an
/// HTTP/2 connection) hands futures to this executor from within connection
/// tasks already running on a runite event loop, so [`crate::spawn`] places
/// them on the same thread. The futures are detached; hyper manages their
/// lifetimes through its own connection state.
///
/// Calling `execute` on a thread with no runite runtime installed would
/// lazily initialize one there (see [`crate::spawn`]); in normal use hyper
/// only invokes it on the thread driving the connection.
;
/// A [`hyper::rt::Timer`] backed by runite's timer wheel.
///
/// Unlocks hyper's timed options (`header_read_timeout`, HTTP/2 keep-alive,
/// etc.), which panic at runtime when no timer is configured.
///
/// Hyper requires its sleep futures to be `Send + Sync`, while runite's own
/// [`Sleep`](crate::time::Sleep) is thread-local. The sleeps produced here are
/// therefore built on the runtime's thread-safe completion primitive: the
/// timer is registered on the runtime thread that first polls the sleep (for
/// hyper, the thread driving the connection), and completing or cancelling it
/// routes through that owner thread. Dropping a sleep on its owning thread
/// cancels the underlying timer immediately; dropping it on another thread is
/// best-effort — the timer fires at its deadline as a no-op, briefly keeping
/// that loop alive.
;
/// `Send + Sync` sleep future for [`RuniteTimer`].
///
/// Lazily arms a runtime timeout on first poll (which must happen on a runite
/// thread — for hyper, the connection's thread). The completion pair carries
/// the wake back to whichever task polls this future, and its cancel hook
/// tears the timeout down if the sleep is dropped early.