pub struct Sections { /* private fields */ }Expand description
The sections a request reads, and how to read each one.
Built once, at startup, and handed to the framework adapter. Each entry is a closure the adapter calls when a request begins — never during it, which is what makes the reads agree.
Implementations§
Source§impl Sections
impl Sections
Sourcepub fn new() -> Self
pub fn new() -> Self
An empty list.
Examples found in repository?
62fn main() {
63 let sections = Sections::new()
64 .section(|| Some(state().lock().expect("not poisoned").0.clone()))
65 .section(|| Some(state().lock().expect("not poisoned").1.clone()));
66
67 println!("sections: {:?}\n", sections.names());
68
69 // One `take()` is one reading of every section. Everything read
70 // *through the snapshot* afterwards is from that instant — a reload
71 // in between cannot tear it.
72 let snapshot = sections.take();
73
74 let server = snapshot.require::<Server>().expect("in scope");
75
76 reload(2); // ← a deployment lands mid-request
77
78 let features = snapshot.require::<Features>().expect("in scope");
79
80 println!("through one snapshot, across a reload:");
81 println!(
82 " server = port {}, generation {}",
83 server.port, server.generation
84 );
85 println!(
86 " features = cache {}, generation {} (same instant)\n",
87 features.cache, features.generation
88 );
89 assert_eq!(server.generation, features.generation);
90
91 // The next request's snapshot sees the new state — this is
92 // per-request pinning, not staleness.
93 let next = sections.take();
94
95 println!("the next snapshot:");
96 println!(
97 " features = {:?}\n",
98 next.require::<Features>().expect("in scope")
99 );
100
101 // And the error half: a type nobody declared answers by name.
102 let missing = snapshot.require::<String>().unwrap_err();
103
104 println!("asking for an undeclared section:\n {missing}");
105}Sourcepub fn section<T, F>(self, read: F) -> Self
pub fn section<T, F>(self, read: F) -> Self
Adds one section, read by read.
let sections = Sections::new().section(try_current);In a service read is || Database::try_current(), or
move || handle.current() for a Dynamic<T>.
Registering the same type twice keeps the last reader, so a composed list can override one entry without rebuilding it.
Examples found in repository?
62fn main() {
63 let sections = Sections::new()
64 .section(|| Some(state().lock().expect("not poisoned").0.clone()))
65 .section(|| Some(state().lock().expect("not poisoned").1.clone()));
66
67 println!("sections: {:?}\n", sections.names());
68
69 // One `take()` is one reading of every section. Everything read
70 // *through the snapshot* afterwards is from that instant — a reload
71 // in between cannot tear it.
72 let snapshot = sections.take();
73
74 let server = snapshot.require::<Server>().expect("in scope");
75
76 reload(2); // ← a deployment lands mid-request
77
78 let features = snapshot.require::<Features>().expect("in scope");
79
80 println!("through one snapshot, across a reload:");
81 println!(
82 " server = port {}, generation {}",
83 server.port, server.generation
84 );
85 println!(
86 " features = cache {}, generation {} (same instant)\n",
87 features.cache, features.generation
88 );
89 assert_eq!(server.generation, features.generation);
90
91 // The next request's snapshot sees the new state — this is
92 // per-request pinning, not staleness.
93 let next = sections.take();
94
95 println!("the next snapshot:");
96 println!(
97 " features = {:?}\n",
98 next.require::<Features>().expect("in scope")
99 );
100
101 // And the error half: a type nobody declared answers by name.
102 let missing = snapshot.require::<String>().unwrap_err();
103
104 println!("asking for an undeclared section:\n {missing}");
105}Sourcepub fn section_with_generation<T, F, G>(self, read: F, generation: G) -> Self
pub fn section_with_generation<T, F, G>(self, read: F, generation: G) -> Self
Sourcepub fn is_consistent(&self) -> bool
pub fn is_consistent(&self) -> bool
Sourcepub fn take(&self) -> Snapshot
pub fn take(&self) -> Snapshot
Reads every section once.
Called by the adapter when a request begins. A section that has not
loaded is left out rather than failing the request: the handler that
asks for it gets NotInScope::NotLoaded, and a handler that does
not ask is unaffected.
Examples found in repository?
62fn main() {
63 let sections = Sections::new()
64 .section(|| Some(state().lock().expect("not poisoned").0.clone()))
65 .section(|| Some(state().lock().expect("not poisoned").1.clone()));
66
67 println!("sections: {:?}\n", sections.names());
68
69 // One `take()` is one reading of every section. Everything read
70 // *through the snapshot* afterwards is from that instant — a reload
71 // in between cannot tear it.
72 let snapshot = sections.take();
73
74 let server = snapshot.require::<Server>().expect("in scope");
75
76 reload(2); // ← a deployment lands mid-request
77
78 let features = snapshot.require::<Features>().expect("in scope");
79
80 println!("through one snapshot, across a reload:");
81 println!(
82 " server = port {}, generation {}",
83 server.port, server.generation
84 );
85 println!(
86 " features = cache {}, generation {} (same instant)\n",
87 features.cache, features.generation
88 );
89 assert_eq!(server.generation, features.generation);
90
91 // The next request's snapshot sees the new state — this is
92 // per-request pinning, not staleness.
93 let next = sections.take();
94
95 println!("the next snapshot:");
96 println!(
97 " features = {:?}\n",
98 next.require::<Features>().expect("in scope")
99 );
100
101 // And the error half: a type nobody declared answers by name.
102 let missing = snapshot.require::<String>().unwrap_err();
103
104 println!("asking for an undeclared section:\n {missing}");
105}Sourcepub fn names(&self) -> Vec<&'static str>
pub fn names(&self) -> Vec<&'static str>
The registered type names, in order.
Examples found in repository?
62fn main() {
63 let sections = Sections::new()
64 .section(|| Some(state().lock().expect("not poisoned").0.clone()))
65 .section(|| Some(state().lock().expect("not poisoned").1.clone()));
66
67 println!("sections: {:?}\n", sections.names());
68
69 // One `take()` is one reading of every section. Everything read
70 // *through the snapshot* afterwards is from that instant — a reload
71 // in between cannot tear it.
72 let snapshot = sections.take();
73
74 let server = snapshot.require::<Server>().expect("in scope");
75
76 reload(2); // ← a deployment lands mid-request
77
78 let features = snapshot.require::<Features>().expect("in scope");
79
80 println!("through one snapshot, across a reload:");
81 println!(
82 " server = port {}, generation {}",
83 server.port, server.generation
84 );
85 println!(
86 " features = cache {}, generation {} (same instant)\n",
87 features.cache, features.generation
88 );
89 assert_eq!(server.generation, features.generation);
90
91 // The next request's snapshot sees the new state — this is
92 // per-request pinning, not staleness.
93 let next = sections.take();
94
95 println!("the next snapshot:");
96 println!(
97 " features = {:?}\n",
98 next.require::<Features>().expect("in scope")
99 );
100
101 // And the error half: a type nobody declared answers by name.
102 let missing = snapshot.require::<String>().unwrap_err();
103
104 println!("asking for an undeclared section:\n {missing}");
105}