{"id":377712,"date":"2024-06-01T15:01:22","date_gmt":"2024-06-01T15:01:22","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=377712"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-06-01T15:01:22","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=377712","title":{"rendered":"<span>\u0422\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u043f\u043e Tokio. 2\/2<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/nn\/kv\/or\/nnkvorz4qbcnf9byn5v1gfedoas.png\" data-src=\"https:\/\/habrastorage.org\/webt\/nn\/kv\/or\/nnkvorz4qbcnf9byn5v1gfedoas.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>Hello world!<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0432\u0442\u043e\u0440\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0430 \u043f\u043e <a href=\"https:\/\/tokio.rs\/\">Tokio<\/a>.<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/habr.com\/ru\/companies\/timeweb\/articles\/815811\/\">\u041f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/a><\/li>\n<li><a href=\"https:\/\/my-js.org\/docs\/guide\/tokio\/\">\u0422\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u0446\u0435\u043b\u0438\u043a\u043e\u043c<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<p>Tokio \u2014 \u044d\u0442\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0441\u0440\u0435\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (runtime) \u043a\u043e\u0434\u0430 Rust. \u041e\u043d\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043b\u044e\u0431\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2 id=\"soderzhanie\">\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<ul>\n<li>\n<p><a href=\"#%D0%BA%D0%B0%D0%B4%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\">\u041a\u0430\u0434\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/a><\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"#%D0%B1%D1%83%D1%84%D0%B5%D1%80%D0%B8%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5-%D1%87%D1%82%D0%B5%D0%BD%D0%B8%D0%B5\">\u0411\u0443\u0444\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435<\/a><\/li>\n<li><a href=\"#%D1%80%D0%B0%D0%B7%D0%B1%D0%BE%D1%80\">\u0420\u0430\u0437\u0431\u043e\u0440<\/a><\/li>\n<li><a href=\"#%D0%B1%D1%83%D1%84%D0%B5%D1%80%D0%B8%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%B0%D1%8F-%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C\">\u0411\u0443\u0444\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c<\/a><\/li>\n<\/ul>\n<p>  <\/li>\n<li>\n<p><a href=\"#%D0%BF%D0%BE%D0%B4%D1%80%D0%BE%D0%B1%D0%BD%D0%BE-%D0%BE%D0%B1-%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D0%B8\">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0431 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u0438<\/a><\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"#%D1%84%D1%8C%D1%8E%D1%87%D0%B5%D1%80%D1%8B-futures\">\u0424\u044c\u044e\u0447\u0435\u0440\u044b (futures)<\/a><\/li>\n<li><a href=\"#%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D0%BD%D0%B8%D1%82%D0%B5%D0%BB%D0%B8-executors\">\u0418\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0438 (executors)<\/a><\/li>\n<li><a href=\"#%D0%B1%D1%83%D0%B4%D0%B8%D0%BB%D1%8C%D0%BD%D0%B8%D0%BA%D0%B8-wakers\">\u0411\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0438 (wakers)<\/a><\/li>\n<li><a href=\"#%D1%80%D0%B5%D0%B7%D1%8E%D0%BC%D0%B5\">\u0420\u0435\u0437\u044e\u043c\u0435<\/a><\/li>\n<li><a href=\"#%D1%80%D0%B5%D0%BC%D0%B0%D1%80%D0%BA%D0%B8\">\u0420\u0435\u043c\u0430\u0440\u043a\u0438<\/a><\/li>\n<\/ul>\n<p>  <\/li>\n<li>\n<p><a href=\"#%D0%B2%D1%8B%D0%B1%D0%BE%D1%80\">\u0412\u044b\u0431\u043e\u0440<\/a><\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"#tokioselect\"><code>tokio::select!<\/code><\/a><\/li>\n<li><a href=\"#%D1%81%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8%D1%81\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/a><\/li>\n<li><a href=\"#%D0%B2%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D0%B5%D0%BC%D0%BE%D0%B5-%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5\">\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/a><\/li>\n<li><a href=\"#%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B8\">\u041e\u0448\u0438\u0431\u043a\u0438<\/a><\/li>\n<li><a href=\"#%D1%81%D0%BE%D0%BF%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81-%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%BE%D0%BC\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c<\/a><\/li>\n<li><a href=\"#%D0%B7%D0%B0%D0%B8%D0%BC%D1%81%D1%82%D0%B2%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\">\u0417\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435<\/a><\/li>\n<li><a href=\"#%D1%86%D0%B8%D0%BA%D0%BB%D1%8B\">\u0426\u0438\u043a\u043b\u044b<\/a><\/li>\n<li><a href=\"#%D0%BF%D0%B0%D1%80%D0%B0%D0%BB%D0%BB%D0%B5%D0%BB%D0%B8%D0%B7%D0%BC-%D0%BF%D0%BE-%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B0%D0%BC\">\u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c \u043f\u043e \u0437\u0430\u0434\u0430\u0447\u0430\u043c<\/a><\/li>\n<\/ul>\n<p>  <\/li>\n<li>\n<p><a href=\"#%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%B8\">\u041f\u043e\u0442\u043e\u043a\u0438<\/a><\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"#%D0%BF%D0%B5%D1%80%D0%B5%D0%B1%D0%BE%D1%80\">\u041f\u0435\u0440\u0435\u0431\u043e\u0440<\/a><\/li>\n<li><a href=\"#%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B5%D1%80%D1%8B\">\u0410\u0434\u0430\u043f\u0442\u0435\u0440\u044b<\/a><\/li>\n<li><a href=\"#%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-stream\"><code>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f Stream<\/code><\/a><\/li>\n<\/ul>\n<p>  <\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/harryheman\/mini-redis\">Mini Redis \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435<\/a><\/p>\n<p>  <\/li>\n<li>\n<p><a href=\"https:\/\/my-js.org\/docs\/guide\/rust\/\">\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e Rust<\/a><\/p>\n<p>  <\/li>\n<li>\n<p><a href=\"https:\/\/my-js.org\/docs\/guide\/rust-cookbook\/\">\u041a\u043d\u0438\u0433\u0430 \u0440\u0435\u0446\u0435\u043f\u0442\u043e\u0432 Rust<\/a><\/p>\n<p>  <\/li>\n<\/ul>\n<p>  <\/p>\n<h1 id=\"kadrirovanie\">\u041a\u0430\u0434\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h1>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0443\u0437\u043d\u0430\u043b\u0438 \u043e \u0432\u0432\u043e\u0434\u0435-\u0432\u044b\u0432\u043e\u0434\u0435, \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043a\u0430\u0434\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (framing layer) Mini-Redis. \u041a\u0430\u0434\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 (framing) \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u0431\u0430\u0439\u0442\u043e\u0432 \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0433\u043e \u0432 \u043f\u043e\u0442\u043e\u043a \u043a\u0430\u0434\u0440\u043e\u0432. \u041a\u0430\u0434\u0440 \u2014 \u044d\u0442\u043e \u0435\u0434\u0438\u043d\u0438\u0446\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u0430\u044f \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0443\u0437\u043b\u0430\u043c\u0438 (peers). \u041a\u0430\u0434\u0440 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 Redis \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use bytes::Bytes;  enum Frame {     Simple(String),     Error(String),     Integer(u64),     Bulk(Bytes),     Null,     Array(Vec&lt;Frame>), }<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>, \u0447\u0442\u043e \u043a\u0430\u0434\u0440 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0435\u0437 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0438. \u0410\u043d\u0430\u043b\u0438\u0437 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f HTTP \u043a\u0430\u0434\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">enum HttpFrame {     RequestHead {         method: Method,         uri: Uri,         version: Version,         headers: HeaderMap,     },     ResponseHead {         status: StatusCode,         version: Version,         headers: HeaderMap,     },     BodyChunk {         chunk: Bytes,     }, }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>Connection<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 <code>TcpStream<\/code> \u0438 \u0447\u0438\u0442\u0430\u0435\u0442\/\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>mini_redis::Frame<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::net::TcpStream; use mini_redis::{Frame, Result};  struct Connection {     stream: TcpStream,     \/\/ ... }  impl Connection {     \/\/\/ \u0427\u0438\u0442\u0430\u0435\u0442 \u043a\u0430\u0434\u0440 \u0438\u0437 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f.     \/\/\/     \/\/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 `None` \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 EOF     pub async fn read_frame(&amp;mut self)         -> Result&lt;Option&lt;Frame>>     {         \/\/ TODO     }      \/\/\/ \u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u0434\u0440 \u0432 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435     pub async fn write_frame(&amp;mut self, frame: &amp;Frame)         -> Result&lt;()>     {         \/\/ TODO     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0435 Redis \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/redis.io\/topics\/protocol\">\u0437\u0434\u0435\u0441\u044c<\/a>. \u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 <code>Connection<\/code> \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/tokio-rs\/mini-redis\/blob\/tutorial\/src\/connection.rs\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<h2 id=\"buferizovannoe-chtenie\">\u0411\u0443\u0444\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>read_frame<\/code> \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0433\u043e \u043a\u0430\u0434\u0440\u0430 \u043f\u0435\u0440\u0435\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u043e\u043c. \u041e\u0434\u0438\u043d \u0432\u044b\u0437\u043e\u0432 <code>TcpStream::read()<\/code> \u043c\u043e\u0436\u0435\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445. \u041e\u043d \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0446\u0435\u043b\u044b\u0439 \u043a\u0430\u0434\u0440, \u0447\u0430\u0441\u0442\u044c \u043a\u0430\u0434\u0440\u0430 \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u0434\u0440\u043e\u0432. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0434\u0440, \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0444\u0435\u0440\u0438\u0437\u0443\u044e\u0442\u0441\u044f, \u0438 \u0438\u0437 \u0441\u043e\u043a\u0435\u0442\u0430 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u0434\u0440\u043e\u0432, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u0439, \u0430 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u0431\u0443\u0444\u0435\u0440 \u0434\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 <code>read_frame()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">touch src\/connection.rs<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0432 <code>Connection<\/code> \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u0435 \u0434\u043b\u044f \u0431\u0443\u0444\u0435\u0440\u0430 \u0447\u0442\u0435\u043d\u0438\u044f (read buffer). \u0414\u0430\u043d\u043d\u044b\u0435 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u0441\u043e\u043a\u0435\u0442\u0430 \u0432 \u0431\u0443\u0444\u0435\u0440 \u0447\u0442\u0435\u043d\u0438\u044f. \u041f\u0440\u0438 \u0440\u0430\u0437\u0431\u043e\u0440\u0435 \u043a\u0430\u0434\u0440\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u0434\u0430\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u0437 \u0431\u0443\u0444\u0435\u0440\u0430.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/docs.rs\/bytes\/1\/bytes\/struct.BytesMut.html\">BytesMut<\/a> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0438\u043f\u0430 \u0431\u0443\u0444\u0435\u0440\u0430. \u042d\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f <a href=\"https:\/\/docs.rs\/bytes\/1\/bytes\/struct.Bytes.html\">Bytes<\/a>.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use bytes::BytesMut; use tokio::net::TcpStream;  pub struct Connection {     stream: TcpStream,     buffer: BytesMut, }  impl Connection {     pub fn new(stream: TcpStream) -> Connection {         Connection {             stream,             \/\/ \u0412\u044b\u0434\u0435\u043b\u044f\u0435\u043c \u0431\u0443\u0444\u0435\u0440 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c 4 \u041a\u0411             buffer: BytesMut::with_capacity(4096),         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <code>read_frame<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::io::AsyncReadExt; use bytes::Buf; use mini_redis::Result;  pub async fn read_frame(&amp;mut self)     -> Result&lt;Option&lt;Frame>> {     loop {         \/\/ \u041f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0434\u0440 \u0438\u0437 \u0431\u0443\u0444\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.         \/\/ \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u0434\u0440         if let Some(frame) = self.parse_frame()? {             return Ok(Some(frame));         }          \/\/ \u0412 \u0431\u0443\u0444\u0435\u0440\u0435 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043a\u0430\u0434\u0440\u0430.         \/\/ \u041f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043e\u043a\u0435\u0442\u0430.         \/\/         \/\/ \u041f\u0440\u0438 \u0443\u0441\u043f\u0435\u0445\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0430\u0439\u0442\u043e\u0432.         \/\/ `0` - \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \"\u043a\u043e\u043d\u0446\u0430 \u043f\u043e\u0442\u043e\u043a\u0430\"         if 0 == self.stream.read_buf(&amp;mut self.buffer).await? {             \/\/ \u0414\u0440\u0443\u0433\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430 \u0437\u0430\u043a\u0440\u044b\u043b\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435. \u0414\u043b\u044f \u0447\u0438\u0441\u0442\u043e\u0433\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f             \/\/ \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 \u0447\u0442\u0435\u043d\u0438\u044f \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0445.             \/\/ \u0415\u0441\u043b\u0438 \u0442\u0430\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u043c\u0435\u044e\u0442\u0441\u044f, \u0437\u043d\u0430\u0447\u0438\u0442 \u0434\u0440\u0443\u0433\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430             \/\/ \u0437\u0430\u043a\u0440\u044b\u043b\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043a\u0430\u0434\u0440\u0430             if self.buffer.is_empty() {                 return Ok(None);             } else {                 return Err(\"Connection reset by peer\".into());             }         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434. \u041c\u0435\u0442\u043e\u0434 <code>read_frame<\/code> \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0446\u0438\u043a\u043b\u0435. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>self.parse_frame()<\/code>. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0434\u0440 Redis \u0438\u0437 <code>self.buffer<\/code>. \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u043a\u0430\u0434\u0440 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043c\u044b \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043e\u043a\u0435\u0442\u0430. \u041f\u043e\u0441\u043b\u0435 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043d\u043e\u0432\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>parse_frame()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u0438\u0437 \u043f\u043e\u0442\u043e\u043a\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>0<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442 \u0443\u0437\u043b\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442. \u0415\u0441\u043b\u0438 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 \u0447\u0442\u0435\u043d\u0438\u044f \u0432\u0441\u0435 \u0435\u0449\u0435 \u0435\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0431\u044b\u043b \u043f\u043e\u043b\u0443\u0447\u0435\u043d \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0434\u0440 \u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u043e \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e. \u042d\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f <code>Err<\/code>.<\/p>\n<p>  <\/p>\n<p><strong>\u0422\u0438\u043f\u0430\u0436 <code>Buf<\/code><\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u0438\u0437 \u043f\u043e\u0442\u043e\u043a\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>read_buf()<\/code>. \u042d\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0447\u0442\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0435\u0435 <a href=\"https:\/\/docs.rs\/bytes\/1\/bytes\/trait.BufMut.html\">BufMut<\/a> \u0438\u0437 \u043a\u0440\u0435\u0439\u0442\u0430 <a href=\"https:\/\/docs.rs\/bytes\/\">bytes<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043f\u043e\u0434\u0443\u043c\u0430\u0439\u0442\u0435, \u043a\u0430\u043a \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0442 \u0436\u0435 \u0446\u0438\u043a\u043b \u0447\u0442\u0435\u043d\u0438\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>read()<\/code>. \u0412\u043c\u0435\u0441\u0442\u043e <code>BytesMut<\/code> \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Vec&lt;u8><\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::net::TcpStream;  pub struct Connection {     stream: TcpStream,     buffer: Vec&lt;u8>,     cursor: usize, }  impl Connection {     pub fn new(stream: TcpStream) -> Connection {         Connection {             stream,             buffer: vec![0; 4096],             cursor: 0,         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>read_frame<\/code> \u0432 <code>Connection<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use mini_redis::{Frame, Result};  pub async fn read_frame(&amp;mut self)     -> Result&lt;Option&lt;Frame>> {     loop {         if let Some(frame) = self.parse_frame()? {             return Ok(Some(frame));         }          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u0430 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435         if self.buffer.len() == self.cursor {             \/\/ \u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u0443\u0444\u0435\u0440\u0430             self.buffer.resize(self.cursor * 2, 0);         }          \/\/ \u0427\u0438\u0442\u0430\u0435\u043c \u0432 \u0431\u0443\u0444\u0435\u0440, \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0445 \u0431\u0430\u0439\u0442         let n = self.stream.read(&amp;mut self.buffer[self.cursor..]).await?;          if 0 == n {             if self.cursor == 0 {                 return Ok(None);             } else {                 return Err(\"Connection reset by peer\".into());             }         } else {             \/\/ \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043a\u0443\u0440\u0441\u043e\u0440             self.cursor += n;         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0431\u0430\u0439\u0442\u043e\u0432\u044b\u043c\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u043c\u0438 \u0438 <code>read()<\/code>, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u043a\u0443\u0440\u0441\u043e\u0440, \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0439, \u043a\u0430\u043a\u043e\u0439 \u043e\u0431\u044a\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u044b\u043b \u043f\u043e\u043c\u0435\u0449\u0435\u043d \u0432 \u0431\u0443\u0444\u0435\u0440. \u041c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>read<\/code> \u043f\u0443\u0441\u0442\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0431\u0443\u0444\u0435\u0440\u0430. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043c\u044b \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0448\u0435\u043c \u0431\u0443\u0444\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u0415\u0441\u043b\u0438 \u0431\u0443\u0444\u0435\u0440 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u0435\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0447\u0442\u0435\u043d\u0438\u0435. \u0412 <code>parse_frame()<\/code> (\u043d\u0435 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u043f\u0440\u0438\u043c\u0435\u0440) \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435\u0441\u044f \u0432 <code>self.buffer[..self.cursor]<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0430\u0439\u0442\u043e\u0432 \u0441 \u043a\u0443\u0440\u0441\u043e\u0440\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u043c, \u043a\u0440\u0435\u0439\u0442 <code>bytes<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044e, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0443\u044e \u043c\u0430\u0441\u0441\u0438\u0432 \u0431\u0430\u0439\u0442\u043e\u0432 \u0438 \u043a\u0443\u0440\u0441\u043e\u0440. \u0422\u0438\u043f\u0430\u0436 <code>Buf<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0438\u043f\u0430\u043c\u0438, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435. \u0422\u0438\u043f\u0430\u0436 <code>BufMut<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0438\u043f\u0430\u043c\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435. \u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435 <code>T: BufMut<\/code> \u0432 <code>read_buf()<\/code> \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u043a\u0443\u0440\u0441\u043e\u0440 \u0431\u0443\u0444\u0435\u0440\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u0432 \u043d\u0430\u0448\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 <code>read_frame()<\/code> \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043a\u0443\u0440\u0441\u043e\u0440\u043e\u043c.<\/p>\n<p>  <\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <code>Vec&lt;u8><\/code> \u0431\u0443\u0444\u0435\u0440 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c. <code>vec![0; 4096]<\/code> \u0432\u044b\u0434\u0435\u043b\u044f\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c 4096 \u0431\u0430\u0439\u0442 \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043d\u043e\u043b\u044c \u0432 \u043a\u0430\u0436\u0434\u0443\u044e \u044f\u0447\u0435\u0439\u043a\u0443. \u041f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0431\u0443\u0444\u0435\u0440\u0430 \u043d\u043e\u0432\u0430\u044f \u0435\u043c\u043a\u043e\u0441\u0442\u044c \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043d\u0443\u043b\u044f\u043c\u0438. \u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u043c. \u041f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 <code>BytesMut<\/code> \u0438 <code>BufMut<\/code> \u0435\u043c\u043a\u043e\u0441\u0442\u044c \u043d\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u0410\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044f <code>BytesMut<\/code> \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0447\u0438\u0442\u0430\u0442\u044c \u043d\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u044d\u0442\u0430\u043f\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<h2 id=\"razbor\">\u0420\u0430\u0437\u0431\u043e\u0440<\/h2>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>parse_frame<\/code>. \u0420\u0430\u0437\u0431\u043e\u0440 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0434\u0432\u0430 \u044d\u0442\u0430\u043f\u0430:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0423\u0431\u0435\u0436\u0434\u0430\u0435\u043c\u0441\u044f, \u0447\u0442\u043e \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u0430\u0434\u0440, \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 \u043a\u0430\u0434\u0440\u0430.<\/li>\n<li>\u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u0430\u0434\u0440.<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u041a\u0440\u0435\u0439\u0442 mini-redis \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043e\u0431\u043e\u0438\u0445 \u044d\u0442\u0438\u0445 \u0448\u0430\u0433\u043e\u0432:<\/p>\n<p>  <\/p>\n<ol>\n<li><a href=\"https:\/\/docs.rs\/mini-redis\/0.4\/mini_redis\/frame\/enum.Frame.html#method.check\">Frame::check<\/a>.<\/li>\n<li><a href=\"https:\/\/docs.rs\/mini-redis\/0.4\/mini_redis\/frame\/enum.Frame.html#method.parse\">Frame::parse<\/a>.<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044e <code>Buf<\/code>. <code>Buf<\/code> \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 <code>Frame::check()<\/code>. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>check<\/code> \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440, \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u043a\u0443\u0440\u0441\u043e\u0440 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u043f\u0435\u0440\u0435\u0434. \u041a\u043e\u0433\u0434\u0430 <code>check()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f, \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u043a\u0443\u0440\u0441\u043e\u0440 \u0431\u0443\u0444\u0435\u0440\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u043a\u043e\u043d\u0435\u0446 \u043a\u0430\u0434\u0440\u0430.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u0438\u043f\u0430 <code>Buf<\/code> \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>std::io::Cursor&lt;&amp;[u8]><\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use mini_redis::{Frame, Result}; use mini_redis::frame::Error::Incomplete; use bytes::Buf; use std::io::Cursor;  fn parse_frame(&amp;mut self)     -> Result&lt;Option&lt;Frame>> {     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u0438\u043f `T: Buf`     let mut buf = Cursor::new(&amp;self.buffer[..]);      \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043b\u0438 \u0446\u0435\u043b\u044b\u0439 \u043a\u0430\u0434\u0440     match Frame::check(&amp;mut buf) {         Ok(_) => {             \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u043b\u0438\u043d\u0443 \u043a\u0430\u0434\u0440\u0430 \u0432 \u0431\u0430\u0439\u0442\u0430\u0445             let len = buf.position() as usize;              \/\/ \u0421\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u043a\u0443\u0440\u0441\u043e\u0440 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 `parse()`             buf.set_position(0);              \/\/ \u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u0430\u0434\u0440             let frame = Frame::parse(&amp;mut buf)?;              \/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u043a\u0430\u0434\u0440 \u0438\u0437 \u0431\u0443\u0444\u0435\u0440\u0430             self.buffer.advance(len);              \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043a\u0430\u0434\u0440             Ok(Some(frame))         }         \/\/ \u0412 \u0431\u0443\u0444\u0435\u0440\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u043c\u0430\u043b\u043e \u0434\u0430\u043d\u043d\u044b\u0445         Err(Incomplete) => Ok(None),         \/\/ \u0412\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430         Err(e) => Err(e.into()),     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>Frame::check<\/code> \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/tokio-rs\/mini-redis\/blob\/tutorial\/src\/frame.rs#L65-L103\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0412\u0430\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f API <code>Buf<\/code> \u0432 \u0441\u0442\u0438\u043b\u0435 &#171;\u0431\u0430\u0439\u0442\u043e\u0432\u043e\u0433\u043e \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u0430&#187; (byte iterator). \u0420\u0435\u0447\u044c \u0438\u0434\u0435\u0442 \u043e\u0431 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u043a\u0443\u0440\u0441\u043e\u0440\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0442\u0438\u043f \u043a\u0430\u0434\u0440\u0430 \u043f\u0440\u0438 \u0435\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0435, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u0439 \u0431\u0430\u0439\u0442. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u2014 <a href=\"https:\/\/docs.rs\/bytes\/1\/bytes\/buf\/trait.Buf.html#method.get_u8\">Buf::get_u8<\/a>. \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0431\u0430\u0439\u0442 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043a\u0443\u0440\u0441\u043e\u0440\u0430 \u0438 \u043a\u0443\u0440\u0441\u043e\u0440 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0435\u0434\u0438\u043d\u0438\u0446\u0443.<\/p>\n<p>  <\/p>\n<p>\u0422\u0438\u043f\u0430\u0436 <a href=\"https:\/\/docs.rs\/bytes\/1\/bytes\/buf\/trait.Buf.html\">Buf<\/a> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432.<\/p>\n<p>  <\/p>\n<h2 id=\"buferizovannaya-zapis\">\u0411\u0443\u0444\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c<\/h2>\n<p>  <\/p>\n<p>\u0414\u0440\u0443\u0433\u0430\u044f \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 API \u043a\u0430\u0434\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u2014 \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>write_frame(frame)<\/code>. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0432 \u0441\u043e\u043a\u0435\u0442 \u0432\u0435\u0441\u044c \u043a\u0430\u0434\u0440. \u0427\u0442\u043e\u0431\u044b \u0441\u0432\u0435\u0441\u0442\u0438 \u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b <code>write()<\/code>, \u0437\u0430\u043f\u0438\u0441\u044c \u0431\u0443\u0444\u0435\u0440\u0438\u0437\u0443\u0435\u0442\u0441\u044f. \u041a\u0430\u0434\u0440\u044b \u043a\u043e\u0434\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432 \u0431\u0443\u0444\u0435\u0440 \u0437\u0430\u043f\u0438\u0441\u0438 (write buffer) \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0438\u0441\u044c\u044e \u0432 \u0441\u043e\u043a\u0435\u0442. \u041e\u0434\u043d\u0430\u043a\u043e, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 <code>read_frame()<\/code>, \u0432\u0435\u0441\u044c \u043a\u0430\u0434\u0440 \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0444\u0435\u0440\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 \u0431\u0430\u0439\u0442\u043e\u0432 \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0438\u0441\u044c\u044e \u0432 \u0441\u043e\u043a\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u0434\u0440 \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e (\u0433\u0440\u0443\u043f\u043f\u043e\u0432\u043e\u0433\u043e) \u043f\u043e\u0442\u043e\u043a\u0430 (bulk stream frame). \u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u2014 <code>Frame::Bulk(Bytes)<\/code>. \u0424\u043e\u0440\u043c\u0430\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u043e\u0433\u043e \u043a\u0430\u0434\u0440\u0430 \u2014 \u044d\u0442\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043a\u0430\u0434\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0441\u0438\u043c\u0432\u043e\u043b\u0430 <code>$<\/code>, \u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u043b\u0438\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0431\u0430\u0439\u0442\u0430\u0445. \u0411\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043a\u0430\u0434\u0440\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>Bytes<\/code>. \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u0435, \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0445 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0440\u043e\u0433\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u043c.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0443\u0444\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <a href=\"https:\/\/docs.rs\/tokio\/1\/tokio\/io\/struct.BufWriter.html\">BufWriter<\/a>. \u042d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>T: AsyncWrite<\/code> \u0438 \u0441\u0430\u043c\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>AsyncWrite<\/code>. \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 <code>write()<\/code> \u0432 <code>BufWriter<\/code>, \u0437\u0430\u043f\u0438\u0441\u044c \u0438\u0434\u0435\u0442 \u043d\u0435 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438, \u0430 \u0432 \u0431\u0443\u0444\u0435\u0440. \u041a\u043e\u0433\u0434\u0430 \u0431\u0443\u0444\u0435\u0440 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f, \u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438, \u0438 \u0431\u0443\u0444\u0435\u0440 \u043e\u0447\u0438\u0449\u0430\u0435\u0442\u0441\u044f. \u0422\u0430\u043a\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0435 \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u044c (bypass) \u0431\u0443\u0444\u0435\u0440 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>write_frame<\/code>. \u041f\u043e\u043b\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 <a href=\"https:\/\/github.com\/tokio-rs\/mini-redis\/blob\/tutorial\/src\/connection.rs#L159-L184\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>Connection<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::io::BufWriter; use tokio::net::TcpStream; use bytes::BytesMut;  pub struct Connection {     stream: BufWriter&lt;TcpStream>,     buffer: BytesMut, }  impl Connection {     pub fn new(stream: TcpStream) -> Connection {         Connection {             stream: BufWriter::new(stream),             buffer: BytesMut::with_capacity(4096),         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c <code>write_frame()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::io::{self, AsyncWriteExt}; use mini_redis::Frame;  async fn write_frame(&amp;mut self, frame: &amp;Frame)     -> io::Result&lt;()> {     match frame {         Frame::Simple(val) => {             self.stream.write_u8(b'+').await?;             self.stream.write_all(val.as_bytes()).await?;             self.stream.write_all(b\"\\r\\n\").await?;         }         Frame::Error(val) => {             self.stream.write_u8(b'-').await?;             self.stream.write_all(val.as_bytes()).await?;             self.stream.write_all(b\"\\r\\n\").await?;         }         Frame::Integer(val) => {             self.stream.write_u8(b':').await?;             self.write_decimal(*val).await?;         }         Frame::Null => {             self.stream.write_all(b\"$-1\\r\\n\").await?;         }         Frame::Bulk(val) => {             let len = val.len();              self.stream.write_u8(b'$').await?;             self.write_decimal(len as u64).await?;             self.stream.write_all(val).await?;             self.stream.write_all(b\"\\r\\n\").await?;         }         Frame::Array(_val) => unimplemented!(),     }      self.stream.flush().await;      Ok(()) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0437\u0434\u0435\u0441\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f <a href=\"https:\/\/docs.rs\/tokio\/1\/tokio\/io\/trait.AsyncWriteExt.html\">AsyncWriteExt<\/a>. \u041e\u043d\u0438 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 <code>TcpStream<\/code>, \u043d\u043e \u043e\u0434\u043d\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0431\u0435\u0437 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/docs.rs\/tokio\/1\/tokio\/io\/trait.AsyncWriteExt.html#method.write_u8\">write_u8<\/a> \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0432 \u0444\u0430\u0439\u043b \u043e\u0434\u0438\u043d \u0431\u0430\u0439\u0442<\/li>\n<li><a href=\"https:\/\/docs.rs\/tokio\/1\/tokio\/io\/trait.AsyncWriteExt.html#method.write_all\">write_all<\/a> \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0432\u0435\u0441\u044c \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442<\/li>\n<li><a href=\"https:\/\/github.com\/tokio-rs\/mini-redis\/blob\/tutorial\/src\/connection.rs#L225-L238\">write_decimal<\/a> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f mini-redis<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u044b\u0437\u043e\u0432\u043e\u043c <code>self.stream.flush().await<\/code>. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>BufWriter<\/code> \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435, \u0432\u044b\u0437\u043e\u0432\u044b <code>write()<\/code> \u043d\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u044e\u0442, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0432 \u0441\u043e\u043a\u0435\u0442. \u041f\u0435\u0440\u0435\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u043e\u043c \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043a\u0430\u0434\u0440 \u0431\u044b\u043b \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0432 \u0441\u043e\u043a\u0435\u0442. \u0412\u044b\u0437\u043e\u0432 <code>flush()<\/code> \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0432 \u0441\u043e\u043a\u0435\u0442 \u043b\u044e\u0431\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435.<\/p>\n<p>  <\/p>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043e\u0439 \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>flush()<\/code> \u0432 <code>write_frame()<\/code>. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c <code>flush()<\/code> \u0443 <code>Connection<\/code>. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043a\u0430\u0434\u0440\u043e\u0432 \u0432 \u0431\u0443\u0444\u0435\u0440 \u0437\u0430\u043f\u0438\u0441\u0438, \u0430 \u0437\u0430\u0442\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438\u0445 \u0432\u0441\u0435 \u0432 \u0441\u043e\u043a\u0435\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 <code>write()<\/code>. \u042d\u0442\u043e \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0435\u0442 API <code>Connection<\/code>. \u041f\u0440\u043e\u0441\u0442\u043e\u0442\u0430 \u2014 \u043e\u0434\u043d\u0430 \u0438\u0437 \u0446\u0435\u043b\u0435\u0439 Mini-Redis, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u043b\u0438 \u0432\u044b\u0437\u043e\u0432 <code>flush().await<\/code> \u0432 <code>write_frame()<\/code>.<\/p>\n<p>  <\/p>\n<h1 id=\"podrobno-ob-asinhronnosti\">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0431 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u0438<\/h1>\n<p>  <\/p>\n<p>\u0423\u0433\u043b\u0443\u0431\u0438\u043c\u0441\u044f \u0432 \u043c\u043e\u0434\u0435\u043b\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f Rust.<\/p>\n<p>  <\/p>\n<h2 id=\"fyuchery-futures\">\u0424\u044c\u044e\u0447\u0435\u0440\u044b (futures)<\/h2>\n<p>  <\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u0440\u0430\u0442\u043a\u043e\u0433\u043e \u043e\u0431\u0437\u043e\u0440\u0430 \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e. \u0412 \u043d\u0435\u0439 \u043d\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::net::TcpStream;  async fn my_async_fn() {     println!(\"hello from async\");     let _socket = TcpStream::connect(\"127.0.0.1:3000\").await.unwrap();     println!(\"async TCP operation complete\"); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0438 \u043e\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>.await<\/code> \u043d\u0430 \u044d\u0442\u043e\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">#[tokio::main] async fn main() {     \/\/ \u0412 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u043f\u043e\u043a\u0430 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f     let what_is_this = my_async_fn();     \/\/ \u0422\u0435\u043a\u0441\u0442 \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435, \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435     \/\/ \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f     what_is_this.await; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 <code>my_async_fn()<\/code>, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u043c. \u0424\u044c\u044e\u0447\u0435\u0440 \u2014 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0442\u0438\u043f\u0430\u0436 <a href=\"https:\/\/doc.rust-lang.org\/std\/future\/trait.Future.html\">std::future::Future<\/a>, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439.<\/p>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 <code>std::future::Future<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::pin::Pin; use std::task::{Context, Poll};  pub trait Future {     type Output;      fn poll(self: Pin&lt;&amp;mut Self>, cx: &amp;mut Context) -> Poll&lt;Self::Output>; }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"https:\/\/doc.rust-lang.org\/book\/ch19-03-advanced-traits.html#specifying-placeholder-types-in-trait-definitions-with-associated-types\">\u0421\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f (associated type)<\/a> <code>Output<\/code> \u2014 \u044d\u0442\u043e \u0442\u0438\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d \u0432\u043e \u0444\u044c\u044e\u0447\u0435\u0440\u0435 \u043f\u043e\u0441\u043b\u0435 \u0435\u0433\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f. \u0422\u0438\u043f <a href=\"https:\/\/doc.rust-lang.org\/std\/pin\/index.html\">Pin<\/a> \u2014 \u044d\u0442\u043e \u0442\u043e, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0447\u0435\u0433\u043e Rust \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0444\u044c\u044e\u0447\u0435\u0440\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445, \u0444\u044c\u044e\u0447\u0435\u0440 Rust \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f, \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0432 \u0444\u043e\u043d\u043e\u0432\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435, \u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u0438\u043c\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f\u043c\u0438. \u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u0444\u044c\u044e\u0447\u0435\u0440\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 (advance) \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043f\u0443\u0442\u0435\u043c \u0435\u0433\u043e \u043e\u043f\u0440\u043e\u0441\u0430 (poll).<\/p>\n<p>  <\/p>\n<p><strong>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f <code>Future<\/code><\/strong><\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0444\u044c\u044e\u0447\u0435\u0440. \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0416\u0434\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u044f.<\/li>\n<li>\u0412\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0432 STDOUT.<\/li>\n<li>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443.<\/li>\n<\/ol>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::{Duration, Instant};  struct Delay {     when: Instant, }  impl Future for Delay {     type Output = &amp;'static str;      fn poll(self: Pin&lt;&amp;mut Self>, cx: &amp;mut Context&lt;'_>)         -> Poll&lt;&amp;'static str>     {         if Instant::now() >= self.when {             println!(\"hello world\");             Poll::Ready(\"done\")         } else {             \/\/ \u041f\u043e\u043a\u0430 \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0439\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043d\u0430 \u044d\u0442\u0443 \u0441\u0442\u0440\u043e\u043a\u0443             cx.waker().wake_by_ref();             Poll::Pending         }     } }  #[tokio::main] async fn main() {     let when = Instant::now() + Duration::from_millis(10);     let future = Delay { when };      let out = future.await;     assert_eq!(out, \"done\"); }<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u0430\u043a \u0444\u044c\u044e\u0447\u0435\u0440<\/strong><\/p>\n<p>  <\/p>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>main<\/code> \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0444\u044c\u044e\u0447\u0435\u0440\u0430 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0430 \u043d\u0435\u043c <code>.await<\/code>. \u0412 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>.await<\/code> \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0435\u0433\u043e <code>Future<\/code>. \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0432\u044b\u0437\u043e\u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0442\u0438\u043f, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 <code>Future<\/code>. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 <code>async fn main()<\/code> \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0444\u044c\u044e\u0447\u0435\u0440 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::{Duration, Instant};  enum MainFuture {     \/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d, \u043d\u0435 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u043b\u0441\u044f     State0,     \/\/ \u0416\u0434\u0435\u0442 `Delay` - \u0441\u0442\u0440\u043e\u043a\u0430 `future.await`     State1(Delay),     \/\/ \u0424\u044c\u044e\u0447\u0435\u0440 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d     Terminated, }  impl Future for MainFuture {     type Output = ();      fn poll(mut self: Pin&lt;&amp;mut Self>, cx: &amp;mut Context&lt;'_>)         -> Poll&lt;()>     {         use MainFuture::*;          loop {             match *self {                 State0 => {                     let when = Instant::now() + Duration::from_millis(10);                     let future = Delay { when };                     *self = State1(future);                 }                 State1(ref mut my_future) => {                     match Pin::new(my_future).poll(cx) {                         Poll::Ready(out) => {                             assert_eq!(out, \"done\");                             *self = Terminated;                             return Poll::Ready(());                         }                         Poll::Pending => {                             return Poll::Pending;                         }                     }                 }                 Terminated => {                     panic!(\"future polled after completion\")                 }             }         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0424\u044c\u044e\u0447\u0435\u0440\u044b Rust \u2014 \u044d\u0442\u043e \u043c\u0430\u0448\u0438\u043d\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 (state machines). \u0417\u0434\u0435\u0441\u044c <code>MainFuture<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0444\u044c\u044e\u0447\u0435\u0440\u0430. \u0424\u044c\u044e\u0447\u0435\u0440 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 <code>State0<\/code>. \u041a\u043e\u0433\u0434\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>call()<\/code>, \u0444\u044c\u044e\u0447\u0435\u0440 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0435 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435. \u0415\u0441\u043b\u0438 \u0444\u044c\u044e\u0447\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c\u0441\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f <code>Poll::Ready<\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0444\u044c\u044e\u0447\u0435\u0440 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c\u0441\u044f, \u043e\u0431\u044b\u0447\u043d\u043e \u0438\u0437-\u0437\u0430 \u043d\u0435\u0445\u0432\u0430\u0442\u043a\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f <code>Poll::Pending<\/code>. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 <code>Poll::Pending<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435, \u0447\u0442\u043e \u0444\u044c\u044e\u0447\u0435\u0440 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u043f\u043e\u0437\u0436\u0435, \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043d\u043e\u0432\u0430 \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>call()<\/code> \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0432\u0440\u0435\u043c\u044f.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0444\u044c\u044e\u0447\u0435\u0440\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0438\u0437 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u0432. \u0412\u044b\u0437\u043e\u0432 <code>call()<\/code> \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0444\u044c\u044e\u0447\u0435\u0440\u0430 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0432\u044b\u0437\u043e\u0432\u0443 <code>call()<\/code> \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0444\u044c\u044e\u0447\u0435\u0440\u0430.<\/p>\n<p>  <\/p>\n<h2 id=\"ispolniteli-executors\">\u0418\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0438 (executors)<\/h2>\n<p>  <\/p>\n<p>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 Rust \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0444\u044c\u044e\u0447\u0435\u0440\u044b. \u0414\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0444\u044c\u044e\u0447\u0435\u0440\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f <code>call()<\/code>. \u0424\u044c\u044e\u0447\u0435\u0440\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0438\u0437 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u0432. \u0412\u043e\u043f\u0440\u043e\u0441 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>call()<\/code> \u0441\u0430\u043c\u043e\u0433\u043e \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0444\u044c\u044e\u0447\u0435\u0440\u0430?<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043b\u0438\u0431\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 <code>tokio::spawn()<\/code>, \u043b\u0438\u0431\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0445 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u043e\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>#[tokio::main]<\/code>. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0444\u044c\u044e\u0447\u0435\u0440 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044e Tokio. \u0418\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0432\u044b\u0437\u043e\u0432 <code>Future::poll()<\/code> \u043d\u0430 \u0432\u043d\u0435\u0448\u043d\u0435\u043c \u0444\u044c\u044e\u0447\u0435\u0440\u0435, \u0434\u043e\u0432\u043e\u0434\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0434\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p><strong>\u041c\u0438\u043d\u0438 Tokio<\/strong><\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u0432\u0441\u0435 \u044d\u0442\u043e \u0441\u043e\u0447\u0435\u0442\u0430\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e Tokio! \u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/tokio-rs\/website\/blob\/master\/tutorial-code\/mini-tokio\/src\/main.rs\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::collections::VecDeque; use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::{Duration, Instant}; use futures::task;  fn main() {     let mut mini_tokio = MiniTokio::new();      mini_tokio.spawn(async {         let when = Instant::now() + Duration::from_millis(10);         let future = Delay { when };          let out = future.await;         assert_eq!(out, \"done\");     });      mini_tokio.run(); }  struct MiniTokio {     tasks: VecDeque&lt;Task>, }  type Task = Pin&lt;Box&lt;dyn Future&lt;Output = ()> + Send>>;  impl MiniTokio {     fn new() -> MiniTokio {         MiniTokio {             tasks: VecDeque::new(),         }     }      \/\/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u0442 \u0444\u044c\u044e\u0447\u0435\u0440 \u043d\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0435 mini-tokio     fn spawn&lt;F>(&amp;mut self, future: F)     where         F: Future&lt;Output = ()> + Send + 'static,     {         self.tasks.push_back(Box::pin(future));     }      fn run(&amp;mut self) {         let waker = task::noop_waker();         let mut cx = Context::from_waker(&amp;waker);          while let Some(mut task) = self.tasks.pop_front() {             if task.as_mut().poll(&amp;mut cx).is_pending() {                 self.tasks.push_back(task);             }         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a. \u042d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>Delay<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0438 &#171;\u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f&#187;. \u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430\u0448\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438\u043c\u0435\u0435\u0442 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u044b\u0439 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a. \u041d\u0430\u0448 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0441\u043f\u0438\u0442. \u0418\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u043f\u043e\u0440\u043e\u0436\u0434\u0435\u043d\u043d\u044b\u0435 \u0444\u044c\u044e\u0447\u0435\u0440\u044b \u0438 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0438\u0445. \u0411\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0444\u044c\u044e\u0447\u0435\u0440 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c <code>Poll::Pending<\/code>. \u042d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u0441\u0436\u0438\u0433\u0430\u0442\u044c \u0446\u0438\u043a\u043b\u044b \u0426\u041f \u0438, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u043c.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0438\u0434\u0435\u0430\u043b\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b mini-tokio \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u043b \u0444\u044c\u044e\u0447\u0435\u0440\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u0433\u043e\u0442\u043e\u0432\u044b \u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438. \u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u043a\u043e\u0433\u0434\u0430 \u0440\u0435\u0441\u0443\u0440\u0441, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430, \u0433\u043e\u0442\u043e\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e. \u0415\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0445\u043e\u0447\u0435\u0442 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0441\u043e\u043a\u0435\u0442\u0430 TCP, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u043a\u0435\u0442 TCP \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0434\u0430\u043d\u043d\u044b\u0435. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0437\u0430\u0434\u0430\u0447\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 (<code>Instant<\/code>). \u0412 \u0438\u0434\u0435\u0430\u043b\u0435, mini-tokio \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043f\u0440\u043e\u0448\u0435\u0441\u0442\u0432\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u044b\u0439, \u043d\u043e \u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0441\u0443\u0440\u0441 \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044e \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  <\/p>\n<h2 id=\"budilniki-wakers\">\u0411\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0438 (wakers)<\/h2>\n<p>  <\/p>\n<p>\u0411\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0438 \u2014 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0430\u044f \u0447\u0430\u0441\u0442\u044c. \u042d\u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0440\u0435\u0441\u0443\u0440\u0441 \u043c\u043e\u0436\u0435\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u0438\u0442\u044c \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043d \u0433\u043e\u0442\u043e\u0432 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<p>\u0415\u0449\u0435 \u0440\u0430\u0437 \u0432\u0437\u0433\u043b\u044f\u043d\u0435\u043c \u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 <code>Future::poll()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">fn poll(self: Pin&lt;&amp;mut Self>, cx: &amp;mut Context)     -> Poll&lt;Self::Output>;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <code>Context<\/code> \u043c\u0435\u0442\u043e\u0434\u0430 <code>poll<\/code> \u0438\u043c\u0435\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <code>waker<\/code>. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <a href=\"https:\/\/doc.rust-lang.org\/std\/task\/struct.Waker.html\">Waker<\/a>, \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 \u043a \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0435. \u0423 <code>Waker<\/code> \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>wake<\/code>. \u0412\u044b\u0437\u043e\u0432 \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044e, \u0447\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u0420\u0435\u0441\u0443\u0440\u0441\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442 <code>wake()<\/code>, \u043a\u043e\u0433\u0434\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044f\u0442 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438, \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0435\u0434\u043e\u043c\u0438\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043f\u0440\u043e\u0441 \u0437\u0430\u0434\u0430\u0447\u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c\u0441\u044f.<\/p>\n<p>  <\/p>\n<p><strong>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 <code>Delay<\/code><\/strong><\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c <code>Delay<\/code>, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::{Duration, Instant}; use std::thread;  struct Delay {     when: Instant, }  impl Future for Delay {     type Output = &amp;'static str;      fn poll(self: Pin&lt;&amp;mut Self>, cx: &amp;mut Context&lt;'_>)         -> Poll&lt;&amp;'static str>     {         if Instant::now() >= self.when {             println!(\"hello world\");             Poll::Ready(\"done\")         } else {             \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0430 \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438             let waker = cx.waker().clone();             let when = self.when;              \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043a \u0442\u0430\u0439\u043c\u0435\u0440\u0430             thread::spawn(move || {                 let now = Instant::now();                  if now &lt; when {                     thread::sleep(when - now);                 }                  waker.wake();             });              Poll::Pending         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435, \u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u0435\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u043e\u043f\u0440\u043e\u0441. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 mini-tokio \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u043e \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u0438.<\/p>\n<p>  <\/p>\n<p>\u0421 \u043d\u0430\u0448\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 <code>Delay<\/code> \u0432\u0441\u0435 \u0435\u0449\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c. \u041c\u044b \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c \u0438\u0445 \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>  <\/p>\n<blockquote><p>\u041a\u043e\u0433\u0434\u0430 \u0444\u044c\u044e\u0447\u0435\u0440 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>Poll::Pending<\/code>, \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0430\u043d \u0441\u0438\u0433\u043d\u0430\u043b \u043e \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u0438. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0437\u0430\u0434\u0430\u0447\u0430 \u0431\u0443\u0434\u0435\u0442 &#171;\u0432\u0438\u0441\u0435\u0442\u044c&#187; \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e.<\/p><\/blockquote>\n<p>\u0412\u0441\u043f\u043e\u043c\u043d\u0438\u043c \u043a\u043e\u0434 <code>Delay<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">impl Future for Delay {     type Output = &amp;'static str;      fn poll(self: Pin&lt;&amp;mut Self>, cx: &amp;mut Context&lt;'_>)         -> Poll&lt;&amp;'static str>     {         if Instant::now() >= self.when {             println!(\"hello world\");             Poll::Ready(\"done\")         } else {             \/\/ !             cx.waker().wake_by_ref();             Poll::Pending         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0432\u0435\u0440\u043d\u0443\u0442\u044c <code>Poll::Pending<\/code>, \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>cx.waker().wake_by_ref()<\/code>. \u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0444\u044c\u044e\u0447\u0435\u0440\u0430. \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f <code>Poll::Pending<\/code>, \u043c\u044b \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u043c \u0437\u0430 \u0432\u044b\u0437\u043e\u0432 \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0430. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0435\u0449\u0435 \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u043e\u0442\u043e\u043a \u0442\u0430\u0439\u043c\u0435\u0440\u0430 (timer thread), \u0442\u043e \u043f\u043e\u0434\u0430\u0435\u043c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0441\u0438\u0433\u043d\u0430\u043b. \u042d\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0444\u044c\u044e\u0447\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u0438, \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u0441\u043d\u043e\u0432\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432 \u043a \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044e.<\/p>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b \u0447\u0430\u0449\u0435, \u0447\u0435\u043c \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043f\u043e\u0434\u0430\u0435\u043c \u0441\u0438\u0433\u043d\u0430\u043b \u043e \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u0438, \u0445\u043e\u0442\u044f \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e. \u0412 \u044d\u0442\u043e\u043c \u043d\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u043b\u043e\u0445\u043e\u0433\u043e, \u043a\u0440\u043e\u043c\u0435 \u043d\u0435\u043d\u0443\u0436\u043d\u043e\u0439 \u0442\u0440\u0430\u0442\u044b \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430. \u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u0446\u0438\u043a\u043b\u0430 \u0437\u0430\u043d\u044f\u0442\u043e\u0441\u0442\u0438 (busy loop).<\/p>\n<p>  <\/p>\n<p><strong>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 Mini Tokio<\/strong><\/p>\n<p>  <\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 Mini Tokio \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u043e \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u0438. \u041c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043b \u0437\u0430\u0434\u0430\u0447\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u0438\u0445 \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u044f, \u0438 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e Mini Tokio \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a. \u041a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u0430\u044f \u0441 \u043d\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0430 \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435. Mini Tokio \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u0441\u0438\u0433\u043d\u0430\u043b \u0432\u043e \u0444\u044c\u044e\u0447\u0435\u0440 \u043f\u0440\u0438 \u0435\u0433\u043e \u043e\u043f\u0440\u043e\u0441\u0435.<\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 Mini Tokio \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043d\u0430\u043b \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447. \u041a\u0430\u043d\u0430\u043b\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438\u0437 \u043b\u044e\u0431\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430. \u0411\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c <code>Send<\/code> \u0438 <code>Sync<\/code>.<\/p>\n<p>  <\/p>\n<blockquote><p>\u0422\u0438\u043f\u0430\u0436\u0438 <code>Send<\/code> \u0438 <code>Sync<\/code> \u2014 \u044d\u0442\u043e \u043c\u0430\u0440\u043a\u0435\u0440\u043d\u044b\u0435 \u0442\u0438\u043f\u0430\u0436\u0438 (marker traits), \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u043e\u043c Rust. \u0422\u0438\u043f\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 <code>Send<\/code>. \u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0442\u0438\u043f\u043e\u0432 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f <code>Send<\/code>, \u043d\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 (\u0432\u0440\u043e\u0434\u0435 <a href=\"https:\/\/doc.rust-lang.org\/std\/rc\/struct.Rc.html\">Rc<\/a>) \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f. \u0422\u0438\u043f\u044b, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u043e\u0436\u043d\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 <code>Sync<\/code>. \u0422\u0438\u043f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c <code>Send<\/code>, \u043d\u043e \u043d\u0435 <code>Sync<\/code>. \u0425\u043e\u0440\u043e\u0448\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <a href=\"https:\/\/doc.rust-lang.org\/std\/cell\/struct.Cell.html\">Cell<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0438, \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043d\u0435\u043c\u0443 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u0435\u043d.<\/p><\/blockquote>\n<p>\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>MiniTokio<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::sync::mpsc; use std::sync::Arc;  struct MiniTokio {     scheduled: mpsc::Receiver&lt;Arc&lt;Task>>,     sender: mpsc::Sender&lt;Arc&lt;Task>>, }  struct Task {     \/\/ TODO }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0411\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f <code>Sync<\/code> \u0438 \u043c\u043e\u0433\u0443\u0442 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 <code>wake()<\/code> \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u0430\u043d\u0430\u043b. \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 <code>wake()<\/code> \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0443\u044e \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0443 \u043a\u0430\u043d\u0430\u043b\u0430. \u041d\u0430\u0448\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <code>Task<\/code> \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u043c\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043a\u0430\u043a \u043f\u043e\u0440\u043e\u0436\u0434\u0435\u043d\u043d\u044b\u0439 \u0444\u044c\u044e\u0447\u0435\u0440, \u0442\u0430\u043a \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044f \u0438\u0437 \u043a\u0430\u043d\u0430\u043b\u0430. \u041c\u044b \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0444\u044c\u044e\u0447\u0435\u0440 \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>TaskFuture<\/code> \u0440\u044f\u0434\u043e\u043c \u0441 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435\u043c <code>Poll<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 <code>Future::poll()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u0439. \u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u200b\u200b\u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 <code>poll<\/code> \u0432 <code>TaskFuture<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::sync::{Arc, Mutex};  \/\/\/ \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u0444\u044c\u044e\u0447\u0435\u0440 \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \/\/\/ \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 `poll` struct TaskFuture {     future: Pin&lt;Box&lt;dyn Future&lt;Output = ()> + Send>>,     poll: Poll&lt;()>, }  struct Task {     \/\/ `Mutex` \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 `Task` \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c `Sync`.     \/\/ `task_future` \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u043e\u0442\u043e\u043a\u0443.     \/\/ `Mutex` \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c. \u041d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 Tokio     \/\/ \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0437\u0434\u0435\u0441\u044c \u043c\u044c\u044e\u0442\u0435\u043a\u0441, \u043d\u043e \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 Tokio \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442     \/\/ \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430, \u0447\u0435\u043c \u043c\u043e\u0436\u0435\u0442 \u0443\u043c\u0435\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0430     task_future: Mutex&lt;TaskFuture>,     executor: mpsc::Sender&lt;Arc&lt;Task>>, }  impl Task {     fn schedule(self: &amp;Arc&lt;Self>) {         self.executor.send(self.clone());     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438, <code>Arc<\/code> \u043a\u043b\u043e\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e \u043a\u0430\u043d\u0430\u043b\u0443. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>schedule<\/code> \u043a <code>std::task::Waker<\/code>. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 API \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/doc.rust-lang.org\/std\/task\/struct.RawWakerVTable.html\">\u0440\u0443\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f vtable<\/a>. \u042d\u0442\u0430 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043d\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430. \u0412\u043c\u0435\u0441\u0442\u043e \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <a href=\"https:\/\/doc.rust-lang.org\/std\/task\/struct.RawWakerVTable.html\">RawWakerVTable<\/a> \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0442\u0438\u043b\u0438\u0442\u0443 <a href=\"https:\/\/docs.rs\/futures\/0.3\/futures\/task\/trait.ArcWake.html\">ArcWake<\/a>, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u0443\u044e \u043a\u0440\u0435\u0439\u0442\u043e\u043c <a href=\"https:\/\/docs.rs\/futures\/\">futures<\/a>. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0442\u0438\u043f\u0430\u0436, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>Task<\/code> \u043a\u0430\u043a \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a.<\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0432 \u0444\u0430\u0439\u043b <code>Cargo.toml<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">futures = \"0.3\"<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c <a href=\"https:\/\/docs.rs\/futures\/0.3\/futures\/task\/trait.ArcWake.html\">futures::task::ArcWake<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use futures::task::{self, ArcWake}; use std::sync::Arc;  impl ArcWake for Task {     fn wake_by_ref(arc_self: &amp;Arc&lt;Self>) {         arc_self.schedule();     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u0442\u043e\u043a \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>waker.wake()<\/code>, \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u0430\u043d\u0430\u043b. \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>MiniTokio::run<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">impl MiniTokio {     fn run(&amp;self) {         while let Ok(task) = self.scheduled.recv() {             task.poll();         }     }      \/\/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 mini-tokio     fn new() -> MiniTokio {         let (sender, scheduled) = mpsc::channel();          MiniTokio { scheduled, sender }     }      \/\/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u0442 \u0444\u044c\u044e\u0447\u0435\u0440 \u043d\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0435 mini-tokio.     \/\/\/     \/\/\/ \u0414\u0430\u043d\u043d\u044b\u0439 \u0444\u044c\u044e\u0447\u0435\u0440 \u043e\u0431\u0435\u0440\u043d\u0443\u0442 \u0432 `Task` \u0438 \u043f\u043e\u043c\u0435\u0449\u0435\u043d \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c `scheduled`.     \/\/\/ \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 `run()`     fn spawn&lt;F>(&amp;self, future: F)     where         F: Future&lt;Output = ()> + Send + 'static,     {         Task::spawn(future, &amp;self.sender);     } }  impl TaskFuture {     fn new(future: impl Future&lt;Output = ()> + Send + 'static) -> TaskFuture {         TaskFuture {             future: Box::pin(future),             poll: Poll::Pending,         }     }      fn poll(&amp;mut self, cx: &amp;mut Context&lt;'_>) {         \/\/ \u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u044b \u043b\u043e\u0436\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u044f, \u0434\u0430\u0436\u0435 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0444\u044c\u044e\u0447\u0435\u0440         \/\/ \u0432\u0435\u0440\u043d\u0443\u043b `Ready`. \u041e\u0434\u043d\u0430\u043a\u043e \u043e\u043f\u0440\u043e\u0441 \u0444\u044c\u044e\u0447\u0435\u0440\u0430, \u0432\u0435\u0440\u043d\u0443\u0432\u0448\u0435\u0433\u043e         \/\/ `Ready`, \u043d\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c,         \/\/ \u0447\u0442\u043e \u0444\u044c\u044e\u0447\u0435\u0440 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434 \u0435\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u043e\u043c.         \/\/ \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u043f\u0430\u043d\u0438\u043a\u0430         if self.poll.is_pending() {             self.poll = self.future.as_mut().poll(cx);         }     } }  impl Task {     fn poll(self: Arc&lt;Self>) {         \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a \u0438\u0437 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 `Task`.         \/\/ \u0417\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f `ArcWake`         let waker = task::waker(self.clone());         let mut cx = Context::from_waker(&amp;waker);          \/\/ \u041d\u0438\u043a\u0430\u043a\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c `task_future`         let mut task_future = self.task_future.try_lock().unwrap();          \/\/ \u041e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0444\u044c\u044e\u0447\u0435\u0440         task_future.poll(&amp;mut cx);     }      \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u043c.     \/\/     \/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439 `Task`, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0434\u0430\u043d\u043d\u044b\u0439 \u0444\u044c\u044e\u0447\u0435\u0440 \u0438 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0435\u0433\u043e     \/\/ \u0432 `sender`. \u041f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044c \u043a\u0430\u043d\u0430\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442 \u0435\u0435     fn spawn&lt;F>(future: F, sender: &amp;mpsc::Sender&lt;Arc&lt;Task>>)     where         F: Future&lt;Output = ()> + Send + 'static,     {         let task = Arc::new(Task {             task_future: Mutex::new(TaskFuture::new(future)),             executor: sender.clone(),         });          let _ = sender.send(task);     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043c\u043d\u043e\u0433\u043e \u0432\u0441\u0435\u0433\u043e. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d <code>MiniTokio::run()<\/code>. \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0446\u0438\u043a\u043b\u0435, \u043f\u043e\u043b\u0443\u0447\u0430\u044f \u0438\u0437 \u043a\u0430\u043d\u0430\u043b\u0430 \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 <code>new<\/code> \u0438 <code>spawn<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043a\u0430\u043d\u0430\u043b, \u0430 \u043d\u0435 <code>VecDeque<\/code>. \u041a\u043e\u0433\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0438\u043c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043b\u043e\u043d \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0434\u0430\u0447\u0430 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>Task::poll<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u044b <code>ArcWake<\/code> \u0438\u0437 \u043a\u0440\u0435\u0439\u0442\u0430 <code>futures<\/code>. \u0411\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f <code>task::Context<\/code>. \u042d\u0442\u043e\u0442 <code>task::Context<\/code> \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 <code>poll()<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"rezyume\">\u0420\u0435\u0437\u044e\u043c\u0435<\/h2>\n<p>  <\/p>\n<p>\u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 Rust. <code>async\/await<\/code> \u0432 Rust \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0438\u043f\u0430\u0436\u0430\u043c\u0438. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043c \u043a\u0440\u0435\u0439\u0442\u0430\u043c, \u0442\u0430\u043a\u0438\u043c \u043a\u0430\u043a Tokio, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 Rust \u043b\u0435\u043d\u0438\u0432\u044b \u0438 \u0442\u0440\u0435\u0431\u0443\u044e\u0442, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u043b\u0430 \u0438\u0445<\/li>\n<li>\u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0444\u044c\u044e\u0447\u0435\u0440\u0430\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0444\u044c\u044e\u0447\u0435\u0440 \u0441 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0435\u0433\u043e \u0437\u0430\u0434\u0430\u0447\u0435\u0439<\/li>\n<li>\u043a\u043e\u0433\u0434\u0430 \u0440\u0435\u0441\u0443\u0440\u0441 \u043d\u0435 \u0433\u043e\u0442\u043e\u0432 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f <code>Poll::Pending<\/code> \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a \u0437\u0430\u0434\u0430\u0447\u0438<\/li>\n<li>\u043a\u043e\u0433\u0434\u0430 \u0440\u0435\u0441\u0443\u0440\u0441 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u043c, \u043e\u0431 \u044d\u0442\u043e\u043c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a \u0437\u0430\u0434\u0430\u0447\u0438<\/li>\n<li>\u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438<\/li>\n<li>\u0437\u0430\u0434\u0430\u0447\u0430 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0435\u0449\u0435 \u0440\u0430\u0437, \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0440\u0435\u0441\u0443\u0440\u0441 \u0433\u043e\u0442\u043e\u0432, \u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"remarki\">\u0420\u0435\u043c\u0430\u0440\u043a\u0438<\/h2>\n<p>  <\/p>\n<p>\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u043f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>Delay<\/code>, \u043c\u044b \u043e\u0442\u043c\u0435\u0442\u0438\u043b\u0438, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0449\u0435\u0439. \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c Rust \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0434\u043d\u043e\u043c\u0443 \u0444\u044c\u044e\u0447\u0435\u0440\u0443 \u043c\u0438\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0438\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use futures::future::poll_fn; use std::future::Future; use std::pin::Pin;  #[tokio::main] async fn main() {     let when = Instant::now() + Duration::from_millis(10);     let mut delay = Some(Delay { when });      poll_fn(move |cx| {         let mut delay = delay.take().unwrap();         let res = Pin::new(&amp;mut delay).poll(cx);          assert!(res.is_pending());          tokio::spawn(async move {             delay.await;         });          Poll::Ready(())     }).await; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>poll_fn<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>Future<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f. \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>Delay<\/code>, \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437, \u0437\u0430\u0442\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0432 \u043d\u043e\u0432\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443, \u0433\u0434\u0435 \u043e\u043d \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f. <code>Delay::poll()<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430\u043c\u0438 <code>Waker<\/code>. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0432\u044b\u0437\u043e\u0432 <code>wake()<\/code> \u043d\u0430 <code>Waker<\/code> \u043f\u0435\u0440\u0435\u0434\u0430\u043d \u0441\u0430\u043c\u043e\u043c\u0443 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c\u0443 \u0432\u044b\u0437\u043e\u0432\u0443 <code>poll()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0444\u044c\u044e\u0447\u0435\u0440\u0430 \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 <code>poll()<\/code> \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>Waker<\/code>. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>poll<\/code> \u0434\u043e\u043b\u0436\u043d\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 <code>Waker<\/code> \u043d\u043e\u0432\u044b\u043c.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0448\u0430 \u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u043d\u043d\u044f\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f <code>Delay<\/code> \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u043b\u0430 \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0435\u0433\u043e \u043e\u043f\u0440\u043e\u0441\u0435. \u042d\u0442\u043e \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e, \u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u043d\u0435\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e, \u0435\u0441\u043b\u0438 \u043e\u043d \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0447\u0430\u0441\u0442\u043e (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c <code>select!<\/code> \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0444\u044c\u044e\u0447\u0435\u0440\u0430, \u043e\u0431\u0430 \u0431\u0443\u0434\u0443\u0442 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u044f\u043a\u0438\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u0432 \u043b\u044e\u0431\u043e\u043c \u0438\u0437 \u043d\u0438\u0445 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435). \u041e\u0434\u0438\u043d \u0438\u0437 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u043a \u0440\u0435\u0448\u0435\u043d\u0438\u044e \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0442\u044c \u0444\u0430\u043a\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043e\u043d \u0435\u0449\u0435 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e <code>Waker<\/code> \u043f\u043e\u0442\u043e\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0432\u044b\u0437\u043e\u0432\u0430\u0445 <code>call()<\/code>, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443, \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043c\u044b \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u043c \u043d\u0435 \u0441\u0430\u043c\u044b\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 <code>Waker<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0448\u0443 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::future::Future; use std::pin::Pin; use std::sync::{Arc, Mutex}; use std::task::{Context, Poll, Waker}; use std::thread; use std::time::{Duration, Instant};  struct Delay {     when: Instant,     \/\/ \u0418\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 `Some`, \u0435\u0441\u043b\u0438 \u043f\u043e\u0442\u043e\u043a \u0441\u043e\u0437\u0434\u0430\u043d, \u0438 `None`, \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435     waker: Option&lt;Arc&lt;Mutex&lt;Waker>>>, }  impl Future for Delay {     type Output = ();      fn poll(mut self: Pin&lt;&amp;mut Self>, cx: &amp;mut Context&lt;'_>) -> Poll&lt;()> {         \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440. \u0415\u0441\u043b\u0438 \u0432\u0440\u0435\u043c\u044f \u0438\u0441\u0442\u0435\u043a\u043b\u043e, \u0437\u043d\u0430\u0447\u0438\u0442         \/\/ \u044d\u0442\u043e\u0442 \u0444\u044c\u044e\u0447\u0435\u0440 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c `Poll::Ready`         if Instant::now() >= self.when {             return Poll::Ready(());         }          \/\/ \u0412\u0440\u0435\u043c\u044f \u043d\u0435 \u0438\u0441\u0442\u0435\u043a\u043b\u043e. \u0415\u0441\u043b\u0438 \u0444\u044c\u044e\u0447\u0435\u0440 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043f\u0435\u0440\u0432\u044b\u0435,         \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043a \u0442\u0430\u0439\u043c\u0435\u0440\u0430. \u0415\u0441\u043b\u0438 \u043f\u043e\u0442\u043e\u043a \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d,         \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 `Waker` \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 `Waker` \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438         if let Some(waker) = &amp;self.waker {             let mut waker = waker.lock().unwrap();              \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 `Waker` \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 `Waker` \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438.             \/\/ \u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0444\u044c\u044e\u0447\u0435\u0440\u0430 `Delay` \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d             \/\/ \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u043c\u0435\u0436\u0434\u0443 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 `poll()`. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442,             \/\/ \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439\u0441\u044f \u0432 \u0434\u0430\u043d\u043d\u043e\u043c `Context` \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f, \u0438 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b             \/\/ \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439\u0441\u044f \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a \u0434\u043b\u044f \u0443\u0447\u0435\u0442\u0430 \u044d\u0442\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f             if !waker.will_wake(cx.waker()) {                 *waker = cx.waker().clone();             }         } else {             let when = self.when;             let waker = Arc::new(Mutex::new(cx.waker().clone()));             self.waker = Some(waker.clone());              \/\/ `poll()` \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043f\u0435\u0440\u0432\u044b\u0435, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043a \u0442\u0430\u0439\u043c\u0435\u0440\u0430             thread::spawn(move || {                 let now = Instant::now();                  if now &lt; when {                     thread::sleep(when - now);                 }                  \/\/ \u0412\u0440\u0435\u043c\u044f \u0438\u0441\u0442\u0435\u043a\u043b\u043e. \u0423\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e, \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a                 let waker = waker.lock().unwrap();                 waker.wake_by_ref();             });         }          \/\/ \u041a \u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d \u0438 \u0442\u0430\u0439\u043c\u0435\u0440 \u0437\u0430\u043f\u0443\u0449\u0435\u043d.         \/\/ \u0412\u0440\u0435\u043c\u044f \u043d\u0435 \u0438\u0441\u0442\u0435\u043a\u043b\u043e, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0444\u044c\u044e\u0447\u0435\u0440 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f,         \/\/ \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u0435\u0440\u043d\u0443\u0442\u044c `Poll::Pending`.         \/\/         \/\/ \u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0442\u0438\u043f\u0430\u0436\u0430 `Future` \u0442\u0440\u0435\u0431\u0443\u0435\u0442, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0435 `Pending`         \/\/ \u0444\u044c\u044e\u0447\u0435\u0440 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0430 \u043e         \/\/ \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u043e\u043f\u0440\u043e\u0441\u0430. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435,         \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f \u0437\u0434\u0435\u0441\u044c `Pending`, \u043c\u044b \u043e\u0431\u0435\u0449\u0430\u0435\u043c, \u0447\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0435\u043c         \/\/ \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439\u0441\u044f \u0432 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0435 `Context`,         \/\/ \u043f\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u041c\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u043c \u044d\u0442\u043e \u043f\u0443\u0442\u0435\u043c         \/\/ \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0432\u044b\u0448\u0435.         \/\/         \/\/ \u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a, \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e\u0432\u0438\u0441\u043d\u0435\u0442 \u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430         Poll::Pending     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e, \u043d\u043e \u0438\u0434\u0435\u044f \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 <code>poll()<\/code> \u0444\u044c\u044e\u0447\u0435\u0440 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c. \u0415\u0441\u043b\u0438 \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442, \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u0447\u0435\u0433\u043e. \u0415\u0441\u043b\u0438 \u043e\u043d\u0438 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442, \u0442\u043e\u0433\u0434\u0430 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p><strong>\u0423\u0442\u0438\u043b\u0438\u0442\u044b <code>Notify<\/code><\/strong><\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438, \u043a\u0430\u043a \u0444\u044c\u044e\u0447\u0435\u0440 <code>Delay<\/code> \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0430. \u0411\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0441\u043d\u043e\u0432\u043e\u0439 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 Rust. \u041e\u0431\u044b\u0447\u043d\u043e \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 <code>Delay<\/code> \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>async\/await<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u0443 <a href=\"https:\/\/docs.rs\/tokio\/1\/tokio\/sync\/struct.Notify.html\">tokio::sync::Notify<\/a>. \u042d\u0442\u0430 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043e \u0437\u0430\u0434\u0430\u0447\u0430\u0445. \u041e\u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0430\u0445, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0435.<\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>Notify<\/code>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>delay<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::sync::Notify; use std::sync::Arc; use std::time::{Duration, Instant}; use std::thread;  async fn delay(dur: Duration) {     let when = Instant::now() + dur;     let notify = Arc::new(Notify::new());     let notify_clone = notify.clone();      thread::spawn(move || {         let now = Instant::now();          if now &lt; when {             thread::sleep(when - now);         }          notify_clone.notify_one();     });      notify.notified().await; }<\/code><\/pre>\n<p>  <\/p>\n<h1 id=\"vybor\">\u0412\u044b\u0431\u043e\u0440<\/h1>\n<p>  <\/p>\n<p>\u0414\u043e \u0441\u0438\u0445 \u043f\u043e\u0440, \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0438 \u043d\u043e\u0432\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Tokio.<\/p>\n<p>  <\/p>\n<h2 id=\"tokioselect\"><code>tokio::select!<\/code><\/h2>\n<p>  <\/p>\n<p>\u041c\u0430\u043a\u0440\u043e\u0441 <code>tokio::select!<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::sync::oneshot;  #[tokio::main] async fn main() {     let (tx1, rx1) = oneshot::channel();     let (tx2, rx2) = oneshot::channel();      tokio::spawn(async {         let _ = tx1.send(\"one\");     });      tokio::spawn(async {         let _ = tx2.send(\"two\");     });      tokio::select! {         val = rx1 => {             println!(\"rx1 completed first with {:?}\", val);         }         val = rx2 => {             println!(\"rx2 completed first with {:?}\", val);         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u043a\u0430\u043d\u0430\u043b\u0430 <code>oneshot<\/code>. \u041b\u044e\u0431\u043e\u0439 \u043a\u0430\u043d\u0430\u043b \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u043c. \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>select!<\/code> \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043d\u0430 \u043e\u0431\u043e\u0438\u0445 \u043a\u0430\u043d\u0430\u043b\u0430\u0445 \u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 <code>val<\/code> \u043a \u200b\u200b\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u043c\u0443 \u0437\u0430\u0434\u0430\u0447\u0435\u0439. \u041a\u043e\u0433\u0434\u0430 <code>tx1<\/code> \u0438\u043b\u0438 <code>tx2<\/code> \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0442\u0441\u044f, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0431\u043b\u043e\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u0412\u0435\u0442\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0430\u0441\u044c, \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f. \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 <code>oneshot::Receiver<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u0430\u043d\u0430\u043b\u0430. <code>oneshot::Receiver<\/code> \u0434\u043b\u044f \u043a\u0430\u043d\u0430\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0435\u0449\u0435 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d, \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p><strong>\u041e\u0442\u043c\u0435\u043d\u0430<\/strong><\/p>\n<p>  <\/p>\n<p>\u0412 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u043c Rust \u043e\u0442\u043c\u0435\u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0444\u044c\u044e\u0447\u0435\u0440\u0430. \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 Rust \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043b\u0435\u043d\u0438\u0432\u044b\u043c\u0438. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043e\u043f\u0440\u043e\u0441\u0435 \u0444\u044c\u044e\u0447\u0435\u0440\u0430. \u0415\u0441\u043b\u0438 \u0444\u044c\u044e\u0447\u0435\u0440 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d, \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0430, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432\u0441\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0438\u043d\u043e\u0433\u0434\u0430 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u0442 \u0444\u043e\u043d\u043e\u0432\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0434\u0440\u0443\u0433\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u0443\u044e \u0432 \u0444\u043e\u043d\u043e\u0432\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435. \u0412 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u0432\u044b\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u041e\u0431\u044b\u0447\u043d\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0424\u044c\u044e\u0447\u0435\u0440\u044b \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0442\u0438\u043f\u044b \u043c\u043e\u0433\u0443\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c <code>Drop<\/code> \u0434\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438. <code>oneshot::Receiver<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>Drop<\/code>, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043e \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0438 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0435 <code>Sender<\/code>. \u041f\u043e\u043b\u043e\u0432\u0438\u043d\u0430-\u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u044d\u0442\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0438 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e, \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u044f \u0435\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::sync::oneshot;  async fn some_operation() -> String {     \/\/ \u0412\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 }  #[tokio::main] async fn main() {     let (mut tx1, rx1) = oneshot::channel();     let (tx2, rx2) = oneshot::channel();      tokio::spawn(async {         \/\/ \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 `closed()`         tokio::select! {             val = some_operation() => {                 let _ = tx1.send(val);             }             _ = tx1.closed() => {                 \/\/ `some_operation()` \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430,                 \/\/ \u0437\u0430\u0434\u0430\u0447\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430, `tx1` \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d             }         }     });      tokio::spawn(async {         let _ = tx2.send(\"two\");     });      tokio::select! {         val = rx1 => {             println!(\"rx1 completed first with {:?}\", val);         }         val = rx2 => {             println!(\"rx2 completed first with {:?}\", val);         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f <code>Future<\/code><\/strong><\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 <code>select!<\/code>, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0433\u0438\u043f\u043e\u0442\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f <code>Future<\/code>. \u042d\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f. \u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 <code>select!<\/code> \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b, \u0442\u0430\u043a\u043e\u0439 \u043a\u0430\u043a \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440 \u043f\u0435\u0440\u0432\u043e\u0439 \u0432\u0435\u0442\u043a\u0438 \u0434\u043b\u044f \u043e\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::sync::oneshot; use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll};  struct MySelect {     rx1: oneshot::Receiver&lt;&amp;'static str>,     rx2: oneshot::Receiver&lt;&amp;'static str>, }  impl Future for MySelect {     type Output = ();      fn poll(mut self: Pin&lt;&amp;mut Self>, cx: &amp;mut Context&lt;'_>) -> Poll&lt;()> {         if let Poll::Ready(val) = Pin::new(&amp;mut self.rx1).poll(cx) {             println!(\"rx1 completed first with {:?}\", val);             return Poll::Ready(());         }          if let Poll::Ready(val) = Pin::new(&amp;mut self.rx2).poll(cx) {             println!(\"rx2 completed first with {:?}\", val);             return Poll::Ready(());         }          Poll::Pending     } }  #[tokio::main] async fn main() {     let (tx1, rx1) = oneshot::channel();     let (tx2, rx2) = oneshot::channel();      \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c `tx1` \u0438 `tx2`      MySelect {         rx1,         rx2,     }.await; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0424\u044c\u044e\u0447\u0435\u0440 <code>MySelect<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0444\u044c\u044e\u0447\u0435\u0440\u044b \u0438\u0437 \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0435\u0442\u043a\u0438. \u041f\u0440\u0438 \u043e\u043f\u0440\u043e\u0441\u0435 <code>MySelect<\/code> \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0442\u0432\u044c. \u0415\u0441\u043b\u0438 \u043e\u043d\u0430 \u0433\u043e\u0442\u043e\u0432\u0430, \u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0438 <code>MySelect<\/code> \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f. \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a <code>.await<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0444\u044c\u044e\u0447\u0435\u0440\u0430, \u043e\u043d \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f. \u042d\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0444\u044c\u044e\u0447\u0435\u0440\u044b \u043e\u0431\u043e\u0438\u0445 \u0432\u0435\u0442\u0432\u0435\u0439 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u044e\u0442\u0441\u044f. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u0434\u043d\u0430 \u0438\u0437 \u0432\u0435\u0442\u0432\u0435\u0439 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0442\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u0418\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0430:<\/p>\n<p>  <\/p>\n<blockquote><p>\u041a\u043e\u0433\u0434\u0430 \u0444\u044c\u044e\u0447\u0435\u0440 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>Poll::Pending<\/code>, \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0430\u0447\u0443 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u043e \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u0438 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0437\u0430\u0434\u0430\u0447\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0441\u0435\u0442\u044c \u0432\u0435\u0447\u043d\u043e.<\/p><\/blockquote>\n<p>\u0412 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>MySelect<\/code> \u043d\u0435\u0442 \u044f\u0432\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 <code>Context<\/code>. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e, \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u044f \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 <code>cx<\/code> \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0444\u044c\u044e\u0447\u0435\u0440\u044b. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0444\u044c\u044e\u0447\u0435\u0440 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044e \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u044f, <code>MySelect<\/code> \u0442\u0430\u043a\u0436\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044e \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f <code>Poll::Pending<\/code> \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 <code>Poll::Pending<\/code> \u0438\u0437 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0444\u044c\u044e\u0447\u0435\u0440\u0430.<\/p>\n<p>  <\/p>\n<h2 id=\"sintaksis\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/h2>\n<p>  <\/p>\n<p>\u041c\u0430\u043a\u0440\u043e\u0441 <code>select!<\/code> \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0434\u0432\u0443\u0445 \u0432\u0435\u0442\u0432\u0435\u0439. \u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u043b\u0438\u043c\u0438\u0442 \u2014 64 \u0432\u0435\u0442\u0432\u0438. \u041a\u0430\u0436\u0434\u0430\u044f \u0432\u0435\u0442\u0432\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">&lt;\u0448\u0430\u0431\u043b\u043e\u043d> = &lt;\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435> => &lt;\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a>,<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043e\u0446\u0435\u043d\u043a\u0435 <code>select!<\/code> \u0432\u0441\u0435 <code>&lt;\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f><\/code> \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e. \u041a\u043e\u0433\u0434\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f, \u0435\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 <code>&lt;\u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c><\/code>. \u0415\u0441\u043b\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u0443, \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0443\u0434\u0430\u043b\u044f\u044e\u0442\u0441\u044f \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f <code>&lt;\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a><\/code>. <code>&lt;\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a><\/code> \u0438\u043c\u0435\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043b\u044e\u0431\u044b\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430\u043c, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c <code>&lt;\u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c><\/code>.<\/p>\n<p>  <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>&lt;\u0448\u0430\u0431\u043b\u043e\u043d\u0430><\/code> \u2014 \u044d\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439: \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043a \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0438 <code>&lt;\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a><\/code> \u0438\u043c\u0435\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u0442\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439. \u0412\u043e\u0442 \u043f\u043e\u0447\u0435\u043c\u0443 \u0432 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u0432\u044b\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 <code>val<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f <code>&lt;\u0448\u0430\u0431\u043b\u043e\u043d\u0430><\/code>, \u0430 <code>&lt;\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a><\/code> \u0438\u043c\u0435\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a <code>val<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 <code>&lt;\u0448\u0430\u0431\u043b\u043e\u043d><\/code> \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f, \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u044e\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435. \u041a \u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u0430 \u0436\u0435 \u043b\u043e\u0433\u0438\u043a\u0430.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>select!<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043b\u044e\u0431\u043e\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430.<\/p>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u0430\u043d\u0430\u043b\u0430 <code>oneshot<\/code> \u0438 TCP-\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::net::TcpStream; use tokio::sync::oneshot;  #[tokio::main] async fn main() {     let (tx, rx) = oneshot::channel();      \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u0430\u043d\u0430\u043b\u0443     tokio::spawn(async move {         tx.send(\"done\").unwrap();     });      tokio::select! {         socket = TcpStream::connect(\"localhost:3465\") => {             println!(\"socket connected {:?}\", socket);         }         msg = rx => {             println!(\"received message {:?}\", msg);         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u0430\u043d\u0430\u043b <code>oneshot<\/code> \u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u0441\u043e\u043a\u0435\u0442\u044b \u0438\u0437 <code>TcpListener<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::io; use tokio::net::TcpListener; use tokio::sync::oneshot;  #[tokio::main] async fn main() -> io::Result&lt;()> {     let (tx, rx) = oneshot::channel();      tokio::spawn(async move {         tx.send(()).unwrap();     });      let listener = TcpListener::bind(\"localhost:3465\").await?;      tokio::select! {         _ = async {             loop {                 let (socket, _) = listener.accept().await?;                 tokio::spawn(async move { process(socket) });             }              \/\/ \u041d\u0435\u0434\u043e\u0441\u0442\u0438\u0436\u0438\u043c\u044b\u0439, \u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u043a\u043e\u0434             Ok::&lt;_, io::Error>(())         } => {}         _ = rx => {             println!(\"terminating accept loop\");         }     }      Ok(()) }  fn process(_socket: tokio::net::TcpStream) {}<\/code><\/pre>\n<p>  <\/p>\n<p>\u0426\u0438\u043a\u043b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0430 \u0438\u043b\u0438 \u043f\u043e\u043a\u0430 <code>rx<\/code> \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0428\u0430\u0431\u043b\u043e\u043d <code>_<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0430\u0441 \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<h2 id=\"vozvraschaemoe-znachenie\">\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u041c\u0430\u043a\u0440\u043e\u0441 <code>select!<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e <code>&lt;\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c><\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">async fn computation1() -> String {     \/\/ ... }  async fn computation2() -> String {     \/\/ ... }  #[tokio::main] async fn main() {     let out = tokio::select! {         res1 = computation1() => res1,         res2 = computation2() => res2,     };      println!(\"{out}\"); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e \u044d\u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b <code>&lt;\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438><\/code> \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0435\u0442\u0432\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0442\u0438\u043f. \u0415\u0441\u043b\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 <code>select!<\/code> \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u043b\u043e\u0441\u044c \u043a\u0430\u043a <code>()<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"oshibki\">\u041e\u0448\u0438\u0431\u043a\u0438<\/h2>\n<p>  <\/p>\n<p>\u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>?<\/code> \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442 (propagate) \u043e\u0448\u0438\u0431\u043a\u0443 \u0438\u0437 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f (\u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u044b\u0448\u0435). \u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0433\u0434\u0435 <code>?<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f, \u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u0438\u043b\u0438 \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435. \u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>?<\/code> \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u0438\u0437 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f <code>Result<\/code>. \u0412\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>?<\/code> \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f <code>select!<\/code>. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0435\u0449\u0435 \u0440\u0430\u0437 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440 \u0446\u0438\u043a\u043b\u0430 \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f TCP-\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::net::TcpListener; use tokio::sync::oneshot; use std::io;  #[tokio::main] async fn main() -> io::Result&lt;()> {     \/\/ ...      let listener = TcpListener::bind(\"localhost:3465\").await?;      tokio::select! {         res = async {             loop {                 let (socket, _) = listener.accept().await?;                 tokio::spawn(async move { process(socket) });             }              Ok::&lt;_, io::Error>(())         } => {             res?;         }         _ = rx => {             println!(\"terminating accept loop\");         }     }      Ok(()) }<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em> \u043d\u0430 <code>listener.accept().await?<\/code>. \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>?<\/code> \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>res<\/code>. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 <code>res<\/code> \u0431\u0443\u0434\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>Err(_)<\/code>. \u0417\u0430\u0442\u0435\u043c \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435 \u0441\u043d\u043e\u0432\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>?<\/code>. \u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f <code>res?<\/code> \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>main<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"sopostavlenie-s-shablonom\">\u0421\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c<\/h2>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u043e\u043c\u043d\u0438\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0432\u0435\u0442\u0432\u0438 <code>select!<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">&lt;\u0448\u0430\u0431\u043b\u043e\u043d> = &lt;\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435> => &lt;\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a>,<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f <code>&lt;\u0448\u0430\u0431\u043b\u043e\u043d\u0430><\/code>. \u041e\u0434\u043d\u0430\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d Rust. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432 <code>MPSC<\/code>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::sync::mpsc;  #[tokio::main] async fn main() {     let (mut tx1, mut rx1) = mpsc::channel(128);     let (mut tx2, mut rx2) = mpsc::channel(128);      tokio::spawn(async move {         \/\/ \u0414\u0435\u043b\u0430\u0435\u043c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0441 `tx1` \u0438 `tx2`     });      tokio::select! {         Some(v) = rx1.recv() => {             println!(\"Got {:?} from rx1\", v);         }         Some(v) = rx2.recv() => {             println!(\"Got {:?} from rx2\", v);         }         else => {             println!(\"Both channels closed\");         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 <code>select!<\/code> \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0442 <code>rx1<\/code> \u0438 <code>rx2<\/code>. \u0415\u0441\u043b\u0438 \u043a\u0430\u043d\u0430\u043b \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f, <code>recv()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>None<\/code>. \u042d\u0442\u043e \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u0443, \u0438 \u0432\u0435\u0442\u043a\u0430 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f. <code>select!<\/code> \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0432\u0435\u0442\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 <code>select!<\/code> \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432\u0435\u0442\u043a\u0443 <code>else<\/code>. <code>select!<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0447\u0442\u043e \u043d\u0438 \u043e\u0434\u043d\u0430 \u0438\u0437 \u0432\u0435\u0442\u0432\u0435\u0439 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d\u0443. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0435\u0442\u0432\u044c <code>else<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"zaimstvovanie\">\u0417\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0437\u0430\u0434\u0430\u0447\u0438, \u043f\u043e\u0440\u043e\u0436\u0434\u0435\u043d\u043d\u043e\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0432\u043b\u0430\u0434\u0435\u0442\u044c \u0432\u0441\u0435\u043c\u0438 \u0441\u0432\u043e\u0438\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u041c\u0430\u043a\u0440\u043e\u0441 <code>select!<\/code> \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u044d\u0442\u043e\u0433\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f. \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0435\u0442\u043a\u0438 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c\u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e. \u0421\u043b\u0435\u0434\u0443\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f Rust, \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043c\u043e\u0433\u0443\u0442 \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0434\u0432\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0443\u043d\u043a\u0442\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f TCP:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::io::AsyncWriteExt; use tokio::net::TcpStream; use std::io; use std::net::SocketAddr;  async fn race(     data: &amp;[u8],     addr1: SocketAddr,     addr2: SocketAddr ) -> io::Result&lt;()> {     tokio::select! {         Ok(_) = async {             let mut socket = TcpStream::connect(addr1).await?;             socket.write_all(data).await?;             Ok::&lt;_, io::Error>(())         } => {}         Ok(_) = async {             let mut socket = TcpStream::connect(addr2).await?;             socket.write_all(data).await?;             Ok::&lt;_, io::Error>(())         } => {}         else => {}     };      Ok(()) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <code>data<\/code> \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0430 \u0432 \u043e\u0431\u043e\u0438\u0445 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445. \u041a\u043e\u0433\u0434\u0430 \u043b\u044e\u0431\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e, \u0434\u0440\u0443\u0433\u0430\u044f \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0435\u0442\u0441\u044f. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u0441 <code>Ok(_)<\/code>, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0430 \u043e\u0434\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0434\u0440\u0443\u0433\u043e\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0434\u0435\u043b\u043e \u0434\u043e\u0445\u043e\u0434\u0438\u0442 \u0434\u043e <code>&lt;\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430><\/code> \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0435\u0442\u043a\u0438, <code>select!<\/code> \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d <code>&lt;\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a><\/code>. \u0418\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u043a\u0430\u0436\u0434\u044b\u0439 <code>&lt;\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a><\/code> \u043c\u043e\u0436\u0435\u0442 \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 <code>out<\/code> \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u043e\u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u0445:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::sync::oneshot;  #[tokio::main] async fn main() {     let (tx1, rx1) = oneshot::channel();     let (tx2, rx2) = oneshot::channel();      let mut out = String::new();      tokio::spawn(async move {         \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 `tx1` \u0438 `tx2`     });      tokio::select! {         _ = rx1 => {             out.push_str(\"rx1 completed\");         }         _ = rx2 => {             out.push_str(\"rx2 completed\");         }     }      println!(\"{}\", out); }<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"cikly\">\u0426\u0438\u043a\u043b\u044b<\/h2>\n<p>  <\/p>\n<p>\u041c\u0430\u043a\u0440\u043e\u0441 <code>select!<\/code> \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0446\u0438\u043a\u043b\u0430\u0445. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0432\u044b\u0431\u043e\u0440\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::sync::mpsc;  #[tokio::main] async fn main() {     let (tx1, mut rx1) = mpsc::channel(128);     let (tx2, mut rx2) = mpsc::channel(128);     let (tx3, mut rx3) = mpsc::channel(128);      loop {         let msg = tokio::select! {             Some(msg) = rx1.recv() => msg,             Some(msg) = rx2.recv() => msg,             Some(msg) = rx3.recv() => msg,             else => { break }         };          println!(\"Got {:?}\", msg);     }      println!(\"All channels have been closed.\"); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u044b\u0431\u043e\u0440 \u043f\u0440\u0438\u0435\u043c\u043d\u0438\u043a\u043e\u0432 \u0442\u0440\u0435\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432. \u041f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043b\u044e\u0431\u043e\u043c\u0443 \u043a\u0430\u043d\u0430\u043b\u0443, \u043e\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 STDOUT. \u041a\u043e\u0433\u0434\u0430 \u043a\u0430\u043d\u0430\u043b \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f, <code>recv()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>None<\/code>. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c, \u043c\u0430\u043a\u0440\u043e\u0441 <code>select!<\/code> \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0436\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0430 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u0430\u043d\u0430\u043b\u0430\u0445. \u041a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043a\u0430\u043d\u0430\u043b\u044b \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0442\u0441\u044f, \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0435\u0442\u0432\u044c <code>else<\/code> \u0438 \u0446\u0438\u043a\u043b \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u041c\u0430\u043a\u0440\u043e\u0441 <code>select!<\/code> \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0432\u0435\u0442\u043a\u0443 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0435\u0435 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438. \u0415\u0441\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u0438\u043c\u0435\u044e\u0442 \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0434\u043b\u044f \u043f\u0440\u0438\u0435\u043c\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u043d \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u043a\u0430\u043d\u0430\u043b. \u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043b\u0443\u0447\u0430\u044f, \u043a\u043e\u0433\u0434\u0430 \u0446\u0438\u043a\u043b \u043f\u0440\u0438\u0435\u043c\u0430 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u0447\u0435\u043c \u043e\u043d\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u0430\u043d\u0430\u043b\u044b, \u0430 \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043a\u0430\u043d\u0430\u043b\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f (fill up). \u0415\u0441\u043b\u0438 <code>select!<\/code> \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0432\u0435\u0442\u0432\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0446\u0438\u043a\u043b\u0430 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c\u0441\u044f <code>rx1<\/code>. \u0415\u0441\u043b\u0438 <code>rx1<\/code> \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u0430\u043d\u0430\u043b\u044b \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c\u0441\u044f.<\/p>\n<p>  <\/p>\n<blockquote><p>\u0415\u0441\u043b\u0438 \u043f\u0440\u0438 \u043e\u0446\u0435\u043d\u043a\u0435 <code>select!<\/code> \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u0438\u043c\u0435\u044e\u0442 \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u0430\u043d\u0430\u043b\u0430. \u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u0430\u043d\u0430\u043b\u044b \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u0442\u0440\u043e\u043d\u0443\u0442\u044b\u043c\u0438, \u0438 \u0438\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0432 \u044d\u0442\u0438\u0445 \u043a\u0430\u043d\u0430\u043b\u0430\u0445 \u0434\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0446\u0438\u043a\u043b\u0430. \u041d\u0438 \u043e\u0434\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0435 \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f.<\/p><\/blockquote>\n<p><strong>\u0412\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/strong><\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 <code>select!<\/code>. \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u0430\u043d\u0430\u043b <code>MPSC<\/code> \u0441 \u0442\u0438\u043f\u043e\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 <code>i32<\/code> \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f. \u041c\u044b \u0445\u043e\u0442\u0438\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043e\u043d\u0430 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f, \u0438\u043b\u0438 \u043f\u043e\u043a\u0430 \u0432 \u043a\u0430\u043d\u0430\u043b\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0447\u0435\u0442\u043d\u043e\u0435 \u0446\u0435\u043b\u043e\u0435 \u0447\u0438\u0441\u043b\u043e.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">async fn action() {     \/\/ ... }  #[tokio::main] async fn main() {     let (mut tx, mut rx) = tokio::sync::mpsc::channel(128);      let operation = action();     tokio::pin!(operation);      loop {         tokio::select! {             _ = &amp;mut operation => break,             Some(v) = rx.recv() => {                 if v % 2 == 0 {                     break;                 }             }         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>, \u0447\u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>action<\/code> \u0432 \u043c\u0430\u043a\u0440\u043e\u0441\u0435 <code>select!<\/code>, \u043e\u043d\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0435 \u0446\u0438\u043a\u043b\u0430. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 <code>action()<\/code> \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>operation<\/code> \u0431\u0435\u0437 \u0432\u044b\u0437\u043e\u0432\u0430 <code>.await<\/code>. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0430\u043a\u0440\u043e\u0441 <code>tokio::pin!<\/code> \u043d\u0430 <code>operation<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0446\u0438\u043a\u043b\u0435 <code>select!<\/code>, \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 <code>operation<\/code>, \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c <code>&amp;mut operation<\/code>. <code>operation<\/code> \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e. \u041a\u0430\u0436\u0434\u0430\u044f \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f \u0446\u0438\u043a\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 <code>operation<\/code> \u0432\u043c\u0435\u0441\u0442\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 <code>action()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 <code>select!<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u0437 \u043a\u0430\u043d\u0430\u043b\u0430. \u0415\u0441\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0442\u043d\u044b\u043c \u0446\u0435\u043b\u044b\u043c \u0447\u0438\u0441\u043b\u043e\u043c, \u0446\u0438\u043a\u043b \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0441\u043d\u043e\u0432\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f <code>select!<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>tokio::pin!<\/code>. \u041c\u044b \u043f\u043e\u043a\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0432\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u044f (pinning). \u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0434\u043b\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0441\u0441\u044b\u043b\u043a\u0438, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u0441\u044b\u043b\u0430\u044e\u0442\u0441\u044f, \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043e \u0438\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c <code>Unpin<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0443\u0434\u0430\u043b\u0438\u043c \u0441\u0442\u0440\u043e\u043a\u0443 <code>tokio::pin!<\/code> \u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">error[E0599]: no method named `poll` found for struct      `std::pin::Pin&lt;&amp;mut &amp;mut impl std::future::Future>`      in the current scope   --> src\/main.rs:16:9    | 16 | \/         tokio::select! { 17 | |             _ = &amp;mut operation => break, 18 | |             Some(v) = rx.recv() => { 19 | |                 if v % 2 == 0 { ...  | 22 | |             } 23 | |         }    | |_________^ method not found in    |             `std::pin::Pin&lt;&amp;mut &amp;mut impl std::future::Future>`    |    = note: the method `poll` exists but the following trait bounds             were not satisfied:            `impl std::future::Future: std::marker::Unpin`            which is required by            `&amp;mut impl std::future::Future: std::future::Future`<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0441 \u0442\u0430\u043a\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u043e\u0439, \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e, <code>Future<\/code> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043a\u0440\u0435\u043f\u0438\u0442\u044c. \u0423\u0437\u043d\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043e <code>Pin<\/code> \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/doc.rust-lang.org\/std\/pin\/index.html\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p><strong>\u041c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0432\u0435\u0442\u043a\u0438<\/strong><\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0446\u0438\u043a\u043b. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u041a\u0430\u043d\u0430\u043b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 <code>i32<\/code>.<\/li>\n<li>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0430\u0434 \u044d\u0442\u0438\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438.<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0416\u0434\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0447\u0435\u0442\u043d\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u0438\u0437 \u043a\u0430\u043d\u0430\u043b\u0430.<\/li>\n<li>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0441 \u0447\u0435\u0442\u043d\u044b\u043c \u0447\u0438\u0441\u043b\u043e\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.<\/li>\n<li>\u0416\u0434\u0435\u043c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0432 \u0442\u043e\u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0435 \u0447\u0435\u0442\u043d\u044b\u0435 \u0447\u0438\u0441\u043b\u0430, \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0435 \u0438\u0437 \u043a\u0430\u043d\u0430\u043b\u0430.<\/li>\n<li>\u0415\u0441\u043b\u0438 \u0434\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u043d\u043e\u0432\u043e\u0435 \u0447\u0435\u0442\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e, \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e.<\/li>\n<\/ol>\n<p>  <\/p>\n<pre><code class=\"rust\">async fn action(input: Option&lt;i32>) -> Option&lt;String> {     \/\/ \u0415\u0441\u043b\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f `None`, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c `None`.     \/\/ \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u043a `let i = input?;`     let i = match input {         Some(input) => input,         None => return None,     };     \/\/ \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 }  #[tokio::main] async fn main() {     let (mut tx, mut rx) = tokio::sync::mpsc::channel(128);      let mut done = false;     let operation = action(None);     tokio::pin!(operation);      tokio::spawn(async move {         let _ = tx.send(1).await;         let _ = tx.send(3).await;         let _ = tx.send(2).await;     });      loop {         tokio::select! {             res = &amp;mut operation, if !done => {                 done = true;                  if let Some(v) = res {                     println!(\"GOT = {}\", v);                     return;                 }             }             Some(v) = rx.recv() => {                 if v % 2 == 0 {                     \/\/ `.set` \u044d\u0442\u043e \u043c\u0435\u0442\u043e\u0434, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 `Pin`                     operation.set(action(Some(v)));                     done = false;                 }             }         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u0443 \u0436\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e, \u0447\u0442\u043e \u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435. \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>action<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0435 \u0446\u0438\u043a\u043b\u0430 \u0438 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>operation<\/code>. <code>operation<\/code> \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u044f\u0435\u0442\u0441\u044f. \u0426\u0438\u043a\u043b \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043a\u0430\u043a \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e, \u0442\u0430\u043a \u0438 \u043f\u0440\u0438\u0435\u043c\u043d\u0438\u043a \u043a\u0430\u043d\u0430\u043b\u0430.<\/p>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>, \u0447\u0442\u043e <code>action<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <code>Option&lt;i32><\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430. \u041f\u0435\u0440\u0435\u0434 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435\u043c \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0447\u0435\u0442\u043d\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0447\u0435\u043c-\u0442\u043e <code>operation<\/code>. \u041c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b <code>action()<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u043b\u0430 <code>Option<\/code> \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b\u0430 <code>Option<\/code>. \u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f <code>None<\/code>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f <code>None<\/code>. \u041d\u0430 \u043f\u0435\u0440\u0432\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0446\u0438\u043a\u043b\u0430, \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c <code>None<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441. \u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0442\u043a\u0430 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 <code>, if !done<\/code>. \u042d\u0442\u043e \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f. \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442, \u0435\u0441\u043b\u0438 \u043f\u0440\u0435\u0434\u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c. \u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 <code>, if !done<\/code> \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">thread 'main' panicked at '`async fn` resumed after completion', src\/main.rs:1:55 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>operation<\/code> \u043f\u043e\u0441\u043b\u0435 \u0435\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f. \u041e\u0431\u044b\u0447\u043d\u043e \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <code>.await<\/code>, \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u0435\u0442\u0441\u044f. \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u043e\u0436\u0438\u0434\u0430\u0435\u043c \u0441\u0441\u044b\u043b\u043a\u0443. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e <code>operation<\/code> \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u044d\u0442\u043e\u0439 \u043f\u0430\u043d\u0438\u043a\u0438, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u0437\u0430\u0431\u043e\u0442\u0438\u0442\u044c\u0441\u044f \u043e \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u0443\u044e \u0432\u0435\u0442\u0432\u044c, \u0435\u0441\u043b\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430. \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <code>done<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430 \u043b\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f. \u0412\u0435\u0442\u0432\u044c <code>select!<\/code> \u043c\u043e\u0436\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435. \u042d\u0442\u043e \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a <code>select!<\/code> \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0436\u0434\u0430\u0442\u044c \u043d\u0430 \u0432\u0435\u0442\u043a\u0435. \u0415\u0441\u043b\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a <code>false<\/code>, \u0432\u0435\u0442\u0432\u044c \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f. <code>done<\/code> \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c <code>false<\/code>. \u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f <code>operation<\/code>, <code>done<\/code> \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>true<\/code>. \u041d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u0435\u0442\u043a\u0430 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f. \u041f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0447\u0435\u0442\u043d\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u0438\u0437 \u043a\u0430\u043d\u0430\u043b\u0430, <code>operation<\/code> \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0438 <code>done<\/code> \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 <code>false<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"parallelizm-po-zadacham\">\u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c \u043f\u043e \u0437\u0430\u0434\u0430\u0447\u0430\u043c<\/h2>\n<p>  <\/p>\n<p>\u0418 <code>tokio::spawn()<\/code>, \u0438 <code>select!<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u041e\u0434\u043d\u0430\u043a\u043e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>tokio::spawn<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0434\u043b\u044f \u0435\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u0417\u0430\u0434\u0430\u0447\u0430 \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u0440\u0435\u0434\u043e\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f Tokio. \u0414\u0432\u0435 \u0440\u0430\u0437\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e. \u041e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u0430\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041f\u043e \u044d\u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u043f\u043e\u0440\u043e\u0436\u0434\u0435\u043d\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0438\u043c\u0435\u0435\u0442 \u0442\u043e \u0436\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0438 \u043f\u043e\u0440\u043e\u0436\u0434\u0435\u043d\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a: \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0439.<\/p>\n<p>  <\/p>\n<p>\u041c\u0430\u043a\u0440\u043e\u0441 <code>select!<\/code> \u043f\u043e\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0432\u0441\u0435 \u0432\u0435\u0442\u043a\u0438 \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0438. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432\u0441\u0435 \u0432\u0435\u0442\u043a\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u043e\u043d\u0438 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e. \u041c\u0430\u043a\u0440\u043e\u0441 <code>select!<\/code> \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 \u043e\u0434\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435.<\/p>\n<p>  <\/p>\n<h1 id=\"potoki\">\u041f\u043e\u0442\u043e\u043a\u0438<\/h1>\n<p>  <\/p>\n<p>\u041f\u043e\u0442\u043e\u043a \u2014 \u044d\u0442\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0441\u0435\u0440\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u042d\u0442\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442 <a href=\"https:\/\/doc.rust-lang.org\/book\/ch13-02-iterators.html\">std::iter::Iterator<\/a>, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f\u0430\u0436\u043e\u043c <a href=\"https:\/\/docs.rs\/futures-core\/0.3\/futures_core\/stream\/trait.Stream.html\">Stream<\/a>. \u041f\u043e\u0442\u043e\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0442\u044c \u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445. \u0418\u0445 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432. Tokio \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0445 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432 \u0432 \u0442\u0438\u043f\u0430\u0436\u0435 <a href=\"https:\/\/docs.rs\/tokio-stream\/0.1\/tokio_stream\/trait.StreamExt.html\">StreamExt<\/a>.<\/p>\n<p>  <\/p>\n<p>Tokio \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043a\u0440\u0435\u0439\u0442\u0435 <code>tokio-stream<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">tokio-stream = \"0.1\"<\/code><\/pre>\n<p>  <\/p>\n<blockquote><p>\u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 Tokio \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u043a\u0440\u0435\u0439\u0442\u0435 <code>tokio-stream<\/code>. \u041f\u043e\u0441\u043b\u0435 \u0441\u0442\u0430\u0431\u0438\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>Stream<\/code> \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 Rust, \u044d\u0442\u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u044b \u0432 \u043a\u0440\u0435\u0439\u0442 <code>tokio<\/code>.<\/p><\/blockquote>\n<p>  <\/p>\n<h2 id=\"perebor\">\u041f\u0435\u0440\u0435\u0431\u043e\u0440<\/h2>\n<p>  <\/p>\n<p>\u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u044f\u0437\u044b\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Rust \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0446\u0438\u043a\u043b\u044b <code>for<\/code>. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0431\u043e\u0440 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0446\u0438\u043a\u043b\u0430 <code>while let<\/code> \u0432 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0438 \u0441 \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>StreamExt::next<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio_stream::StreamExt;  #[tokio::main] async fn main() {     let mut stream = tokio_stream::iter(&amp;[1, 2, 3]);      while let Some(v) = stream.next().await {         println!(\"GOT = {:?}\", v);     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0438 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u044b, \u043c\u0435\u0442\u043e\u0434 <code>next<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>Option&lt;T><\/code>, \u0433\u0434\u0435 <code>T<\/code> \u2014 \u0442\u0438\u043f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 <code>None<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430.<\/p>\n<p>  <\/p>\n<p><strong>\u0422\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u044f Mini-Redis<\/strong><\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430 Mini-Redis. \u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/tokio-rs\/website\/blob\/master\/tutorial-code\/streams\/src\/main.rs\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio_stream::StreamExt; use mini_redis::client;  async fn publish() -> mini_redis::Result&lt;()> {     let mut client = client::connect(\"127.0.0.1:6379\").await?;      \/\/ \u041f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435     client.publish(\"numbers\", \"1\".into()).await?;     client.publish(\"numbers\", \"two\".into()).await?;     client.publish(\"numbers\", \"3\".into()).await?;     client.publish(\"numbers\", \"four\".into()).await?;     client.publish(\"numbers\", \"five\".into()).await?;     client.publish(\"numbers\", \"6\".into()).await?;     Ok(()) }  async fn subscribe() -> mini_redis::Result&lt;()> {     let client = client::connect(\"127.0.0.1:6379\").await?;     let subscriber = client.subscribe(vec![\"numbers\".to_string()]).await?;     let messages = subscriber.into_stream();      tokio::pin!(messages);      while let Some(msg) = messages.next().await {         println!(\"got = {:?}\", msg);     }      Ok(()) }  #[tokio::main] async fn main() -> mini_redis::Result&lt;()> {     tokio::spawn(async {         publish().await     });      subscribe().await?;      println!(\"done\");      Ok(()) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u043b\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 Mini-Redis \u0432 \u043a\u0430\u043d\u0430\u043b\u0435 <code>numbers<\/code>. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u0442 \u043a\u0430\u043d\u0430\u043b \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u043d\u0430 \u0432\u0435\u0440\u043d\u0443\u0432\u0448\u0435\u043c\u0441\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <a href=\"https:\/\/docs.rs\/mini-redis\/0.4\/mini_redis\/client\/struct.Subscriber.html#method.into_stream\">into_stream<\/a>. \u042d\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u0435\u0442 <code>Subscriber<\/code>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f \u043f\u043e\u0442\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0434\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043c\u0435\u0440\u0435 \u0438\u0445 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f. <em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434 \u043f\u0435\u0440\u0435\u0431\u043e\u0440\u043e\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0441\u0442\u0435\u043a\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0430\u043a\u0440\u043e\u0441\u0430 <a href=\"https:\/\/docs.rs\/tokio\/1\/tokio\/macro.pin.html\">tokio::pin!<\/a>. \u0412\u044b\u0437\u043e\u0432 <code>next()<\/code> \u0434\u043b\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0435\u0433\u043e \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u044f. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>into_stream<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0435\u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u044f\u0432\u043d\u043e \u0437\u0430\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u0435\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044e.<\/p>\n<p>  <\/p>\n<blockquote><p>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 Rust &#171;\u0437\u0430\u043a\u0440\u0435\u043f\u043b\u044f\u0435\u0442\u0441\u044f&#187;, \u043a\u043e\u0433\u0434\u0430 \u0435\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0432 \u043f\u0430\u043c\u044f\u0442\u0438. \u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043d\u0430 \u043d\u0435\u0433\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438. \u042d\u0442\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>async\/await<\/code> \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 \u0442\u043e\u0447\u043a\u0438 <code>.await<\/code>.<\/p><\/blockquote>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u043f\u043e\u0442\u043e\u043a, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u200b\u200b\u043e\u0448\u0438\u0431\u043a\u0443.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 Mini-Redis:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">mini-redis-server<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">got = Ok(Message { channel: \"numbers\", content: b\"1\" }) got = Ok(Message { channel: \"numbers\", content: b\"two\" }) got = Ok(Message { channel: \"numbers\", content: b\"3\" }) got = Ok(Message { channel: \"numbers\", content: b\"four\" }) got = Ok(Message { channel: \"numbers\", content: b\"five\" }) got = Ok(Message { channel: \"numbers\", content: b\"6\" })<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u043d\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u044b, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u043e\u0439 \u0438 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u0438\u0434\u0435\u0442 \u0433\u043e\u043d\u043a\u0430. \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f. \u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b Mini-Redis \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439, \u043f\u043e\u043a\u0430 \u0430\u043a\u0442\u0438\u0432\u0435\u043d \u0441\u0435\u0440\u0432\u0435\u0440.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u044d\u0442\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443.<\/p>\n<p>  <\/p>\n<h2 id=\"adaptery\">\u0410\u0434\u0430\u043f\u0442\u0435\u0440\u044b<\/h2>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 <code>Stream<\/code> \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0434\u0440\u0443\u0433\u043e\u0439 <code>Stream<\/code>, \u0447\u0430\u0441\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 &#171;\u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430\u043c\u0438 \u043f\u043e\u0442\u043e\u043a\u0430&#187;, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 \u0444\u043e\u0440\u043c\u0443 &#171;\u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430&#187; (adapter pattern). \u041f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u043c\u0438 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430\u043c\u0438 \u043f\u043e\u0442\u043e\u043a\u0430 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f <a href=\"https:\/\/docs.rs\/tokio-stream\/0.1\/tokio_stream\/trait.StreamExt.html#method.map\">map<\/a>, <a href=\"https:\/\/docs.rs\/tokio-stream\/0.1\/tokio_stream\/trait.StreamExt.html#method.take\">take<\/a> \u0438 <a href=\"https:\/\/docs.rs\/tokio-stream\/0.1\/tokio_stream\/trait.StreamExt.html#method.filter\">filter<\/a>.<\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u043d\u043e\u0432\u0438\u043c Mini-Redis, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0443. \u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>take()<\/code>. \u042d\u0442\u043e\u0442 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u0442\u043e\u043a \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0432\u044b\u0434\u0430\u0432\u0430\u043b \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 <code>n<\/code> \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">let messages = subscriber     .into_stream()     .take(3);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">got = Ok(Message { channel: \"numbers\", content: b\"1\" }) got = Ok(Message { channel: \"numbers\", content: b\"two\" }) got = Ok(Message { channel: \"numbers\", content: b\"3\" })<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043c \u043f\u043e\u0442\u043e\u043a \u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u044b\u043c\u0438 \u0447\u0438\u0441\u043b\u0430\u043c\u0438. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0434\u043b\u0438\u043d\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u043e\u0442\u0431\u0440\u043e\u0441\u0430 \u043b\u044e\u0431\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u0438\u043a\u0430\u0442\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>filter()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">let messages = subscriber     .into_stream()     .filter(|msg| match msg {         Ok(msg) if msg.content.len() == 1 => true,         _ => false,     })     .take(3);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">got = Ok(Message { channel: \"numbers\", content: b\"1\" }) got = Ok(Message { channel: \"numbers\", content: b\"3\" }) got = Ok(Message { channel: \"numbers\", content: b\"6\" })<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>, \u0447\u0442\u043e \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0412\u044b\u0437\u043e\u0432 <code>filter()<\/code>, \u0430 \u0437\u0430\u0442\u0435\u043c <code>take()<\/code> \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 <code>take()<\/code>, \u0430 \u0437\u0430\u0442\u0435\u043c <code>filter()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u0432 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0432\u044b\u0432\u043e\u0434, \u0443\u0434\u0430\u043b\u0438\u0432 \u0447\u0430\u0441\u0442\u044c <code>Ok(Message { ... })<\/code>. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>map()<\/code>. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>map()<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 <code>filter()<\/code>, \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 <code>Ok<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>unwrap()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">let messages = subscriber     .into_stream()     .filter(|msg| match msg {         Ok(msg) if msg.content.len() == 1 => true,         _ => false,     })     .map(|msg| msg.unwrap().content)     .take(3);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">got = b\"1\" got = b\"3\" got = b\"6\"<\/code><\/pre>\n<p>  <\/p>\n<p><code>filter()<\/code> \u0438 <code>map()<\/code> \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0432 \u043e\u0434\u0438\u043d \u0432\u044b\u0437\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/docs.rs\/tokio-stream\/0.1\/tokio_stream\/trait.StreamExt.html#method.filter_map\">filter_map()<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0438 <a href=\"https:\/\/docs.rs\/tokio-stream\/0.1\/tokio_stream\/trait.StreamExt.html\">\u0434\u0440\u0443\u0433\u0438\u0435 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b<\/a>.<\/p>\n<p>  <\/p>\n<h2 id=\"realizaciya-stream\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f <code>Stream<\/code><\/h2>\n<p>  <\/p>\n<p>\u0422\u0438\u043f\u0430\u0436 <code>Stream<\/code> \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u0442\u0438\u043f\u0430\u0436 <code>Future<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::pin::Pin; use std::task::{Context, Poll};  pub trait Stream {     type Item;      fn poll_next(         self: Pin&lt;&amp;mut Self>,         cx: &amp;mut Context&lt;'_>     ) -> Poll&lt;Option&lt;Self::Item>>;      fn size_hint(&amp;self) -> (usize, Option&lt;usize>) {         (0, None)     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>Stream::poll_next<\/code> \u0432\u043e \u043c\u043d\u043e\u0433\u043e\u043c \u043f\u043e\u0445\u043e\u0436\u0430 \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>Future::poll<\/code>, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0438\u0437 \u043f\u043e\u0442\u043e\u043a\u0430. \u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0435\u043b\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0440\u0430\u0437\u0434\u0435\u043b\u043e\u0432, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u0442\u043e\u043a \u043d\u0435 \u0433\u043e\u0442\u043e\u0432 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>Poll::Pending<\/code>. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a \u0437\u0430\u0434\u0430\u0447\u0438. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u043d\u043e\u0432\u0430 \u043e\u043f\u0440\u043e\u0448\u0435\u043d, \u0431\u0443\u0434\u0438\u043b\u044c\u043d\u0438\u043a \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435.<\/p>\n<p>  <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>size_hint<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 \u0441 <a href=\"https:\/\/doc.rust-lang.org\/book\/ch13-02-iterators.html\">\u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u0430\u043c\u0438<\/a>.<\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u044b\u0447\u043d\u043e \u043f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0442\u043e\u043a\u0430 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u0432 \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u0444\u044c\u044e\u0447\u0435\u0440 <code>Delay<\/code>. \u041c\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u0432 \u043f\u043e\u0442\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0434\u0430\u0435\u0442 <code>()<\/code> \u0442\u0440\u0438 \u0440\u0430\u0437\u0430 \u0441 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u043c 10 \u043c\u0441:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio_stream::Stream; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::Duration;  struct Interval {     rem: usize,     delay: Delay, }  impl Interval {     fn new() -> Self {         Self {             rem: 3,             delay: Delay { when: Instant::now() }         }     } }  impl Stream for Interval {     type Item = ();      fn poll_next(mut self: Pin&lt;&amp;mut Self>, cx: &amp;mut Context&lt;'_>)         -> Poll&lt;Option&lt;()>>     {         if self.rem == 0 {             \/\/ \u0417\u0430\u0434\u0435\u0440\u0436\u0435\u043a \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u0442             return Poll::Ready(None);         }          match Pin::new(&amp;mut self.delay).poll(cx) {             Poll::Ready(_) => {                 let when = self.delay.when + Duration::from_millis(10);                 self.delay = Delay { when };                 self.rem -= 1;                 Poll::Ready(Some(()))             }             Poll::Pending => Poll::Pending,         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p><strong><code>async-stream<\/code><\/strong><\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0438\u043f\u0430\u0436\u0430 <code>Stream<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0442\u043e\u043c\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u044f\u0437\u044b\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Rust \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 <code>async\/await<\/code> \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0440\u0435\u0439\u0442 <a href=\"https:\/\/docs.rs\/async-stream\">async-stream<\/a>. \u041e\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0430\u043a\u0440\u043e\u0441 <code>stream!<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043f\u043e\u0442\u043e\u043a. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u0442\u043e\u0433\u043e \u043a\u0440\u0435\u0439\u0442\u0430 \u0432\u044b\u0448\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use async_stream::stream; use std::time::{Duration, Instant};  stream! {     let mut when = Instant::now();      for _ in 0..3 {         let delay = Delay { when };         delay.await;         yield ();         when += Duration::from_millis(10);     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043a\u043e\u043d\u0435\u0446 \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0430, \u0432 \u0446\u0435\u043b\u043e\u043c.<\/p>\n<p>  <\/p>\n<p>Happy coding!<\/p>\n<p>  <\/p>\n<hr\/>\n<p>  <\/p>\n<blockquote><p><a href=\"https:\/\/t.me\/timewebru\"><b>\u041d\u043e\u0432\u043e\u0441\u0442\u0438, \u043e\u0431\u0437\u043e\u0440\u044b \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432 \u0438 \u043a\u043e\u043d\u043a\u0443\u0440\u0441\u044b \u043e\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b Timeweb.Cloud \u2014 \u0432 \u043d\u0430\u0448\u0435\u043c Telegram-\u043a\u0430\u043d\u0430\u043b\u0435<\/b><\/a> <b>\u21a9<\/b><\/p><\/blockquote>\n<p><a href=\"https:\/\/timeweb.cloud\/?i=106909\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/b5\/pj\/of\/b5pjofdoxth14ro-rjsrn7sbmiy.png\" data-src=\"https:\/\/habrastorage.org\/webt\/b5\/pj\/of\/b5pjofdoxth14ro-rjsrn7sbmiy.png\"\/><\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/816743\/\"> https:\/\/habr.com\/ru\/articles\/816743\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/nn\/kv\/or\/nnkvorz4qbcnf9byn5v1gfedoas.png\" data-src=\"https:\/\/habrastorage.org\/webt\/nn\/kv\/or\/nnkvorz4qbcnf9byn5v1gfedoas.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>Hello world!<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0432\u0442\u043e\u0440\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0430 \u043f\u043e <a href=\"https:\/\/tokio.rs\/\">Tokio<\/a>.<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/habr.com\/ru\/companies\/timeweb\/articles\/815811\/\">\u041f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/a><\/li>\n<li><a href=\"https:\/\/my-js.org\/docs\/guide\/tokio\/\">\u0422\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u0446\u0435\u043b\u0438\u043a\u043e\u043c<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<p>Tokio \u2014 \u044d\u0442\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0441\u0440\u0435\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (runtime) \u043a\u043e\u0434\u0430 Rust. \u041e\u043d\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043b\u044e\u0431\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-377712","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/377712","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=377712"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/377712\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=377712"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=377712"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=377712"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}