### **Практическое задание: задачи с таймаутом**

Создайте метод TaskPool::create, которая будет отправлять задачу в канал, но если не получается отправить задачу в канал в течение 100 миллисекунд, возвращается None
```rust
use std::time::{Duration, Instant};

use tokio::{
    sync::mpsc::{Receiver, Sender, channel, error::SendError},
    time::timeout,
};

struct TaskPool<T> {
    tasks: Receiver<T>,
    sender: Sender<T>,
}

impl<T> TaskPool<T> {
    fn new(queue_size: usize) -> Self {
        let (sender, tasks) = channel::<T>(queue_size);
        Self { tasks, sender }
    }

    async fn create(&self, task: T) -> Option<Result<(), SendError<T>>> {
		// Напишите свое решение здесь
    }

    async fn pull_task(&mut self) -> Option<T> {
        self.tasks.recv().await
    }
}

#[tokio::main]
async fn main() {
    let mut tasks = TaskPool::new(2);

    assert_eq!(tasks.create(()).await, Some(Ok(())));
    assert_eq!(tasks.create(()).await, Some(Ok(())));

    let start = Instant::now();
    assert_eq!(tasks.create(()).await, None);
    let end = start.elapsed();

    assert!(end > Duration::from_millis(90));
    assert!(end < Duration::from_millis(110));

    assert_eq!(tasks.pull_task().await, Some(()));
    assert_eq!(tasks.create(()).await, Some(Ok(())));
}
```
### Подсказки

используйте tokio::time::timeout для таймаута
tokio::time::timeout принимает фьючерс для которого нужен таймаут
используйте .send() для отправки значение
обратите внимание, что .send() возвращает фьючерс

Проверьте свой код по чек-листу:
используется tokio::time::timeout
используются асинхронные каналы
все тесты проходят
### **Решение**
```rust
async fn create(&self, task: T) -> Option<Result<(), SendError<T>>> {
    let sender = self.sender.send(task);
    timeout(Duration::from_millis(100), sender).await.ok()
}
```

Вы знаете про существование таких синхронизационных примитивов в стандартной библиотеке, как Mutex, RwLock, каналы. И в тоже происходит ожидание. Но они блокируют поток, поэтому в tokio есть альтернативы с идентичным интерфейсом, но асинхронным:

У асинхронных мьютекса и RwLock есть преимущество: если фьючерс ожидает лока асинхронного мьютекса, токио будет обратно переключаться на другие фьючерсы. В то время, как синхронные версии будут держать поток и не давать другим фьючерсам исполняться. Для синхронных версий это создает проблему: если MutexGuard пересек границу .await, где, к примеру, ожидается ответ в течение 30 секунд, то другой фьючерс, ожидающий лока мьютекса, будет держать целый поток токио в течение всего этого времени, что приведет к потере производительности. А если рантайм токио будет однопоточным, то программа зависнет навсегда.
после вызова await залочен, что приводит к ожиданию анлока от других 