Есть программа на языке RUST. Надо изменить ее чтобы: 1) если какой-либо сервер недоступен, то при распределении задач - на этот сервер не посылаются задачи на выполнение, и задание посылается на другой работающий сервер. При этом в консоли сервера пишется "Задание id="n" передано от сервера X к серверу Y. 2) На серверах worker, когда получается задание пишется информация в консоль: "Получено задание номер и информация по пакету: здесь указывается информация по соединению с сервером - есть сертификат или нет, протокол http или https, версия протокола http - 1 или 2  . 3) В некоторых местах программы, где требуется нужно добавить комментарии на русском языке. Текст файлов программы:  ///+++ ./Cargo.toml
[package]
name = "servhttps"
version = "0.1.0"
edition = "2021"

[dependencies]
tokio = { version = "1", features = ["full"] }
hyper = { version = "0.14", features = ["server", "client", "http1", "tcp"] }
hyper-tls = "0.5"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rand = "0.8"
chrono = "0.4"
rustls-pemfile = "1.0"
webpki-roots = "0.22"
rustls = {version = "0.21", features = ["dangerous_configuration"]}
hyper-rustls = { version = "0.24", features = ["http1"] }

[[bin]]
name = "main_server"
path = "src/main.rs"

[[bin]]
name = "worker"
path = "src/worker.rs"


///+++ ./src/main.rs
use hyper::{Body, Client, Request};
use hyper_rustls::HttpsConnectorBuilder;
use rand::Rng;
use std::fs::OpenOptions;
use std::io::Write;
use tokio::sync::{mpsc, Mutex};
use std::time::Instant;
use rustls::{Certificate, ServerName};
use std::sync::Arc;
use std::time::SystemTime;

mod models;
use models::{Task, TaskResult};

// Максимальное количество серверов worker (до 10)
const MAX_SERVER_COUNT: usize = 10;

#[tokio::main]
async fn main() {
    // Получаем количество задач из аргумента командной строки
    let args: Vec<String> = std::env::args().collect();
    if args.len() < 2 {
        eprintln!("Использование: main_server <количество_задач>");
        return;
    }

    let task_count: u64 = match args[1].parse() {
        Ok(n) => n,
        Err(_) => {
            eprintln!("Ошибка: Аргумент должен быть целым числом");
            return;
        }
    };

    // Создаем TLS-конфиг без проверки сертификатов
    let tls_config = rustls::ClientConfig::builder()
        .with_safe_defaults()
        .with_custom_certificate_verifier(Arc::new(InsecureVerifier))
        .with_no_client_auth();

    let https = HttpsConnectorBuilder::new()
        .with_tls_config(tls_config)
        .https_only()
        .enable_http1()
        .build();

    let client = Client::builder().build::<_, hyper::Body>(https);

    // Генерируем задания
    let mut tasks = Vec::new();
    let mut rng = rand::thread_rng();
    for id in 0..task_count {
        // Распределяем задачи равномерно между серверами
        let server_index = (id as usize % MAX_SERVER_COUNT) + 1; // от 1 до 10
        let task = Task {
            id,
            number1: rng.gen_range(1..100),
            number2: rng.gen_range(1..100),
            server_index,
        };
        tasks.push(task);
    }

    // Список активных серверов (по умолчанию все доступны)
    let active_servers = Arc::new(Mutex::new(vec![true; MAX_SERVER_COUNT]));

    // Канал для получения результатов
    let (tx, mut rx) = mpsc::channel::<TaskResult>(100);

    // Отправляем задачи
    for task in tasks {
        let client = client.clone();
        let tx = tx.clone();
        let active_servers = Arc::clone(&active_servers);
        let server_url = format!("https://localhost:{}", 8000 + task.server_index); // порт = 8000 + индекс

        tokio::spawn(async move {
            let server_idx = task.server_index - 1; // Индекс для массива (начинается с 0)

            // Проверяем, доступен ли сервер
            {
                let servers = active_servers.lock().await;
                if !servers[server_idx] {
                    println!("Сервер {} не доступен. Задача {} пропущена.", task.server_index, task.id);
                    return;
                }
            }

            let start_time = Instant::now();

            // Пытаемся отправить задачу
            match send_task_to_server(&client, &task, &server_url).await {
                Ok(result) => {
                    let execution_time = start_time.elapsed().as_millis() as i64;
                    let result_with_time = TaskResult {
                        id: result.id,
                        server_index: result.server_index,
                        number1: result.number1,
                        number2: result.number2,
                        result: result.result,
                        execution_time,
                    };
                    tx.send(result_with_time).await.unwrap();
                },
                Err(e) => {
                    // Сервер недоступен
                    {
                        let mut servers = active_servers.lock().await;
                        servers[server_idx] = false; // Отмечаем как недоступный
                    }
                    println!("Сервер {} недоступен: {}", task.server_index, e);
                }
            }
        });
    }

    drop(tx); // Закрываем канал отправки

    // Обрабатываем результаты
    while let Some(result) = rx.recv().await {
        log_result(&result);
        println!("Получен результат: {:?}", result);
    }
}

/// Функция для логирования результатов в файл
fn log_result(result: &TaskResult) {
    let mut file = OpenOptions::new()
        .append(true)
        .create(true)
        .open("results.log")
        .expect("Не удалось открыть файл для логирования");

    let log_entry = format!(
        "Task ID: {}, Server: {}, Number1: {}, Number2: {}, Result: {}, Execution Time: {}ms\n",
        result.id, result.server_index, result.number1, result.number2, result.result, result.execution_time
    );
    file.write_all(log_entry.as_bytes()).expect("Не удалось записать в файл");
}

