pub async fn run_local_handler<F, Fut, R, Msg, Context>(
message_handler: F,
) -> Result<R, Error>where
F: Fn(Msg, Arc<Context>) -> Fut,
Fut: Future<Output = Result<R>>,
Msg: DeserializeOwned,
Context: LocalContext<Msg> + Debug,Expand description
Executes a message handler against the message provided by the LocalContext.
The run_local_handler function takes care of the following tasks:
- Sets up tracing to ensure all
tracing::<...>!()calls are JSON formatted for consumption by CloudWatch. - Initialises a shared context object, which is passed to your handler.
- Initialises a single message object, which is passed to your handler.
§Writing a message handler
To write a message handler, you need to define four elements:
- The
Messagestructure, which defines the structure of the messages which will be sent to your message handler. - The
Contextstructure, which represents the shared state that will be passed into your message handler. This structure needs to implement the LocalContext trait. - The
message_handlerfunction, which accepts aMessageand aContext, and performs the desired actions.
§Example
use anyhow::Result;
use async_trait::async_trait;
use clap::Parser;
use serde::Deserialize;
use std::fmt::Debug;
use std::sync::Arc;
use cobalt_aws::lambda::{run_local_handler, Error, LocalContext};
#[tokio::main]
async fn main() -> Result<(), Error> {
let result = run_local_handler(message_handler).await?;
Ok(())
}
/// The structure of the messages to be processed by our message handler.
#[derive(Debug, Deserialize)]
pub struct Message {
pub target: String,
}
/// Shared context we build up before invoking the local runner.
#[derive(Debug)]
pub struct Context {
pub greeting: String,
}
#[async_trait]
impl LocalContext<Message> for Context {
/// Initialise a shared context object which will be
/// passed to the message handler.
async fn from_local() -> Result<Self> {
Ok(Context {
greeting: "Hello".to_string(),
})
}
/// Construct a message to be processed.
async fn msg(&self) -> Result<Message> {
Ok(Message {
target: "World".to_string(),
})
}
}
/// Process a single message, within the given context.
async fn message_handler(message: Message, context: Arc<Context>) -> Result<()> {
tracing::debug!("Message: {:?}", message);
tracing::debug!("Context: {:?}", context);
// Log a greeting to the target
tracing::info!("{}, {}!", context.greeting, message.target);
Ok(())
}