<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
    <title>Блог Бишонена - Concurrency</title>
    <subtitle>Ещё один блог о разработке программного обеспечения.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://bshn.rs/ru/tags/concurrency/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://bshn.rs"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-04-01T00:00:00+00:00</updated>
    <id>https://bshn.rs/ru/tags/concurrency/atom.xml</id>
    <entry xml:lang="ru">
        <title>Безопасность отмены в разных Rust Async-рантаймах</title>
        <published>2026-04-01T00:00:00+00:00</published>
        <updated>2026-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            Никита Бишонен
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bshn.rs/ru/blog/2026-04-01-cancellation-safety-in-async-rust-runtimes/"/>
        <id>https://bshn.rs/ru/blog/2026-04-01-cancellation-safety-in-async-rust-runtimes/</id>
        
        <content type="html" xml:base="https://bshn.rs/ru/blog/2026-04-01-cancellation-safety-in-async-rust-runtimes/">&lt;p&gt;Для более глубокого понимания я рекомендую своим дорогим друзьям прочитать или посмотреть отличный &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sunshowers.io&#x2F;posts&#x2F;cancelling-async-rust&#x2F;&quot;&gt;тред&lt;&#x2F;a&gt;, сделанный Рейном,
где она описывает её отношение к “безопасности отмены” в Rust с асинхронностью.&lt;&#x2F;p&gt;
&lt;p&gt;TL;DR для тех, кто предпочитает хакать, а не читать:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git clone https:&#x2F;&#x2F;gitlab.com&#x2F;blogging1&#x2F;cancellation-safety&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cargo test --no-fail-fast --workspace&lt;&#x2F;code&gt; (или ваш рантайм по выбору с &lt;code&gt;-p cancel_%RUNTIME%&lt;&#x2F;code&gt; вместо &lt;code&gt;--workspace&lt;&#x2F;code&gt;);&lt;&#x2F;li&gt;
&lt;li&gt;Читайте ошибки и тесты;&lt;&#x2F;li&gt;
&lt;li&gt;Читайте &lt;code&gt;lib.rs&lt;&#x2F;code&gt; для рантаймов, которые вас интересуют;&lt;&#x2F;li&gt;
&lt;li&gt;Играйте с кодом, чтобы исправить все тесты.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;problema&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#problema&quot; aria-label=&quot;Anchor link for: problema&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Проблема&lt;&#x2F;h1&gt;
&lt;p&gt;“Безопасность отмены” обычно означает отсутствие неожиданных “эффектов”, когда последовательность асинхронных операций прерывается до того, как она достигнет финального состояния.
Я могу представить &lt;code&gt;panic!&lt;&#x2F;code&gt; посередине синхронной последовательности операций как аналогию.&lt;&#x2F;p&gt;
&lt;p&gt;Её фундаментальные принципы связаны с трейтом &lt;code&gt;Future&lt;&#x2F;code&gt; и деталями реализации асинхронного рантайма.
Здесь я хотел бы провести эксперимент, чтобы найти общие паттерны и различия в том, как Tokio, smol и glommio обрабатывают отмены.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Future::poll&lt;&#x2F;code&gt; — ключевой аспект здесь, так как на этапе компиляции каждая реализация &lt;code&gt;Future&lt;&#x2F;code&gt; представляет собой конечный автомат,
представляющий последовательность операций, “отмена” означает, что &lt;strong&gt;Runtime&lt;&#x2F;strong&gt; (Реактор, Event Loop или планировщик) перестанет опрашивать этот конечный автомат и (надеюсь) уничтожит его состояние;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Pin&lt;&#x2F;code&gt; и &lt;code&gt;Unpin&lt;&#x2F;code&gt; имеют свои места, так как типы &lt;code&gt;!Unpin&lt;&#x2F;code&gt; должны обеспечивать дополнительные гарантии, чтобы считаться “безопасными” (снижение “эффектов”);&lt;&#x2F;li&gt;
&lt;li&gt;Реализация &lt;code&gt;Waker&lt;&#x2F;code&gt; может играть большую роль в обработке запросов об отмене.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;primer&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#primer&quot; aria-label=&quot;Anchor link for: primer&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Пример&lt;&#x2F;h1&gt;
&lt;p&gt;В нашем приключении мы присоединимся к нашим сильным и гордым друзьям, живущим в Мории:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; mine_with_tool&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;F&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt; FT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt; pickaxe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt;MAX_ALLOWED_SHIFTS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        pickaxe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        println!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;Здесь у ворот король ОЖИДАЕТ&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Ferrum&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Dirty&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bag &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;так наш асинхронный процесс будет имитировать работу гнома в шахтах. Сам &lt;code&gt;mine_with_tool&lt;&#x2F;code&gt; является композитной реализацией &lt;code&gt;trait Future&lt;&#x2F;code&gt;,
внутри которой выполняется &lt;code&gt;MAX_ALLOWED_SHIFTS&lt;&#x2F;code&gt; шагов для достижения своего финального (завершенного) состояния.
Простыми словами, строка 4: &lt;code&gt;pickaxe().await;&lt;&#x2F;code&gt; будет точкой, где конечный автомат опрашивается и продвигается вперед.
Это означает, что именно в этом месте может быть использовано для “отмены” выполнения.&lt;&#x2F;p&gt;
&lt;p&gt;Как это выглядит на высокоуровневом промежуточном представлении (код очищен для большей лаконичности, пожалуйста, запустите &lt;code&gt;cargo +nightly rustc -- -Z unpretty=hir&lt;&#x2F;code&gt;
внутри папки &lt;code&gt;moria&lt;&#x2F;code&gt;, чтобы увидеть полный вывод):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; mine_with_tool&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;F&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt; FT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #565869);font-style: italic;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt; pickaxe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;impl Trait&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    where&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; FnMut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt; FT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt; FT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt; std&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;future&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Future&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt; _task_context&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; ResumeTy&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        loop&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;            match&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; next&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;                None&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; break&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;                Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;  0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                    match&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; into_future&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;pickaxe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                        mut&lt;&#x2F;span&gt;&lt;span&gt; __awaitee&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                            loop&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                                match&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; unsafe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;                                        poll&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;new_unchecked&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; __awaitee&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;                                            get_context&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_task_context&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;                                    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;                                    Ready&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;  0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; break&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;                                    Pending&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;                                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                _task_context&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;yield&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;                            }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;                    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;                    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Ferrum&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Dirty&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bag &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;почти никакой “async” магии больше, у нас есть &lt;code&gt;loop&lt;&#x2F;code&gt;, &lt;code&gt;unsafe&lt;&#x2F;code&gt; и &lt;code&gt;yield ()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Давайте перейдем к “безопасности”. По моему скромному мнению, если нет &lt;code&gt;unsafe&lt;&#x2F;code&gt; кода и компилятор Rust доволен, операция безопасна.
Однако это не означает, что программа ведет себя так, как ожидают от неё программисты.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;...&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; mine_with_tool&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;...&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Ferrum&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Dirty&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bag &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;попробуйте сами понять, что делает эту реализацию &lt;code&gt;trait Future&lt;&#x2F;code&gt; названной “небезопасной отменой” (я предпочитаю небезопасная, так как &lt;strong&gt;unsafe&lt;&#x2F;strong&gt;
важно, но является отдельным термином Rust).&lt;&#x2F;p&gt;
&lt;p&gt;Ответ кроется в том, как эта асинхронная операция хранит свое состояние и отслеживает свой прогресс. Обе эти вещи происходят внутренне,
при этом удерживая изменяемую ссылку на состояние, предоставляемую вызывающей стороной &lt;code&gt;dwarf: &amp;amp;mut Dwarf&lt;&#x2F;code&gt;.
Давайте посмотрим на два примера использования этой функции внутри рантайма &lt;code&gt;smol&lt;&#x2F;code&gt;, чтобы понять, почему такая реализация может давать сюрпризы вызывающей стороне,
если произойдет отмена.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; work&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;mine&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;or&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;            Timer&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;after&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt;HALF_SHIFT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Гном здесь работает половину смены времени и сделал некоторый прогресс.
Но когда мы идем смотреть, как запускается тест:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; dwallin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Name&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Dwalin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;work&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; dwallin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; Сумка пуста, но я слышал песню!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;assert!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dwallin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;is_some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;мы видим, что проверка того, что работа была проделана, не проходит.
Причина в том, что таймаут наступил до того, как Двалину удалось завершить свою работу, и всё, что он положил в “сумку”
во внутреннем состоянии конечного автомата, было отброшено, как только мы отменили операцию в первом опросе после таймаута.
(Попробуйте изменить &lt;code&gt;Timer::after(HALF_SHIFT)&lt;&#x2F;code&gt; на использование &lt;code&gt;FULL_SHIFT&lt;&#x2F;code&gt; и посмотрите, поможет ли это 😉).
Так это то, что мы можем назвать небезопасной отменой (или некорректной, как предложила Рейн) реализацией асинхронной операции,
которая приводит к поведению, которого мы не ожидаем.&lt;&#x2F;p&gt;
&lt;p&gt;Более интересный (и более близкий к реальности) сценарий может произойти, если сделать нашу реализацию &lt;code&gt;Future&lt;&#x2F;code&gt; более сложной и “грязной”:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; work&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Mutex&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; dwarf_guard&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;lock&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; old_bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dwarf_guard&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;take&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;    timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt;HALF_SHIFT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;mine&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; dwarf_guard&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;err&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;new_bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dwarf_guard&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;as_mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        new_bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; old_bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Я знаю, гномы не любят асинхронное программание, но это иллюстрирует проблему очень хорошо.
Наша операция извлекает состояние из входных данных, держит его внутренне, затем накапливает с собственными результатами вычислений и возвращает его обратно.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;┌────────────────────────────────────────────────────────────────────────────────────────┐&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  ┌────────────┐    ┌──────────────┐    ┌───────┐    ┌─────────────┐    ┌──────────────┐│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  │ Lock Mutex │ -&amp;gt; │ Take Old Bag │ -&amp;gt; │ Mine  │ -&amp;gt; │Take New Bag │ -&amp;gt; │  Merge Bags  ││&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  └────────────┘    └──────────────┘    └───────┘    └─────────────┘    └──────────────┘│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  ┌────────────┐    ┌──────────────┐                                                    │&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│-&amp;gt;│Release Lock│ -&amp;gt; │    End       │                                                    │&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  └────────────┘    └──────────────┘                                                    │&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└────────────────────────────────────────────────────────────────────────────────────────┘&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Проблема в том, что с точки зрения мьютекса операция “безопасна”, так как мы знаем, что никто больше не изменит состояние &lt;code&gt;dwarf&lt;&#x2F;code&gt;.
Однако она “некорректна”, если мы отменим &lt;code&gt;super::mine&lt;&#x2F;code&gt; до того, как она полностью завершится.
&lt;code&gt;old_bag&lt;&#x2F;code&gt; будет отброшен, так как &lt;code&gt;new_bag&lt;&#x2F;code&gt; не будет существовать (&lt;code&gt;dwarf_guard.bag.as_mut()&lt;&#x2F;code&gt; равно &lt;code&gt;None&lt;&#x2F;code&gt;).
Так как реализация будущего &lt;code&gt;work&lt;&#x2F;code&gt; является композицией самой себя с реализацией будущего &lt;code&gt;super::mine&lt;&#x2F;code&gt; и реализацией будущего &lt;code&gt;timeout&lt;&#x2F;code&gt;,
наша логика ломается, так как оба будущего ведут себя некорректно с точки зрения системы (хотя это полностью ожидаемо, валидно и &lt;strong&gt;безопасно&lt;&#x2F;strong&gt; Rust-код по моему мнению).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;sravnenie&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#sravnenie&quot; aria-label=&quot;Anchor link for: sravnenie&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Сравнение&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;obzor-arkhitektury-rantaima&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#obzor-arkhitektury-rantaima&quot; aria-label=&quot;Anchor link for: obzor-arkhitektury-rantaima&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Обзор архитектуры рантайма&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;tokio-otraslevoi-standart&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#tokio-otraslevoi-standart&quot; aria-label=&quot;Anchor link for: tokio-otraslevoi-standart&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Tokio: Отраслевой стандарт&lt;&#x2F;h3&gt;
&lt;p&gt;Tokio представляет собой самый широко используемый асинхронный рантайм в экосистеме Rust.
Его архитектура фокусируется на:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Многопоточный пул исполнителей&lt;&#x2F;strong&gt; для вычислительно-тяжелых задач;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Модель завершения на основе Completer&lt;&#x2F;strong&gt; для неблокирующих операций;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Надежная отмена задач&lt;&#x2F;strong&gt; с явными возможностями прерывания;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Комплексная экосистема&lt;&#x2F;strong&gt; поддерживающих библиотек;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Ключевые характеристики:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Встроенные токены отмены через &lt;code&gt;tokio_util::sync::CancellationToken&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;tokio::spawn()&lt;&#x2F;code&gt; для создания задач;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;tokio::select!&lt;&#x2F;code&gt; для одновременных операций;&lt;&#x2F;li&gt;
&lt;li&gt;Встроенные утилиты таймаута;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;smol-minimalistichnyi-podkhod&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#smol-minimalistichnyi-podkhod&quot; aria-label=&quot;Anchor link for: smol-minimalistichnyi-podkhod&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
smol: Минималистичный подход&lt;&#x2F;h3&gt;
&lt;p&gt;smol использует радикально другой подход с:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Однопоточный исполнитель&lt;&#x2F;strong&gt; по умолчанию;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Упрощенный API&lt;&#x2F;strong&gt;, фокусирующийся на основных асинхронных операциях;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Собственного рантайма нет&lt;&#x2F;strong&gt; — он предоставляет существующие исполнители;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Легковесные зависимости&lt;&#x2F;strong&gt; и минимальные накладные расходы;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Ключевые характеристики:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;smol::spawn()&lt;&#x2F;code&gt; для создания задач;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;smol::Timer&lt;&#x2F;code&gt; для асинхронных задержек;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;smol::channel&lt;&#x2F;code&gt; для передачи сообщений;&lt;&#x2F;li&gt;
&lt;li&gt;Нет явных токенов отмены в основном API;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;glommio-fokus-na-proizvoditel-nosti-i-o&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#glommio-fokus-na-proizvoditel-nosti-i-o&quot; aria-label=&quot;Anchor link for: glommio-fokus-na-proizvoditel-nosti-i-o&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Glommio: Фокус на производительности I&#x2F;O&lt;&#x2F;h3&gt;
&lt;p&gt;Glommio представляет собой специализированный рантайм, разработанный для высокопроизводительных нагрузок I&#x2F;O:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Локальная модель исполнителя&lt;&#x2F;strong&gt; с подходом “share-nothing-first”;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Оптимизированный для I&#x2F;O&lt;&#x2F;strong&gt; с архитектурой thread-per-core;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Нет общей памяти&lt;&#x2F;strong&gt; между потоками по умолчанию;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Локальные только futures&lt;&#x2F;strong&gt; для лучшей локальности кэша;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Ключевые характеристики:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;glommio::LocalExecutor&lt;&#x2F;code&gt; для однопоточного выполнения;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;glommio::spawn_local()&lt;&#x2F;code&gt; для задач;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;glommio::timer&lt;&#x2F;code&gt; для задержек;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;glommio::channels::local_channel&lt;&#x2F;code&gt; для локальной только коммуникации;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;analiz-stsenariev-otmeny&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#analiz-stsenariev-otmeny&quot; aria-label=&quot;Anchor link for: analiz-stsenariev-otmeny&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Анализ сценариев отмены&lt;&#x2F;h2&gt;
&lt;p&gt;Большинство сценариев ведут себя похоже в разных рантаймах:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Простая отмена через Drop: используйте явные механизмы drop для futures, и все рантаймы показывают частичную потерю работы, когда futures отбрасываются неожиданно;&lt;&#x2F;li&gt;
&lt;li&gt;Отмена через таймаут: все предоставляют явную обработку таймаута, и тесты показывают, что таймаут не сохраняет частичные результаты;&lt;&#x2F;li&gt;
&lt;li&gt;Операции, защищенные мьютексом: &lt;code&gt;tokio::sync::Mutex&lt;&#x2F;code&gt;, &lt;code&gt;smol::lock::Mutex&lt;&#x2F;code&gt;, &lt;code&gt;glommio::sync::RwLock&lt;&#x2F;code&gt; имеют схожую семантику,
в то время как тесты демонстрируют паттерны удержания блокировок и очистка работает так, как должно, хотя мы все равно теряем прогресс;&lt;&#x2F;li&gt;
&lt;li&gt;Коммуникация на основе каналов: очень похоже, только с нюансами локальности;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Но некоторые из них имеют нюансы:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Макросы вроде &lt;code&gt;select!&lt;&#x2F;code&gt; и одновременные операции с токенами отмены специфичны для экосистемы рантайма &lt;code&gt;Tokio&lt;&#x2F;code&gt;,
что кажется не хорошим или плохим делом. Как описала Рейн в своём треде и что я слышал от других разработчиков,
такие макросы иногда полностью запрещаются в проектах из-за их неявного характера (и например заменяются на &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;futures-concurrency&#x2F;latest&#x2F;futures_concurrency&#x2F;&quot;&gt;futures_concurrency&lt;&#x2F;a&gt;);&lt;&#x2F;li&gt;
&lt;li&gt;“Явная” отмена:
&lt;ul&gt;
&lt;li&gt;в &lt;code&gt;Tokio&lt;&#x2F;code&gt; делается через &lt;code&gt;JoinHandle::abort&lt;&#x2F;code&gt;, и отбрасывание хендла не вызывает отмену, &lt;code&gt;nahdle.await&lt;&#x2F;code&gt; вернет ошибку &lt;code&gt;JoinError&lt;&#x2F;code&gt;
если реализация будущего была отменена (или нормальный результат, если она завершилась), также стоит отметить, что задачи &lt;code&gt;spawn_blocking&lt;&#x2F;code&gt; не являются “отменяемыми”,
так как они не асинхронны (но это предотвратит запуск задачи, если она еще не началась!);&lt;&#x2F;li&gt;
&lt;li&gt;в &lt;code&gt;smol&lt;&#x2F;code&gt; можно вызвать &lt;code&gt;Task::cancel&lt;&#x2F;code&gt; и дождаться отмены (которая может вернуть &lt;code&gt;Some&lt;&#x2F;code&gt;, если завершилась), это похоже на отбрасывание реализации будущего;&lt;&#x2F;li&gt;
&lt;li&gt;в &lt;code&gt;glommio&lt;&#x2F;code&gt; подход также идентичен &lt;code&gt;smol&lt;&#x2F;code&gt; с тем, что возвращается &lt;code&gt;Option&lt;&#x2F;code&gt; при ожидании отмены;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Со стороны документации эта тема покрыта только в документации API &lt;code&gt;Tokio&lt;&#x2F;code&gt;, &lt;code&gt;smol&lt;&#x2F;code&gt; имеет одну маленькую (ха-ха) заметку на этот счет:&lt;strong&gt;Примечание, что отмена задачи на самом деле разбудит её и перепланирует в последний раз. Затем исполнитель может уничтожить задачу, просто отбросив её Runnable или вызвав run().&lt;&#x2F;strong&gt;,
в то время как в &lt;code&gt;glommio&lt;&#x2F;code&gt; я не смог найти упоминаний о безопасности отмены или корректности. Я думаю, есть два фактора, почему это так:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;У Tokio гораздо большая популярность и использование, хотя и больше ресурсов для добавления документации;&lt;&#x2F;li&gt;
&lt;li&gt;У Tokio гораздо более “опасный” API и внутренняя модель исполнителя, что делает его легче встретить проблемы безопасности отмены при его использовании;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Надеюсь, вы нашли что-то новое в этом блог-посте, пишите свои мысли в комментариях и проверьте дополнительные ресурсы, если хотите.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;dopolnitel-nye-resursy-i-istochniki-vdokhnoveniia&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#dopolnitel-nye-resursy-i-istochniki-vdokhnoveniia&quot; aria-label=&quot;Anchor link for: dopolnitel-nye-resursy-i-istochniki-vdokhnoveniia&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Дополнительные ресурсы и источники вдохновения&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Отличный тред Рейна &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sunshowers.io&#x2F;posts&#x2F;cancelling-async-rust&#x2F;&quot;&gt;talk&lt;&#x2F;a&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;Текущий комментарий о &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;async-book&#x2F;issues&#x2F;227#issuecomment-2496234560&quot;&gt;state of the book section&lt;&#x2F;a&gt; о безопасности отмены;&lt;&#x2F;li&gt;
&lt;li&gt;Документация Tokio на &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;tokio&#x2F;latest&#x2F;tokio&#x2F;sync&#x2F;mpsc&#x2F;struct.Sender.html#cancel-safety&quot;&gt;эту тему&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;futures-concurrency&#x2F;latest&#x2F;futures_concurrency&#x2F;&quot;&gt;Structured Concurrency lib&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;(Конец файла - всего 266 строк)&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
