Skip to content

Commit b48a08d

Browse files
committed
Add lambda runtime support
Summary: This PR adds the support to run the user services on Amazon Lambda
1 parent 24c829d commit b48a08d

File tree

5 files changed

+403
-13
lines changed

5 files changed

+403
-13
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ default = ["http_server", "rand", "uuid", "tracing-span-filter"]
2222
hyper = ["dep:hyper", "http-body-util", "restate-sdk-shared-core/http"]
2323
http_server = ["hyper", "hyper/server", "hyper/http2", "hyper-util", "tokio/net", "tokio/signal", "tokio/macros"]
2424
tracing-span-filter = ["dep:tracing-subscriber"]
25+
lambda = [ "dep:http-serde", "dep:lambda_runtime", "dep:aws_lambda_events"]
2526

2627
[dependencies]
2728
bytes = "1.10"
@@ -43,6 +44,9 @@ tokio = { version = "1.44", default-features = false, features = ["sync"] }
4344
tracing = "0.1"
4445
tracing-subscriber = { version = "0.3", features = ["registry"], optional = true }
4546
uuid = { version = "1.16.0", optional = true }
47+
http-serde = { version = "2.1.1", optional = true }
48+
aws_lambda_events = { version = "0.16.1", optional = true }
49+
lambda_runtime = { version = "0.14.2", optional = true }
4650

4751
[dev-dependencies]
4852
tokio = { version = "1", features = ["full"] }

README.md

Lines changed: 81 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010

1111
## Community
1212

