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
//! SnapStart lifecycle support.
//!
//! AWS Lambda SnapStart reduces cold start latency by taking a Firecracker
//! microVM snapshot of the initialized execution environment and restoring from
//! it on subsequent invocations. Resources initialized before the snapshot may
//! become invalid after restore: TCP connections are dropped, credentials may
//! expire, and unique values generated during init would be shared across every
//! restored instance.
//!
//! Implement [`SnapStartResource`] on types that hold such resources and
//! register them with
//! [`Runtime::register_snapstart_resource`](crate::Runtime::register_snapstart_resource).
//! The runtime invokes the registered hooks around the snapshot/restore boundary
//! when SnapStart is enabled (`AWS_LAMBDA_INITIALIZATION_TYPE == "snap-start"`)
//! and does nothing otherwise.
//!
//! # Ordering
//!
//! Resources are orchestrated with stack (LIFO/FIFO) ordering, mirroring how
//! Go's `defer`, middleware unwinding, and Rust destructors work:
//!
//! - [`before_snapshot`](SnapStartResource::before_snapshot) runs in **reverse**
//! registration order (LIFO) — dependents tear down before their foundations.
//! - [`after_restore`](SnapStartResource::after_restore) runs in **registration**
//! order (FIFO) — foundations rebuild before the dependents that need them.
//!
//! The rule for users is one line: **register foundations first** (e.g.
//! credentials before the pool that uses them, the pool before the cache that
//! uses it). Teardown and rebuild then both happen in the correct relative order
//! automatically:
//!
//! ```text
//! register: credentials → pool → cache
//! before_snapshot: cache → pool → credentials (reverse)
//! after_restore: credentials → pool → cache (forward)
//! ```
//!
//! # Example
//!
//! ```no_run
//! use lambda_runtime::{BoxFuture, Error, SnapStartResource};
//!
//! struct DbPool {
//! // e.g. a connection pool handle
//! }
//!
//! impl SnapStartResource for DbPool {
//! fn before_snapshot(&self) -> BoxFuture<'_, Result<(), Error>> {
//! Box::pin(async move {
//! // release connections before the snapshot
//! Ok(())
//! })
//! }
//!
//! fn after_restore(&self) -> BoxFuture<'_, Result<(), Error>> {
//! Box::pin(async move {
//! // re-establish connections after restore
//! Ok(())
//! })
//! }
//! }
//! ```
use crate::;
/// A resource that needs custom logic around the SnapStart snapshot/restore
/// boundary.
///
/// Implement this trait on types holding snapshot-sensitive state (connection
/// pools, credentials, cached DNS, etc.) and register them with
/// [`Runtime::register_snapstart_resource`](crate::Runtime::register_snapstart_resource).
///
/// Both methods default to a no-op, so implementors only override the hook they
/// need. See the [module docs](crate::snapstart) for ordering semantics.
///
/// Each method returns a [`BoxFuture`] (rather than being an `async fn`) so the
/// trait stays object-safe and can be stored as `dyn SnapStartResource` without
/// pulling in the `async-trait` crate. Implementations wrap their body in
/// `Box::pin(async move { .. })`.