You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: command.rs
    path of file: ./repos/sozu/bin/src/ctl
    
    the code of the file until where you have to start completion: use std::time::Duration;

use sozu_command_lib::{
    logging::setup_logging_with_config,
    proto::command::{
        request::RequestType, response_content::ContentType, ListWorkers, QueryMetricsOptions,
        Request, Response, ResponseContent, ResponseStatus, UpgradeMain,
    },
};

use crate::ctl::{create_channel, CommandManager, CtlError};

impl CommandManager {
    fn write_request_on_channel(&mut self, request: Request) -> Result<(), CtlError> {
        self.channel
            .write_messag
    
    pub fn upgrade_main(&mut self) -> Result<(), CtlError> {
        debug!("updating main process");
        self.send_request(RequestType::UpgradeMain(UpgradeMain {}).into())?;

        info!("recreating a channel to reconnect with the new main process...");
        self.channel = create_channel(&self.config)?;

        info!("requesting the list of workers from the new main");
        let response =
            self.send_request_get_response(RequestType::ListWorkers(ListWorkers {}).into(), true)?;

        let workers = match response.content {
            Some(ResponseContent {
                content_type: Some(ContentType::Workers(worker_infos)),
            }) => worker_infos,
            _ => return Err(CtlError::WrongResponse(response)),
        };

        info!("About to upgrade these workers: {:?}", workers);

        let mut upgrade_jobs = Vec::new();

        for worker in workers.vec {
            info!("trying to upgrade worker {}", worker.id);
            let config = self.config.clone();

            upgrade_jobs.push(std::thread::spawn(move || {
                setup_logging_with_config(&config, &format!("UPGRADE-WRK-{}", worker.id));

                info!("creating channel to upgrade worker {}", worker.id);
                let channel = match create_channel(&config) {
                    Ok(channel) => channel,
                    Err(e) => {
                        error!(
                            "could not create channel to worker {}, this is critical: {}",
                            worker.id, e
                        );
                        return;
                    }
                };

                info!("created channel to upgrade worker {}", worker.id);

                let mut command_manager = CommandManager {
                    channel,
                    timeout: Duration::from_secs(60), // overriden by upgrade_timeout anyway
                    config,
                    json: false,
                };

                match command_manager.upgrade_worker(worker.id) {
                    Ok(()) => info!("successfully upgraded worker {}", worker.id),
                    Err(e) => error!("error upgrading worker {}: {}", worker.id, e),
                }
            }));
        }

        for job in upgrade_jobs {
            if let Err(e) = job.join() {
                error!("an upgrading job panicked: {:?}", e)
            }
        }

        info!("Finished upgrading");

        Ok(())
    }