13-
* 🤗️ [Join our online community](https://discord.gg/skW3AZ6uGd) for help, sharing feedback and talking to the community.
14-
* 📖 [Check out our documentation](https://docs.restate.dev) to get quickly started!
15-
* 📣 [Follow us on Twitter](https://twitter.com/restatedev) for staying up to date.
16-
* 🙋 [Create a GitHub issue](https://github.com/restatedev/sdk-java/issues) for requesting a new feature or reporting a problem.
17-
* 🏠 [Visit our GitHub org](https://github.com/restatedev) for exploring other repositories.
13+
- 🤗️ [Join our online community](https://discord.gg/skW3AZ6uGd) for help, sharing feedback and talking to the community.
14+
- 📖 [Check out our documentation](https://docs.restate.dev) to get quickly started!
15+
- 📣 [Follow us on Twitter](https://twitter.com/restatedev) for staying up to date.
16+
- 🙋 [Create a GitHub issue](https://github.com/restatedev/sdk-java/issues) for requesting a new feature or reporting a problem.
17+
- 🏠 [Visit our GitHub org](https://github.com/restatedev) for exploring other repositories.
1818

1919
## Using the SDK
2020

@@ -58,6 +58,74 @@ async fn main() {
5858
}
5959
```
6060

61+
## Running on Lambda
62+
63+
The Restate Rust SDK supports running services on AWS Lambda using Lambda Function URLs. This allows you to deploy your Restate services as serverless functions.
64+
65+
### Setup
66+
67+
First, enable the `lambda` feature in your `Cargo.toml`:
68+
69+
```toml
70+
[dependencies]
71+
restate-sdk = { version = "0.1", features = ["lambda"] }
72+
tokio = { version = "1", features = ["full"] }
73+
```
74+
75+
### Basic Lambda Service
76+
77+
Here's how to create a simple Lambda service:
78+
79+
```rust
80+
use restate_sdk::prelude::*;
81+
82+
#[restate_sdk::service]
83+
trait Greeter {
84+
async fn greet(name: String) -> HandlerResult<String>;
85+
}
86+
87+
struct GreeterImpl;
88+
89+
impl Greeter for GreeterImpl {
90+
async fn greet(&self, _: Context<'_>, name: String) -> HandlerResult<String> {
91+
Ok(format!("Greetings {name}"))
92+
}
93+
}
94+
95+
#[tokio::main]
96+
async fn main() {
97+
// To enable logging/tracing
98+
// tracing_subscriber::fmt::init();
99+
100+
// Build and run the Lambda endpoint
101+
Endpoint::builder()
102+
.bind(GreeterImpl.serve())
103+
.build_lambda()
104+
.run()
105+
.await
106+
.unwrap();
107+
}
108+
```
109+
110+
### Deployment
111+
112+
1. Install `cargo-lambda`
113+
```
114+
cargo install cargo-lambda
115+
```
116+
2. Build your Lambda function:
117+
118+
```bash
119+
cargo lambda build --release --arm64 --output-format zip
120+
```
121+
122+
3. Create a Lambda function with the following configuration:
123+
124+
- **Runtime**: Amazon Linux 2023
125+
- **Architecture**: arm64
126+
127+
4. Upload your `zip` file to the Lambda function.
128+
61129
### Logging
62130

63131
The SDK uses tokio's [`tracing`](https://docs.rs/tracing/latest/tracing/) crate to generate logs.
@@ -121,15 +189,15 @@ The Rust SDK is currently in active development, and might break across releases
121189

122190
The compatibility with Restate is described in the following table:
123191

124-
| Restate Server\sdk-rust | 0.0 - 0.2 | 0.3 | 0.4 - 0.5 | 0.6 |
125-
|-------------------------|-----------|-----|-----------|------------------|
126-
| 1.0 | | | ||
127-
| 1.1 | | | ||
128-
| 1.2 | | | ||
129-
| 1.3 | | | | ✅ <sup>(1)</sup> |
130-
| 1.4 | | | ||
192+
| Restate Server\sdk-rust | 0.0 - 0.2 | 0.3 | 0.4 - 0.5 | 0.6 |
193+
| ----------------------- | --------- | --- | --------- | ----------------- |
194+
| 1.0 |||||
195+
| 1.1 |||||
196+
| 1.2 |||||
197+
| 1.3 |||| ✅ <sup>(1)</sup> |
198+
| 1.4 |||||
131199

132-
<sup>(1)</sup> **Note** `bind_with_options` works only from Restate 1.4 onward.
200+
<sup>(1)</sup> **Note** `bind_with_options` works only from Restate 1.4 onward.
133201

134202
## Contributing
135203

src/endpoint/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub struct InputReceiver(InputReceiverInner);
4343
enum InputReceiverInner {
4444
Channel(tokio::sync::mpsc::UnboundedReceiver<Result<Bytes, BoxError>>),
4545
BoxedStream(Pin<Box<dyn Stream<Item = Result<Bytes, BoxError>> + Send + 'static>>),
46+
Bytes(Option<Bytes>),
4647
}
4748

4849
impl InputReceiver {
@@ -54,6 +55,10 @@ impl InputReceiver {
5455
Self(InputReceiverInner::Channel(rx))
5556
}
5657

58+
pub fn from_bytes(b: Bytes) -> Self {
59+
Self(InputReceiverInner::Bytes(Some(b)))
60+
}
61+
5762
async fn recv(&mut self) -> Option<Result<Bytes, BoxError>> {
5863
poll_fn(|cx| self.poll_recv(cx)).await
5964
}
@@ -62,6 +67,7 @@ impl InputReceiver {
6267
match &mut self.0 {
6368
InputReceiverInner::Channel(ch) => ch.poll_recv(cx),
6469
InputReceiverInner::BoxedStream(s) => s.poll_next_unpin(cx),
70+
InputReceiverInner::Bytes(b) => Poll::Ready(b.take().map(Ok)),
6571
}
6672
}
6773
}
@@ -432,6 +438,11 @@ impl Builder {
432438
Ok(self)
433439
}
434440

441+
pub(crate) fn set_protocol_mode(mut self, mode: crate::discovery::ProtocolMode) -> Self {
442+
self.discovery.protocol_mode = Some(mode);
443+
self
444+
}
445+
435446
/// Build the [`Endpoint`].
436447
pub fn build(self) -> Endpoint {
437448
Endpoint(Arc::new(EndpointInner {
@@ -440,6 +451,14 @@ impl Builder {
440451
identity_verifier: self.identity_verifier,
441452
}))
442453
}
454+
455+
#[cfg(feature = "lambda")]
456+
pub fn build_lambda(self) -> crate::lambda::LambdaEndpoint {
457+
crate::lambda::LambdaEndpoint::new(
458+
self.set_protocol_mode(crate::discovery::ProtocolMode::RequestResponse)
459+
.build(),
460+
)
461+
}
443462
}
444463

445464
/// This struct encapsulates all the business logic to handle incoming requests to the SDK,

0 commit comments

Comments
 (0)