Skip to content

ExecutionPhase after server runtime has been created could usefully include current Tokio runtime handle. #694

@mgs255

Description

@mgs255

What is the problem your feature solves, or the need it fulfills?

In order to use the execution phases to perform any asynchronous operations we need access to the server runtime handle.

Describe the solution you'd like

Update the new ExecutionPhase enum added in 0.6.0 to pass the current runtime handle to any phase after the server is running.

In my case I was trying to initialize an asynchronous memcached client which is used as a 2nd level storage layer, for example:

pub fn init_server(config: &Config) -> Result<Server> {
    // Start pingora server with a much reduced grace period....
    let mut pingora_config = ServerConf::default();
    pingora_config.work_stealing = true;
    pingora_config.grace_period_seconds = Some(15);
    pingora_config.graceful_shutdown_timeout_seconds = Some(10);
    let mut server = Server::new_with_opt_and_conf(None, pingora_config);

    // Set up ExecutionPhase broadcast hook to initialize memcached client as soon as server starts
    let mut phase_watch = server.watch_execution_phase();
    std::thread::spawn(move || {
        while let Ok(phase) = phase_watch.blocking_recv() {
            debug!("Received ExecutionPhase: {:?}", phase);
            if let ExecutionPhase::Running(handle) = phase {
                info!("Server entered Running phase - initializing memcached client");
                // Use the provided runtime handle to spawn the initialization task
                handle.spawn(async {
                    match get_memcached_client().await.version().await {
                        Ok(version) => info!("Memcached client initialized successfully - version: {}", version),
                        Err(e) => error!("Failed to initialize memcached client: {}", e),
                    }
                });
                break;
            }
        }
    });

    server.bootstrap();
    ...

Without this I couldn't find any other nice way of initializing the memcached library nicely before the server starts receiving requests.

Describe alternatives you've considered

Adding another event just before the server is set to Running which passes this runtime handle, i.e. ServerStarted

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions