Skip to content

[codex] Implement simplified flame-rs API#456

Merged
k82cn merged 9 commits into
xflops:mainfrom
k82cn:flm_455
May 16, 2026
Merged

[codex] Implement simplified flame-rs API#456
k82cn merged 9 commits into
xflops:mainfrom
k82cn:flm_455

Conversation

@k82cn
Copy link
Copy Markdown
Contributor

@k82cn k82cn commented May 16, 2026

Summary

  • add the RFE455 design report and implement the simplified flame-rs client API
  • add FlameMessage, typed task/common-data helpers, SessionOptions, Session::invoke, Session::run, and TaskHandle
  • add optional flame-rs-macros support for #[derive(FlameMessage)], #[entrypoint], and #[instance]
  • polish flmping to use the typed macro path and update flmexec to use the new session/root runner helpers

Validation

  • cargo fmt
  • cargo check -p flame-rs
  • cargo check -p flame-rs --features macros
  • cargo check -p flmping
  • cargo check -p flmexec
  • cargo test -p flame-rs --lib --features macros
  • cargo test -p flame-rs --features macros --test rfe455_macro_test
  • cargo metadata --no-deps --format-version 1
  • git diff --check

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a higher-level Rust SDK API for Flame, significantly reducing boilerplate for both clients and services. Key features include the FlameMessage trait for typed payload serialization, ergonomic client helpers like SessionOptions and TaskHandle, and procedural macros (#[entrypoint] and #[instance]) for defining services. The flmping and flmexec components have been refactored to utilize these new APIs. Review feedback identifies a blocking std::thread::sleep call in an asynchronous context, inconsistencies in error mapping within the macro implementation compared to the design document, and the use of unwrap() in documentation examples which contradicts the project's reliability goals.

Comment thread flmping/src/service.rs Outdated

let mem_size = Byte::from_u64(mem.len() as u64).to_string();
if let Some(duration) = input.duration {
thread::sleep(Duration::from_millis(duration));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using std::thread::sleep in an async function is problematic as it blocks the executor's thread, preventing other tasks from running. This can lead to performance issues and deadlocks in a concurrent environment. You should use the asynchronous version from tokio: ::tokio::time::sleep(...).await.

Suggested change
thread::sleep(Duration::from_millis(duration));
::tokio::time::sleep(Duration::from_millis(duration)).await;

#[flame_rs::instance]
impl ModelService {
async fn enter(&self, _instance: FlameInstance) -> Result<(), FlameError> {
*self.assets.lock().unwrap() = Some(load_assets()?);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The example code here and in the following lines (513, 514, 518) uses .unwrap() on Mutex lock results. This can cause the service to panic if the lock is poisoned. This contradicts the design's own reliability goal on line 1022, which states that "Generated code must avoid unwrap." The generated code sketch starting at line 872 correctly handles poisoned locks with map_err. It would be best to update this example to reflect the same robust error handling to provide a consistent and safe implementation pattern.

Comment on lines +133 to +146
impl #impl_generics #crate_path::message::FlameMessage for #name #ty_generics #where_clause {
fn encode(
&self,
) -> ::std::result::Result<#crate_path::__private::bytes::Bytes, #crate_path::apis::FlameError> {
#crate_path::__private::serde_json::to_vec(self)
.map(#crate_path::__private::bytes::Bytes::from)
.map_err(|err| #crate_path::apis::FlameError::InvalidConfig(err.to_string()))
}

fn decode(bytes: &[u8]) -> ::std::result::Result<Self, #crate_path::apis::FlameError> {
#crate_path::__private::serde_json::from_slice(bytes)
.map_err(|err| #crate_path::apis::FlameError::Internal(err.to_string()))
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The error mapping for encode and decode seems to be swapped compared to the design document and general error handling principles.

  1. encode: An error during encoding a service's response should be an Internal error. The current implementation maps it to InvalidConfig.
  2. decode: An error when decoding a client's request should be an InvalidConfig error. The current implementation maps it to Internal.

This is inconsistent with the design document (RFE455), which specifies on lines 990 and 997 that decode failures should be InvalidConfig and encode failures should be Internal.

Suggested change
impl #impl_generics #crate_path::message::FlameMessage for #name #ty_generics #where_clause {
fn encode(
&self,
) -> ::std::result::Result<#crate_path::__private::bytes::Bytes, #crate_path::apis::FlameError> {
#crate_path::__private::serde_json::to_vec(self)
.map(#crate_path::__private::bytes::Bytes::from)
.map_err(|err| #crate_path::apis::FlameError::InvalidConfig(err.to_string()))
}
fn decode(bytes: &[u8]) -> ::std::result::Result<Self, #crate_path::apis::FlameError> {
#crate_path::__private::serde_json::from_slice(bytes)
.map_err(|err| #crate_path::apis::FlameError::Internal(err.to_string()))
}
}
impl #impl_generics #crate_path::message::FlameMessage for #name #ty_generics #where_clause {
fn encode(
&self,
) -> ::std::result::Result<#crate_path::__private::bytes::Bytes, #crate_path::apis::FlameError> {
#crate_path::__private::serde_json::to_vec(self)
.map(#crate_path::__private::bytes::Bytes::from)
.map_err(|err| #crate_path::apis::FlameError::Internal(err.to_string()))
}
fn decode(bytes: &[u8]) -> ::std::result::Result<Self, #crate_path::apis::FlameError> {
#crate_path::__private::serde_json::from_slice(bytes)
.map_err(|err| #crate_path::apis::FlameError::InvalidConfig(err.to_string()))
}
}

@codecov
Copy link
Copy Markdown

codecov Bot commented May 16, 2026

@k82cn k82cn merged commit 2bf8043 into xflops:main May 16, 2026
6 checks passed
@k82cn k82cn deleted the flm_455 branch May 16, 2026 21:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant