spawn_with_context

Function spawn_with_context 

Source
pub async fn spawn_with_context<F, T>(
    future: F,
) -> JoinHandle<Result<T, SignerError>>
where F: Future<Output = Result<T, SignerError>> + Send + 'static, T: Send + 'static,
Expand description

Spawns a new task while preserving SignerContext if available.

§Why This Is Necessary

The SignerContext is stored in tokio::task_local! storage, which means it is NOT automatically propagated to new tasks spawned with tokio::spawn. This is a fundamental limitation of task-local storage - it’s only accessible within the same task where it was set.

Without this function, the following would fail:

// WRONG - This will fail with "No signer context"
SignerContext::with_signer(signer, async {
    let handle = tokio::spawn(async {
        // This will fail - SignerContext is not available here!
        let current = SignerContext::current().await?; // ERROR
        transfer_sol("recipient", 1.0).await
    });
    handle.await?
}).await

The correct approach using spawn_with_context:

// CORRECT - This properly propagates the SignerContext
SignerContext::with_signer(signer, async {
    let handle = spawn_with_context(async {
        // SignerContext is available here!
        transfer_sol("recipient", 1.0).await
    }).await;
    handle.await?
}).await

§How It Works

This function:

  1. Checks if a SignerContext exists in the current task
  2. If yes, captures it and wraps the spawned future with SignerContext::with_signer
  3. If no, spawns the task normally without context

This ensures that tools requiring signing operations work correctly when executed through agent frameworks that use task spawning for parallelism.

Note: This function is async because it needs to check for the current signer. The future passed in should return a Result<T, SignerError>.