упр.11 задача 1

Предадени решения

Краен срок:
24.12.2025 23:59
Точки:
4

Срокът за предаване на решения е отминал

// Include the solution source in the same file, so we
// don't have to worry about item visibility.
// Please don't use `include!` in real code, this is a hack
// around the checking system.
include!{ "../src/lib.rs" }
#[test]
fn test_basic() {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_time()
.build()
.unwrap();
rt.block_on(async {
let tasks = vec![
(1, Duration::from_millis(300)),
(2, Duration::from_millis(1200)),
(3, Duration::from_millis(500)),
(4, Duration::from_millis(900)),
(5, Duration::from_millis(200)),
];
let mut output = Vec::new();
manage_tasks(&tasks, &mut output).await;
let output_str = String::from_utf8(output).unwrap();
let output_lines = output_str.lines().collect::<std::collections::BTreeSet<_>>();
assert_eq!(
output_lines,
std::collections::BTreeSet::from_iter(
[
"Task 5 finished in 200 ms",
"Task 1 finished in 300 ms",
"Task 3 finished in 500 ms",
"Task 4 timed out",
"Task 2 timed out",
"Successful tasks: 3",
"Failed tasks: 2",
]
.into_iter()
),
);
});
}

Тази задача изисква да използвате външната библиотека tokio.
Направете си нов проект с cargo new или cargo init.
Извикайте cargo add tokio --features=full. Алтернативно, можете да добавите на ръка следното в Cargo.toml файла на вашия проект.

[dependencies]
tokio = { version = "1.48.0", features = ["full"] }

След това компилирайте с cargo build.
Можете да използвате неща от библиотеката с use tokio::...;
Има документация на https://docs.rs/tokio/latest/tokio/.

Системата ще позволява използването на библиотеките tokio и futures.


Task Scheduler

Ще реализирате опростен асинхронен мениджър на задачи, който стартира задачи с различна продължителност и събира резултатите им.

Част 1 — Асинхронна задача

Имплементирайте асинхронна функция:

use std::time::Duration;

async fn run_task(id: usize, duration: Duration) -> Result<String, String>

Функцията трябва:

  1. Асинхронно да изчака време duration.

  2. Ако duration > 800 ms, да върне грешка:

   Task {id} timed out
  1. В противен случай да върне:
   Task {id} finished in {duration_ms} ms

Част 2 — Мениджър на задачи

Имплементирайте функция

use std::io::Write;

async fn manage_tasks(task_infos: &[(usize, Duration)], w: &mut dyn Write);
  1. Функцията получава списък от задачи във формат (id, duration).

  2. Стартирайте всички задачи паралелно, например използвайки tokio::spawn.

  3. Не await-вайте задачите веднага след стартирането им.

  4. След като всички задачи са стартирани:

    • изчакайте всяка от тях;
    • ако задачата е успешна, отпечатайте в w резултата (използвайте writeln!(w, ...));
    • ако е неуспешна, отпечатайте в w грешката.
  5. Накрая отпечатайте в w обобщение:

   Successful tasks: X
   Failed tasks: Y

Примерен изход

Редът на извеждане не е фиксиран.

Task 5 finished in 200 ms
Task 1 finished in 300 ms
Task 3 finished in 500 ms
Task 4 timed out
Task 2 timed out
Successful tasks: 3
Failed tasks: 2

Обобщена информация от лекцията

Задължително прочетете (или си припомнете): Указания за предаване на домашни

Погрижете се решението ви да се компилира с базовия тест:

// Include the solution source in the same file, so we
// don't have to worry about item visibility.
// Please don't use `include!` in real code, this is a hack
// around the checking system.
include!{ "../src/lib.rs" }
#[test]
fn test_basic() {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_time()
.build()
.unwrap();
rt.block_on(async {
let tasks = vec![
(1, Duration::from_millis(300)),
(2, Duration::from_millis(1200)),
(3, Duration::from_millis(500)),
(4, Duration::from_millis(900)),
(5, Duration::from_millis(200)),
];
let mut output = Vec::new();
manage_tasks(&tasks, &mut output).await;
let output_str = String::from_utf8(output).unwrap();
let output_lines = output_str.lines().collect::<std::collections::BTreeSet<_>>();
assert_eq!(
output_lines,
std::collections::BTreeSet::from_iter(
[
"Task 5 finished in 200 ms",
"Task 1 finished in 300 ms",
"Task 3 finished in 500 ms",
"Task 4 timed out",
"Task 2 timed out",
"Successful tasks: 3",
"Failed tasks: 2",
]
.into_iter()
),
);
});
}