aws-lambda-rust-runtime の現時点でのリリース版 (0.2) で Tokio を使うときのイディオム。
現状 reqwest や rusoto_dynamodb が tokio 0.2 のランタイムを要求するのに、aws-lambda-rust-runtime が async 対応していないという面倒くささがある(master を使えば対応はしているのであるが)。
結論としてはこんな感じにしておけばいい。
async fn handler(event: Event, context: Context) -> Result<(), HandlerError> {
// ...
}
fn main() {
let mut rt = tokio::runtime::Runtime::new().unwrap();
lambda!(move |event, context| rt.block_on(handler(event, context)));
}ポイントは runtime は tokio::main ではなく明示的に生成するのと、この runtime をクロージャで使うこと。将来 handler が async で定義できる流れではあると思うので、今からそうしておいた方がいいと思う。
これはダメな例。
fn handler(event: Event, context: Context) -> Result<(), HandlerError> {
futures::executor::block_on(/* ... */)
}
#[tokio::main]
async fn main() {
lambda!(handler);
}おそらく futures と tokio の executor が混ざってしまうからだと思うのだが、この構成だと一応動きはするものの、しばらく Lambda で動かしておくと定期的にタイムアウト(future の解決に失敗している感じ)が起きてしまい、安定して動かなかった。
構成を改めてからは安定して動作している。