Skip to content

Performance: MockBot restarts Actix server on every dispatch() call #41

@stepan-romankov

Description

@stepan-romankov

Hi! First of all, thanks for creating this testing library - it's been very helpful for testing teloxide bots.

I noticed that MockBot::dispatch() creates a new ServerManager instance on every call, which starts and stops an Actix HTTP server for each dispatched update:

pub async fn dispatch(&mut self) {
    self.state.lock().unwrap().reset();

    let server = ServerManager::start(self.me.clone(), self.state.clone())
        .await
        .unwrap();  // New server every time

    // ... dispatch logic ...

    server.stop().await.unwrap();  // Server stopped
}

For integration tests that simulate realistic user flows (e.g., multi-step registration, ordering workflows), this adds significant overhead. A test with 50+ dispatch calls can take several minutes due to repeated server startup/shutdown.

Questions:

Is there a specific reason the server is restarted on each dispatch? (e.g., state isolation, thread safety concerns)
Would you be open to a PR that keeps the server alive across dispatches and only resets the response state?
Proposed change:

The server could be started lazily on first dispatch and reused for subsequent calls:

pub async fn dispatch(&mut self) {
    // Only reset responses, not the entire server
    self.state.lock().unwrap().responses = Responses::default();

    // Start server only if not already running
    if self.server.is_none() {
        self.server = Some(ServerManager::start(...).await?);
    }

    // ... dispatch using existing server ...
    
    // Server stays alive, stopped on MockBot::drop()
}

This would preserve the existing API while significantly improving performance for multi-dispatch test scenarios.

I've prototyped this approach locally and saw test times drop from ~60s to ~1s for a 20-dispatch test. Happy to submit a PR if you think this direction makes sense.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions