Skip to content

Commit 33d7e7b

Browse files
docs(bottlecap): update README with accurate Managed Instance implementation details
1 parent 4238fa4 commit 33d7e7b

1 file changed

Lines changed: 48 additions & 13 deletions

File tree

bottlecap/README.md

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,21 @@ Bottlecap supports several flush strategies that control when and how observabil
3030
### Managed Instance Mode vs On-Demand Mode
3131

3232
#### Managed Instance Mode
33-
- **Activation**: Automatically enabled when Lambda uses managed instances (concurrent execution environment)
33+
Lambda Managed Instances run your functions on EC2 instances (managed by AWS) with multi-concurrent invocations. This requires setting up a **capacity provider** - a configuration that defines VPC settings, instance requirements, and scaling parameters for the managed instances.
34+
35+
- **Activation**: Detected automatically via the `AWS_LAMBDA_INITIALIZATION_TYPE` environment variable. When this equals `"lambda-managed-instances"`, Bottlecap enters Managed Instance mode
3436
- **Flush Behavior**:
35-
- A dedicated background task continuously flushes data at regular intervals (default: 60 seconds)
37+
- A dedicated background task continuously flushes data at regular intervals (default: 30 seconds)
3638
- All flushes are **non-blocking** and run concurrently with invocation processing
3739
- Prevents resource buildup by skipping a flush cycle if the previous flush is still in progress
3840
- `DD_SERVERLESS_FLUSH_STRATEGY` is **ignored** in this mode
3941
- **Shutdown Behavior**:
4042
- Background flusher waits for pending flushes to complete before shutdown
4143
- Final flush ensures all remaining data is sent before the execution environment terminates
42-
- **Use case**: High-concurrency Lambda functions with multiple concurrent invocations
44+
- **Execution Model**: Multi-concurrent invocations where one execution environment handles multiple invocations simultaneously (unlike traditional Lambda's one-invocation-per-environment model)
45+
- **Use case**: Steady-state, high-volume workloads where optimizing costs with predictable capacity is desired
4346
- **Key advantage**: Zero flush overhead per invocation - flushing happens independently in the background
47+
- **Infrastructure**: Lambda launches 3 instances by default for availability zone resiliency when a function version is published to a capacity provider
4448

4549
#### On-Demand Mode (Traditional Mode)
4650
- **Activation**: Default mode for standard Lambda execution (one invocation at a time)
@@ -89,7 +93,7 @@ Bottlecap supports several flush strategies that control when and how observabil
8993

9094
| Mode | Strategy | Blocking? | Adapts? | Best For |
9195
|------|----------|-----------|---------|----------|
92-
| **Managed Instance** | *Always Continuous* | ❌ No | ❌ No | High-concurrency Lambda with concurrent invocations |
96+
| **Managed Instance** | *Always Continuous* | ❌ No | ❌ No | Steady-state high-volume workloads with multi-concurrent invocations |
9397
| **On-Demand** | Default | Initially yes, then no | ✅ Yes | General use - auto-optimizes |
9498
| **On-Demand** | End | ✅ Yes | ❌ No | Minimal overhead, sporadic invocations |
9599
| **On-Demand** | EndPeriodically | ✅ Yes | ❌ No | Long-running functions with progress visibility |
@@ -99,32 +103,55 @@ Bottlecap supports several flush strategies that control when and how observabil
99103
### Implementation Details
100104

101105
#### Managed Instance Mode Implementation
102-
Located in `bottlecap/src/bin/bottlecap/main.rs` (lines 581-828):
103-
- **Background Flusher Task** (lines 611-653):
106+
Located in `bottlecap/src/bin/bottlecap/main.rs`:
107+
- **Mode Detection** (`bottlecap/src/config/aws.rs`):
108+
- Checks if `AWS_LAMBDA_INITIALIZATION_TYPE` environment variable equals `"lambda-managed-instances"`
109+
- **Event Subscription** (`bottlecap/src/extension/mod.rs`):
110+
- Only subscribes to `SHUTDOWN` events (not `INVOKE` events)
111+
- On-Demand mode subscribes to both `INVOKE` and `SHUTDOWN` events
112+
- **Flush Strategy Override**:
113+
- Function: `get_flush_strategy_for_mode()`
114+
- If user configures a non-continuous strategy, it's overridden to continuous with a warning
115+
- Uses `DEFAULT_CONTINUOUS_FLUSH_INTERVAL` (30 seconds) from `flush_control.rs`
116+
- **Main Event Loop**:
117+
- Processes events from the event bus (telemetry events like `platform.start`, `platform.report`)
118+
- Does NOT call `/next` endpoint for each invocation (only for shutdown)
119+
- Uses `tokio::select!` with biased ordering to prioritize telemetry events over shutdown signals
120+
- **Background Flusher Task**:
104121
- Spawns at startup and runs until shutdown
105122
- Uses `tokio::select!` to handle periodic flush ticks and shutdown signals
106123
- Calls `PendingFlushHandles::spawn_non_blocking_flushes()` for each flush cycle
107124
- Skips flush if previous flush handles are still pending
108-
- **Non-Blocking Flush Spawning** (lines 140-200):
125+
- **Non-Blocking Flush Spawning**:
126+
- Method: `PendingFlushHandles::spawn_non_blocking_flushes()`
109127
- Spawns separate async tasks for logs, traces, metrics, stats, and proxy flushes
110128
- Each task runs independently without blocking the main event loop
111129
- Failed payloads are tracked for retry in `await_flush_handles()`
112-
- **Shutdown Handling** (lines 655-728):
130+
- **Shutdown Handling**:
113131
- Separate task waits for SHUTDOWN event from Extensions API
114132
- Cancels background flusher and signals main event loop
115-
- Final flush ensures all data is sent before termination (lines 788-826)
133+
- **Final Flush**:
134+
- Function: `blocking_flush_all()`
135+
- Ensures all remaining data is sent before termination
136+
- Uses blocking flush with `force_flush_trace_stats=true`
116137

117138
#### On-Demand Mode Implementation
118-
Located in `bottlecap/src/bin/bottlecap/main.rs` (lines 830-1072):
119-
- **Flush Control**: `bottlecap/src/lifecycle/flush_control.rs`
139+
Located in `bottlecap/src/bin/bottlecap/main.rs`:
140+
- **Flush Control** (`bottlecap/src/lifecycle/flush_control.rs`):
141+
- Function: `evaluate_flush_decision()`
120142
- Evaluates flush strategy and invocation history
121143
- Returns `FlushDecision` enum: `End`, `Periodic`, `Continuous`, or `Dont`
144+
- Adaptive behavior: After ~20 invocations, Default strategy switches from End to Continuous
122145
- **Event Loop**: Uses `FlushControl::evaluate_flush_decision()` to determine flush behavior
123146
- `FlushDecision::End`: Waits for `platform.runtimeDone`, then performs blocking flush
124147
- `FlushDecision::Periodic`: Performs blocking flush at configured interval
125148
- `FlushDecision::Continuous`: Spawns non-blocking flush tasks (similar to Managed Instance)
126149
- `FlushDecision::Dont`: Skips flushing for this cycle
127-
- **Configuration**: `bottlecap/src/config/flush_strategy.rs`
150+
- **Final Flush**:
151+
- Function: `blocking_flush_all()`
152+
- Blocking flush with `force_flush_trace_stats=true`
153+
- Ensures all remaining data is sent before shutdown
154+
- **Configuration** (`bottlecap/src/config/flush_strategy.rs`):
128155
- Deserializes `DD_SERVERLESS_FLUSH_STRATEGY` environment variable
129156
- Supports formats: `"end"`, `"end,<ms>"`, `"periodically,<ms>"`, `"continuously,<ms>"`
130157

@@ -133,8 +160,16 @@ Located in `bottlecap/src/bin/bottlecap/main.rs` (lines 830-1072):
133160
| Aspect | Managed Instance Mode | On-Demand Mode |
134161
|--------|----------------------|----------------|
135162
| **Event Source** | Telemetry API (platform events) | Extensions API `/next` endpoint |
136-
| **Invocation Model** | Concurrent invocations | Sequential invocations |
163+
| **Invocation Model** | Multi-concurrent (one environment handles multiple invocations) | Single-concurrent (one invocation per environment) |
164+
| **Scaling** | Asynchronous, CPU-based scaling | Reactive scaling with cold starts |
165+
| **Pricing** | EC2 instance-based | Per-request duration-based |
137166
| **Flush Trigger** | Background interval timer | Invocation lifecycle + interval |
138167
| **Strategy Config** | Ignored (always continuous) | Configurable via env var |
139168
| **Main Loop** | Event bus processing | `/next` + event bus processing |
140169
| **Shutdown Detection** | Separate task monitors `/next` | Main loop receives from `/next` |
170+
171+
## References
172+
173+
### AWS Lambda Managed Instances Documentation
174+
- [Introducing AWS Lambda Managed Instances: Serverless simplicity with EC2 flexibility](https://aws.amazon.com/blogs/aws/introducing-aws-lambda-managed-instances-serverless-simplicity-with-ec2-flexibility/) - AWS Blog announcement
175+
- [Lambda Managed Instances - AWS Lambda Developer Guide](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html) - Official AWS documentation

0 commit comments

Comments
 (0)