Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[server] Should we support "internal" interfaces? #68

Open
jamesmunns opened this issue Dec 17, 2024 · 0 comments
Open

[server] Should we support "internal" interfaces? #68

jamesmunns opened this issue Dec 17, 2024 · 0 comments
Labels
wontfix This will not be worked on

Comments

@jamesmunns
Copy link
Owner

In #26 (comment), a user asked about offering internal interfaces, e.g. the ability to act as a client within the server itself.

My current opinion on this is "no, we shouldn't". I'm leaving this as a tracking issue in case people would like to discuss, or to point them here if they ask how to do this.

This is for a couple of reasons:

First, we would need to EITHER ask the user to pay the cost of ser/de, to allow re-use of the current code, or to use "multiple interface" code discussed in #67; OR we would need to introduce a new path that skips the ser/de parts of the dispatcher. However, if we choose the latter, you could "just" call the blocking or async handler functions directly, if you are able to "manufacture" the context necessary to pass to the functions. spawn handlers are a little more complicated as they are oriented around passing in a Sender, so this isn't a complete solution

Second, my opinion here is that you are better off just writing "normal code" for this, and sharing the resources between your internal tasks and the postcard-rpc server. For example, if you had some SPI sensor, you could wrap it in a mutex, and give one handle to the postcard-rpc server and one to your internal task. Something like:

type MutexSensor = Mutex<ThreadModeRawMutex, Sensor<Spi>>;
static SPI_SENSOR: StaticCell<MutexSensor> = StaticCell::new();

#[embassy_executor::main]
async fn main(spawner: Spawner) {
    // ...
    let sensor: &'static MutexSensor = SPI_SENSOR.init(...);
    
    // Set up postcard-rpc server
    let context = Context { sensor };
    let dispatcher = MyApp::new(context, spawner.into());
    let mut server: AppServer = Server::new(
        tx_impl,
        rx_impl,
        pbufs.rx_buf.as_mut_slice(),
        dispatcher,
        vkk,
    );
    
    // Spawn internal tasks
    spawner.must_spawn(my_internal_task(sensor));
    
    // ...
}

// this is a handler for a postcard-rpc endpoint
async fn get_spi_data(ctx: &mut Context, hdr: VarHeader, req: ()) -> SensorData {
    ctx.sensor.lock().await.read_data().await
}

// This is an internal task
#[embassy_executor::task]
async fn my_internal_task(sensor: &'static MutexSensor) {
    loop {
        Timer::after(Duration::from_millis(100)).await;
        let reading = sensor.lock().await.read_data().await;
        // ...
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

1 participant