Здравствуйте!
Натолкнулся на первую серьезную проблему с заимствованием. Задача - нужно, чтобы веб-сервер обработал один запрос и завершился. Код такой
let addr: SocketAddr = ([127, 0, 0, 1], 3000).into();
let (sender, receiver) = futures::sync::oneshot::channel::<()>();
let proc = || {
let res = service_fn_ok(got_google_response);
sender.send(());
res
};
let server = Server::bind(&addr)
.serve(proc)
.with_graceful_shutdown(receiver)
.map_err(|e| eprintln!("server error: {}", e));
Rust компилировать отказывается т.к. serve требует Fn, но proc имеет тип FnOnce из-за того, что метод send принимает объект sender во владение.
Сделать канал не oneshot тоже не выходит, т.к. with_graceful_shutdown требует именно его.
Как обойти данную проблему? Есть какой-то подход?
Спасибо.
let (sender, receiver) = futures::sync::oneshot::channel::<()>();
let sender = RefCell::new(Some(sender));
let proc = || {
let res = service_fn_ok(got_google_response);
sender.borrow_mut().take().map(|s| s.send(()));
res
};
Получилось! Откомпилировалось, по крайней мере. Вот окончательный вариант.
let addr: SocketAddr = ([127, 0, 0, 1], 3000).into();
let (sender, receiver) = futures::sync::oneshot::channel::<()>();
let sender = RefCell::new(Some(sender));
let proc = move || {
let res = service_fn_ok(got_google_response);
sender.borrow_mut().take().unwrap().send(());
res
};
Нельзя переместить заимствованные данные. Option остается заимствованным, но при этом позволяет переместить то, что лежит у него внутри с помощью take().
Т.е., мой вариант кода упадёт при повторном вызове proc, т.к. в Option уже будет не Some, а None? Другими словами, здесь Option используется как контейнер для транспортировки значения?