/// Функция для отправки задания на рабочий сервер
async fn send_task_to_server(
    client: &Client<hyper_rustls::HttpsConnector<hyper::client::HttpConnector>>,
    task: &Task,
    server_url: &str,
) -> Result<TaskResult, hyper::Error> {
    let task_json = serde_json::to_string(task).unwrap();
    let req = Request::builder()
        .method("POST")
        .uri(format!("{}/task", server_url))
        .header("Content-Type", "application/json")
        .body(Body::from(task_json))
        .unwrap();

    let res = client.request(req).await?;
    let body_bytes = hyper::body::to_bytes(res.into_body()).await?;
    let result: TaskResult = serde_json::from_slice(&body_bytes).unwrap();
    Ok(result)
}

// Небезопасный верификатор сертификатов (для тестирования)
struct InsecureVerifier;

impl rustls::client::ServerCertVerifier for InsecureVerifier {
    fn verify_server_cert(
        &self,
        _end_entity: &Certificate,
        _intermediates: &[Certificate],
        _server_name: &ServerName,
        _scts: &mut dyn Iterator<Item = &[u8]>,
        _ocsp_response: &[u8],
        _now: SystemTime,
    ) -> Result<rustls::client::ServerCertVerified, rustls::Error> {
        Ok(rustls::client::ServerCertVerified::assertion())
    }
}


///+++ ./src/models.rs
use serde::{Deserialize, Serialize};

// Структура задания
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Task {
    pub id: u64,           // Уникальный номер задания
    pub number1: i32,      // Первое число
    pub number2: i32,      // Второе число
    pub server_index: usize, // Индекс сервера, который будет выполнять задание
}

// Структура результата
#[derive(Serialize, Deserialize, Debug)]
pub struct TaskResult {
    pub id: u64,           // Уникальный номер задания
    pub server_index: usize, // Индекс сервера
    pub number1: i32,      // Первое число
    pub number2: i32,      // Второе число
    pub result: i32,       // Результат (произведение)
    pub execution_time: i64, // Время выполнения (в миллисекундах)
}

///+++ ./src/worker.rs
use hyper::{Body, Request, Response, Server, service::{make_service_fn, service_fn}};
use serde_json;
use std::convert::Infallible;
use std::net::SocketAddr;
use hyper_rustls::TlsAcceptor;
use rustls::{Certificate, PrivateKey};
use rustls::server::ServerConfig;
use rustls_pemfile::{certs, pkcs8_private_keys};
use std::fs::File;
use std::io::BufReader;
use hyper::server::conn::AddrIncoming;

mod models;
use models::{Task, TaskResult};

// Функция для загрузки SSL/TLS-сертификатов
fn load_rustls_config() -> rustls::ServerConfig {
    let cert_file = &mut BufReader::new(File::open("server.crt").unwrap());
    let key_file = &mut BufReader::new(File::open("server.key").unwrap());

    let cert_chain: Vec<Certificate> = certs(cert_file)
        .unwrap()
        .into_iter()
        .map(Certificate)
        .collect();

    let mut keys: Vec<PrivateKey> = pkcs8_private_keys(key_file)
        .unwrap()
        .into_iter()
        .map(PrivateKey)
        .collect();

    let config = ServerConfig::builder()
        .with_safe_defaults()
        .with_no_client_auth()
        .with_single_cert(cert_chain, keys.remove(0))
        .unwrap();

    config
}

// Обработчик входящих заданий
async fn handle_task(req: Request<Body>) -> Result<Response<Body>, Infallible> {
    let body_bytes = hyper::body::to_bytes(req.into_body()).await.unwrap();
    let task: Task = serde_json::from_slice(&body_bytes).unwrap();

    // Выполняем задание (перемножаем числа)
    let result = task.number1 * task.number2;

    // Формируем результат
    let task_result = TaskResult {
        id: task.id,
        server_index: task.server_index,
        number1: task.number1,
        number2: task.number2,
        result,
        execution_time: 0, // Время выполнения будет добавлено на Сервер0
    };

    // Возвращаем результат в формате JSON
    let result_json = serde_json::to_string(&task_result).unwrap();
    Ok(Response::new(Body::from(result_json)))
}

#[tokio::main]
async fn main() {
    // Получаем номер сервера из аргумента
    let server_index = std::env::args().nth(1).unwrap_or("1".to_string()).parse::<usize>().unwrap();
    let port = 8000 + server_index;

    let addr = SocketAddr::from(([127, 0, 0, 1], port as u16));

    // Настраиваем TLS
    let tls_config = load_rustls_config(); // Убираем Arc здесь
    let incoming = AddrIncoming::bind(&addr).unwrap();
    let acceptor = TlsAcceptor::builder()
        .with_tls_config(tls_config) // Передаем ServerConfig напрямую
        .with_all_versions_alpn()
        .with_incoming(incoming);

    let make_svc = make_service_fn(|_conn| async {
        Ok::<_, Infallible>(service_fn(handle_task))
    });

    let server = Server::builder(acceptor).serve(make_svc);
    println!("Рабочий сервер {} запущен на порту {} (HTTPS)", server_index, port);

    if let Err(e) = server.await {
        eprintln!("Ошибка сервера: {}", e);
    }
}