blob: 578ea3d978859c3272ade8b0f477eac6dae110b8 [file] [log] [blame]
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `/root/.cargo/git/checkouts/tokio-377c595163f99a10/dfe252d/tokio/src/time/interval.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>interval.rs - source</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceSerif4-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../FiraSans-Regular.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../FiraSans-Medium.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceCodePro-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceSerif4-Bold.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceCodePro-Semibold.ttf.woff2"><link rel="stylesheet" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../source-script.js"></script><script defer src="../../../source-files.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc source"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><a class="sidebar-logo" href="../../../tokio/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a></nav><main><div class="width-limiter"><nav class="sub"><a class="sub-logo-container" href="../../../tokio/index.html"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></a><form class="search-form"><div class="search-container"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></div></form></nav><section id="main-content" class="content"><div class="example-wrap"><pre class="src-line-numbers"><span id="1">1</span>
<span id="2">2</span>
<span id="3">3</span>
<span id="4">4</span>
<span id="5">5</span>
<span id="6">6</span>
<span id="7">7</span>
<span id="8">8</span>
<span id="9">9</span>
<span id="10">10</span>
<span id="11">11</span>
<span id="12">12</span>
<span id="13">13</span>
<span id="14">14</span>
<span id="15">15</span>
<span id="16">16</span>
<span id="17">17</span>
<span id="18">18</span>
<span id="19">19</span>
<span id="20">20</span>
<span id="21">21</span>
<span id="22">22</span>
<span id="23">23</span>
<span id="24">24</span>
<span id="25">25</span>
<span id="26">26</span>
<span id="27">27</span>
<span id="28">28</span>
<span id="29">29</span>
<span id="30">30</span>
<span id="31">31</span>
<span id="32">32</span>
<span id="33">33</span>
<span id="34">34</span>
<span id="35">35</span>
<span id="36">36</span>
<span id="37">37</span>
<span id="38">38</span>
<span id="39">39</span>
<span id="40">40</span>
<span id="41">41</span>
<span id="42">42</span>
<span id="43">43</span>
<span id="44">44</span>
<span id="45">45</span>
<span id="46">46</span>
<span id="47">47</span>
<span id="48">48</span>
<span id="49">49</span>
<span id="50">50</span>
<span id="51">51</span>
<span id="52">52</span>
<span id="53">53</span>
<span id="54">54</span>
<span id="55">55</span>
<span id="56">56</span>
<span id="57">57</span>
<span id="58">58</span>
<span id="59">59</span>
<span id="60">60</span>
<span id="61">61</span>
<span id="62">62</span>
<span id="63">63</span>
<span id="64">64</span>
<span id="65">65</span>
<span id="66">66</span>
<span id="67">67</span>
<span id="68">68</span>
<span id="69">69</span>
<span id="70">70</span>
<span id="71">71</span>
<span id="72">72</span>
<span id="73">73</span>
<span id="74">74</span>
<span id="75">75</span>
<span id="76">76</span>
<span id="77">77</span>
<span id="78">78</span>
<span id="79">79</span>
<span id="80">80</span>
<span id="81">81</span>
<span id="82">82</span>
<span id="83">83</span>
<span id="84">84</span>
<span id="85">85</span>
<span id="86">86</span>
<span id="87">87</span>
<span id="88">88</span>
<span id="89">89</span>
<span id="90">90</span>
<span id="91">91</span>
<span id="92">92</span>
<span id="93">93</span>
<span id="94">94</span>
<span id="95">95</span>
<span id="96">96</span>
<span id="97">97</span>
<span id="98">98</span>
<span id="99">99</span>
<span id="100">100</span>
<span id="101">101</span>
<span id="102">102</span>
<span id="103">103</span>
<span id="104">104</span>
<span id="105">105</span>
<span id="106">106</span>
<span id="107">107</span>
<span id="108">108</span>
<span id="109">109</span>
<span id="110">110</span>
<span id="111">111</span>
<span id="112">112</span>
<span id="113">113</span>
<span id="114">114</span>
<span id="115">115</span>
<span id="116">116</span>
<span id="117">117</span>
<span id="118">118</span>
<span id="119">119</span>
<span id="120">120</span>
<span id="121">121</span>
<span id="122">122</span>
<span id="123">123</span>
<span id="124">124</span>
<span id="125">125</span>
<span id="126">126</span>
<span id="127">127</span>
<span id="128">128</span>
<span id="129">129</span>
<span id="130">130</span>
<span id="131">131</span>
<span id="132">132</span>
<span id="133">133</span>
<span id="134">134</span>
<span id="135">135</span>
<span id="136">136</span>
<span id="137">137</span>
<span id="138">138</span>
<span id="139">139</span>
<span id="140">140</span>
<span id="141">141</span>
<span id="142">142</span>
<span id="143">143</span>
<span id="144">144</span>
<span id="145">145</span>
<span id="146">146</span>
<span id="147">147</span>
<span id="148">148</span>
<span id="149">149</span>
<span id="150">150</span>
<span id="151">151</span>
<span id="152">152</span>
<span id="153">153</span>
<span id="154">154</span>
<span id="155">155</span>
<span id="156">156</span>
<span id="157">157</span>
<span id="158">158</span>
<span id="159">159</span>
<span id="160">160</span>
<span id="161">161</span>
<span id="162">162</span>
<span id="163">163</span>
<span id="164">164</span>
<span id="165">165</span>
<span id="166">166</span>
<span id="167">167</span>
<span id="168">168</span>
<span id="169">169</span>
<span id="170">170</span>
<span id="171">171</span>
<span id="172">172</span>
<span id="173">173</span>
<span id="174">174</span>
<span id="175">175</span>
<span id="176">176</span>
<span id="177">177</span>
<span id="178">178</span>
<span id="179">179</span>
<span id="180">180</span>
<span id="181">181</span>
<span id="182">182</span>
<span id="183">183</span>
<span id="184">184</span>
<span id="185">185</span>
<span id="186">186</span>
<span id="187">187</span>
<span id="188">188</span>
<span id="189">189</span>
<span id="190">190</span>
<span id="191">191</span>
<span id="192">192</span>
<span id="193">193</span>
<span id="194">194</span>
<span id="195">195</span>
<span id="196">196</span>
<span id="197">197</span>
<span id="198">198</span>
<span id="199">199</span>
<span id="200">200</span>
<span id="201">201</span>
<span id="202">202</span>
<span id="203">203</span>
<span id="204">204</span>
<span id="205">205</span>
<span id="206">206</span>
<span id="207">207</span>
<span id="208">208</span>
<span id="209">209</span>
<span id="210">210</span>
<span id="211">211</span>
<span id="212">212</span>
<span id="213">213</span>
<span id="214">214</span>
<span id="215">215</span>
<span id="216">216</span>
<span id="217">217</span>
<span id="218">218</span>
<span id="219">219</span>
<span id="220">220</span>
<span id="221">221</span>
<span id="222">222</span>
<span id="223">223</span>
<span id="224">224</span>
<span id="225">225</span>
<span id="226">226</span>
<span id="227">227</span>
<span id="228">228</span>
<span id="229">229</span>
<span id="230">230</span>
<span id="231">231</span>
<span id="232">232</span>
<span id="233">233</span>
<span id="234">234</span>
<span id="235">235</span>
<span id="236">236</span>
<span id="237">237</span>
<span id="238">238</span>
<span id="239">239</span>
<span id="240">240</span>
<span id="241">241</span>
<span id="242">242</span>
<span id="243">243</span>
<span id="244">244</span>
<span id="245">245</span>
<span id="246">246</span>
<span id="247">247</span>
<span id="248">248</span>
<span id="249">249</span>
<span id="250">250</span>
<span id="251">251</span>
<span id="252">252</span>
<span id="253">253</span>
<span id="254">254</span>
<span id="255">255</span>
<span id="256">256</span>
<span id="257">257</span>
<span id="258">258</span>
<span id="259">259</span>
<span id="260">260</span>
<span id="261">261</span>
<span id="262">262</span>
<span id="263">263</span>
<span id="264">264</span>
<span id="265">265</span>
<span id="266">266</span>
<span id="267">267</span>
<span id="268">268</span>
<span id="269">269</span>
<span id="270">270</span>
<span id="271">271</span>
<span id="272">272</span>
<span id="273">273</span>
<span id="274">274</span>
<span id="275">275</span>
<span id="276">276</span>
<span id="277">277</span>
<span id="278">278</span>
<span id="279">279</span>
<span id="280">280</span>
<span id="281">281</span>
<span id="282">282</span>
<span id="283">283</span>
<span id="284">284</span>
<span id="285">285</span>
<span id="286">286</span>
<span id="287">287</span>
<span id="288">288</span>
<span id="289">289</span>
<span id="290">290</span>
<span id="291">291</span>
<span id="292">292</span>
<span id="293">293</span>
<span id="294">294</span>
<span id="295">295</span>
<span id="296">296</span>
<span id="297">297</span>
<span id="298">298</span>
<span id="299">299</span>
<span id="300">300</span>
<span id="301">301</span>
<span id="302">302</span>
<span id="303">303</span>
<span id="304">304</span>
<span id="305">305</span>
<span id="306">306</span>
<span id="307">307</span>
<span id="308">308</span>
<span id="309">309</span>
<span id="310">310</span>
<span id="311">311</span>
<span id="312">312</span>
<span id="313">313</span>
<span id="314">314</span>
<span id="315">315</span>
<span id="316">316</span>
<span id="317">317</span>
<span id="318">318</span>
<span id="319">319</span>
<span id="320">320</span>
<span id="321">321</span>
<span id="322">322</span>
<span id="323">323</span>
<span id="324">324</span>
<span id="325">325</span>
<span id="326">326</span>
<span id="327">327</span>
<span id="328">328</span>
<span id="329">329</span>
<span id="330">330</span>
<span id="331">331</span>
<span id="332">332</span>
<span id="333">333</span>
<span id="334">334</span>
<span id="335">335</span>
<span id="336">336</span>
<span id="337">337</span>
<span id="338">338</span>
<span id="339">339</span>
<span id="340">340</span>
<span id="341">341</span>
<span id="342">342</span>
<span id="343">343</span>
<span id="344">344</span>
<span id="345">345</span>
<span id="346">346</span>
<span id="347">347</span>
<span id="348">348</span>
<span id="349">349</span>
<span id="350">350</span>
<span id="351">351</span>
<span id="352">352</span>
<span id="353">353</span>
<span id="354">354</span>
<span id="355">355</span>
<span id="356">356</span>
<span id="357">357</span>
<span id="358">358</span>
<span id="359">359</span>
<span id="360">360</span>
<span id="361">361</span>
<span id="362">362</span>
<span id="363">363</span>
<span id="364">364</span>
<span id="365">365</span>
<span id="366">366</span>
<span id="367">367</span>
<span id="368">368</span>
<span id="369">369</span>
<span id="370">370</span>
<span id="371">371</span>
<span id="372">372</span>
<span id="373">373</span>
<span id="374">374</span>
<span id="375">375</span>
<span id="376">376</span>
<span id="377">377</span>
<span id="378">378</span>
<span id="379">379</span>
<span id="380">380</span>
<span id="381">381</span>
<span id="382">382</span>
<span id="383">383</span>
<span id="384">384</span>
<span id="385">385</span>
<span id="386">386</span>
<span id="387">387</span>
<span id="388">388</span>
<span id="389">389</span>
<span id="390">390</span>
<span id="391">391</span>
<span id="392">392</span>
<span id="393">393</span>
<span id="394">394</span>
<span id="395">395</span>
<span id="396">396</span>
<span id="397">397</span>
<span id="398">398</span>
<span id="399">399</span>
<span id="400">400</span>
<span id="401">401</span>
<span id="402">402</span>
<span id="403">403</span>
<span id="404">404</span>
<span id="405">405</span>
<span id="406">406</span>
<span id="407">407</span>
<span id="408">408</span>
<span id="409">409</span>
<span id="410">410</span>
<span id="411">411</span>
<span id="412">412</span>
<span id="413">413</span>
<span id="414">414</span>
<span id="415">415</span>
<span id="416">416</span>
<span id="417">417</span>
<span id="418">418</span>
<span id="419">419</span>
<span id="420">420</span>
<span id="421">421</span>
<span id="422">422</span>
<span id="423">423</span>
<span id="424">424</span>
<span id="425">425</span>
<span id="426">426</span>
<span id="427">427</span>
<span id="428">428</span>
<span id="429">429</span>
<span id="430">430</span>
<span id="431">431</span>
<span id="432">432</span>
<span id="433">433</span>
<span id="434">434</span>
<span id="435">435</span>
<span id="436">436</span>
<span id="437">437</span>
<span id="438">438</span>
<span id="439">439</span>
<span id="440">440</span>
<span id="441">441</span>
<span id="442">442</span>
<span id="443">443</span>
<span id="444">444</span>
<span id="445">445</span>
<span id="446">446</span>
<span id="447">447</span>
<span id="448">448</span>
<span id="449">449</span>
<span id="450">450</span>
<span id="451">451</span>
<span id="452">452</span>
<span id="453">453</span>
<span id="454">454</span>
<span id="455">455</span>
<span id="456">456</span>
<span id="457">457</span>
<span id="458">458</span>
<span id="459">459</span>
<span id="460">460</span>
<span id="461">461</span>
<span id="462">462</span>
<span id="463">463</span>
<span id="464">464</span>
<span id="465">465</span>
<span id="466">466</span>
<span id="467">467</span>
<span id="468">468</span>
<span id="469">469</span>
<span id="470">470</span>
<span id="471">471</span>
<span id="472">472</span>
<span id="473">473</span>
<span id="474">474</span>
<span id="475">475</span>
<span id="476">476</span>
<span id="477">477</span>
<span id="478">478</span>
<span id="479">479</span>
<span id="480">480</span>
<span id="481">481</span>
<span id="482">482</span>
<span id="483">483</span>
<span id="484">484</span>
<span id="485">485</span>
<span id="486">486</span>
<span id="487">487</span>
<span id="488">488</span>
<span id="489">489</span>
<span id="490">490</span>
<span id="491">491</span>
<span id="492">492</span>
<span id="493">493</span>
<span id="494">494</span>
<span id="495">495</span>
<span id="496">496</span>
<span id="497">497</span>
<span id="498">498</span>
<span id="499">499</span>
<span id="500">500</span>
<span id="501">501</span>
<span id="502">502</span>
<span id="503">503</span>
<span id="504">504</span>
<span id="505">505</span>
<span id="506">506</span>
<span id="507">507</span>
<span id="508">508</span>
<span id="509">509</span>
<span id="510">510</span>
<span id="511">511</span>
<span id="512">512</span>
<span id="513">513</span>
<span id="514">514</span>
<span id="515">515</span>
<span id="516">516</span>
<span id="517">517</span>
<span id="518">518</span>
<span id="519">519</span>
<span id="520">520</span>
<span id="521">521</span>
<span id="522">522</span>
<span id="523">523</span>
<span id="524">524</span>
<span id="525">525</span>
<span id="526">526</span>
<span id="527">527</span>
<span id="528">528</span>
<span id="529">529</span>
<span id="530">530</span>
<span id="531">531</span>
<span id="532">532</span>
<span id="533">533</span>
<span id="534">534</span>
<span id="535">535</span>
</pre><pre class="rust"><code><span class="kw">use </span><span class="kw">crate</span>::future::poll_fn;
<span class="kw">use </span><span class="kw">crate</span>::time::{sleep_until, Duration, Instant, Sleep};
<span class="kw">use </span><span class="kw">crate</span>::util::trace;
<span class="kw">use </span>std::panic::Location;
<span class="kw">use </span>std::pin::Pin;
<span class="kw">use </span>std::task::{Context, Poll};
<span class="kw">use </span>std::{convert::TryInto, future::Future};
<span class="doccomment">/// Creates new [`Interval`] that yields with interval of `period`. The first
/// tick completes immediately. The default [`MissedTickBehavior`] is
/// [`Burst`](MissedTickBehavior::Burst), but this can be configured
/// by calling [`set_missed_tick_behavior`](Interval::set_missed_tick_behavior).
///
/// An interval will tick indefinitely. At any time, the [`Interval`] value can
/// be dropped. This cancels the interval.
///
/// This function is equivalent to
/// [`interval_at(Instant::now(), period)`](interval_at).
///
/// # Panics
///
/// This function panics if `period` is zero.
///
/// # Examples
///
/// ```
/// use tokio::time::{self, Duration};
///
/// #[tokio::main]
/// async fn main() {
/// let mut interval = time::interval(Duration::from_millis(10));
///
/// interval.tick().await; // ticks immediately
/// interval.tick().await; // ticks after 10ms
/// interval.tick().await; // ticks after 10ms
///
/// // approximately 20ms have elapsed.
/// }
/// ```
///
/// A simple example using `interval` to execute a task every two seconds.
///
/// The difference between `interval` and [`sleep`] is that an [`Interval`]
/// measures the time since the last tick, which means that [`.tick().await`]
/// may wait for a shorter time than the duration specified for the interval
/// if some time has passed between calls to [`.tick().await`].
///
/// If the tick in the example below was replaced with [`sleep`], the task
/// would only be executed once every three seconds, and not every two
/// seconds.
///
/// ```
/// use tokio::time;
///
/// async fn task_that_takes_a_second() {
/// println!(&quot;hello&quot;);
/// time::sleep(time::Duration::from_secs(1)).await
/// }
///
/// #[tokio::main]
/// async fn main() {
/// let mut interval = time::interval(time::Duration::from_secs(2));
/// for _i in 0..5 {
/// interval.tick().await;
/// task_that_takes_a_second().await;
/// }
/// }
/// ```
///
/// [`sleep`]: crate::time::sleep()
/// [`.tick().await`]: Interval::tick
</span><span class="attribute">#[track_caller]
</span><span class="kw">pub fn </span>interval(period: Duration) -&gt; Interval {
<span class="macro">assert!</span>(period &gt; Duration::new(<span class="number">0</span>, <span class="number">0</span>), <span class="string">&quot;`period` must be non-zero.&quot;</span>);
internal_interval_at(Instant::now(), period, trace::caller_location())
}
<span class="doccomment">/// Creates new [`Interval`] that yields with interval of `period` with the
/// first tick completing at `start`. The default [`MissedTickBehavior`] is
/// [`Burst`](MissedTickBehavior::Burst), but this can be configured
/// by calling [`set_missed_tick_behavior`](Interval::set_missed_tick_behavior).
///
/// An interval will tick indefinitely. At any time, the [`Interval`] value can
/// be dropped. This cancels the interval.
///
/// # Panics
///
/// This function panics if `period` is zero.
///
/// # Examples
///
/// ```
/// use tokio::time::{interval_at, Duration, Instant};
///
/// #[tokio::main]
/// async fn main() {
/// let start = Instant::now() + Duration::from_millis(50);
/// let mut interval = interval_at(start, Duration::from_millis(10));
///
/// interval.tick().await; // ticks after 50ms
/// interval.tick().await; // ticks after 10ms
/// interval.tick().await; // ticks after 10ms
///
/// // approximately 70ms have elapsed.
/// }
/// ```
</span><span class="attribute">#[track_caller]
</span><span class="kw">pub fn </span>interval_at(start: Instant, period: Duration) -&gt; Interval {
<span class="macro">assert!</span>(period &gt; Duration::new(<span class="number">0</span>, <span class="number">0</span>), <span class="string">&quot;`period` must be non-zero.&quot;</span>);
internal_interval_at(start, period, trace::caller_location())
}
<span class="attribute">#[cfg_attr(not(all(tokio_unstable, feature = <span class="string">&quot;tracing&quot;</span>)), allow(unused_variables))]
</span><span class="kw">fn </span>internal_interval_at(
start: Instant,
period: Duration,
location: <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span><span class="lifetime">&#39;static </span>Location&lt;<span class="lifetime">&#39;static</span>&gt;&gt;,
) -&gt; Interval {
<span class="attribute">#[cfg(all(tokio_unstable, feature = <span class="string">&quot;tracing&quot;</span>))]
</span><span class="kw">let </span>resource_span = {
<span class="kw">let </span>location = location.expect(<span class="string">&quot;should have location if tracing&quot;</span>);
<span class="macro">tracing::trace_span!</span>(
<span class="string">&quot;runtime.resource&quot;</span>,
concrete_type = <span class="string">&quot;Interval&quot;</span>,
kind = <span class="string">&quot;timer&quot;</span>,
loc.file = location.file(),
loc.line = location.line(),
loc.col = location.column(),
)
};
<span class="attribute">#[cfg(all(tokio_unstable, feature = <span class="string">&quot;tracing&quot;</span>))]
</span><span class="kw">let </span>delay = resource_span.in_scope(|| Box::pin(sleep_until(start)));
<span class="attribute">#[cfg(not(all(tokio_unstable, feature = <span class="string">&quot;tracing&quot;</span>)))]
</span><span class="kw">let </span>delay = Box::pin(sleep_until(start));
Interval {
delay,
period,
missed_tick_behavior: Default::default(),
<span class="attribute">#[cfg(all(tokio_unstable, feature = <span class="string">&quot;tracing&quot;</span>))]
</span>resource_span,
}
}
<span class="doccomment">/// Defines the behavior of an [`Interval`] when it misses a tick.
///
/// Sometimes, an [`Interval`]&#39;s tick is missed. For example, consider the
/// following:
///
/// ```
/// use tokio::time::{self, Duration};
/// # async fn task_that_takes_one_to_three_millis() {}
///
/// #[tokio::main]
/// async fn main() {
/// // ticks every 2 milliseconds
/// let mut interval = time::interval(Duration::from_millis(2));
/// for _ in 0..5 {
/// interval.tick().await;
/// // if this takes more than 2 milliseconds, a tick will be delayed
/// task_that_takes_one_to_three_millis().await;
/// }
/// }
/// ```
///
/// Generally, a tick is missed if too much time is spent without calling
/// [`Interval::tick()`].
///
/// By default, when a tick is missed, [`Interval`] fires ticks as quickly as it
/// can until it is &quot;caught up&quot; in time to where it should be.
/// `MissedTickBehavior` can be used to specify a different behavior for
/// [`Interval`] to exhibit. Each variant represents a different strategy.
///
/// Note that because the executor cannot guarantee exact precision with timers,
/// these strategies will only apply when the delay is greater than 5
/// milliseconds.
</span><span class="attribute">#[derive(Debug, Clone, Copy, PartialEq, Eq)]
</span><span class="kw">pub enum </span>MissedTickBehavior {
<span class="doccomment">/// Ticks as fast as possible until caught up.
///
/// When this strategy is used, [`Interval`] schedules ticks &quot;normally&quot; (the
/// same as it would have if the ticks hadn&#39;t been delayed), which results
/// in it firing ticks as fast as possible until it is caught up in time to
/// where it should be. Unlike [`Delay`] and [`Skip`], the ticks yielded
/// when `Burst` is used (the [`Instant`]s that [`tick`](Interval::tick)
/// yields) aren&#39;t different than they would have been if a tick had not
/// been missed. Like [`Skip`], and unlike [`Delay`], the ticks may be
/// shortened.
///
/// This looks something like this:
/// ```text
/// Expected ticks: | 1 | 2 | 3 | 4 | 5 | 6 |
/// Actual ticks: | work -----| delay | work | work | work -| work -----|
/// ```
///
/// In code:
///
/// ```
/// use tokio::time::{interval, Duration};
/// # async fn task_that_takes_200_millis() {}
///
/// # #[tokio::main(flavor = &quot;current_thread&quot;)]
/// # async fn main() {
/// let mut interval = interval(Duration::from_millis(50));
///
/// // First tick resolves immediately after creation
/// interval.tick().await;
///
/// task_that_takes_200_millis().await;
/// // The `Interval` has missed a tick
///
/// // Since we have exceeded our timeout, this will resolve immediately
/// interval.tick().await;
///
/// // Since we are more than 100ms after the start of `interval`, this will
/// // also resolve immediately.
/// interval.tick().await;
///
/// // Also resolves immediately, because it was supposed to resolve at
/// // 150ms after the start of `interval`
/// interval.tick().await;
///
/// // Resolves immediately
/// interval.tick().await;
///
/// // Since we have gotten to 200ms after the start of `interval`, this
/// // will resolve after 50ms
/// interval.tick().await;
/// # }
/// ```
///
/// This is the default behavior when [`Interval`] is created with
/// [`interval`] and [`interval_at`].
///
/// [`Delay`]: MissedTickBehavior::Delay
/// [`Skip`]: MissedTickBehavior::Skip
</span>Burst,
<span class="doccomment">/// Tick at multiples of `period` from when [`tick`] was called, rather than
/// from `start`.
///
/// When this strategy is used and [`Interval`] has missed a tick, instead
/// of scheduling ticks to fire at multiples of `period` from `start` (the
/// time when the first tick was fired), it schedules all future ticks to
/// happen at a regular `period` from the point when [`tick`] was called.
/// Unlike [`Burst`] and [`Skip`], ticks are not shortened, and they aren&#39;t
/// guaranteed to happen at a multiple of `period` from `start` any longer.
///
/// This looks something like this:
/// ```text
/// Expected ticks: | 1 | 2 | 3 | 4 | 5 | 6 |
/// Actual ticks: | work -----| delay | work -----| work -----| work -----|
/// ```
///
/// In code:
///
/// ```
/// use tokio::time::{interval, Duration, MissedTickBehavior};
/// # async fn task_that_takes_more_than_50_millis() {}
///
/// # #[tokio::main(flavor = &quot;current_thread&quot;)]
/// # async fn main() {
/// let mut interval = interval(Duration::from_millis(50));
/// interval.set_missed_tick_behavior(MissedTickBehavior::Delay);
///
/// task_that_takes_more_than_50_millis().await;
/// // The `Interval` has missed a tick
///
/// // Since we have exceeded our timeout, this will resolve immediately
/// interval.tick().await;
///
/// // But this one, rather than also resolving immediately, as might happen
/// // with the `Burst` or `Skip` behaviors, will not resolve until
/// // 50ms after the call to `tick` up above. That is, in `tick`, when we
/// // recognize that we missed a tick, we schedule the next tick to happen
/// // 50ms (or whatever the `period` is) from right then, not from when
/// // were *supposed* to tick
/// interval.tick().await;
/// # }
/// ```
///
/// [`Burst`]: MissedTickBehavior::Burst
/// [`Skip`]: MissedTickBehavior::Skip
/// [`tick`]: Interval::tick
</span>Delay,
<span class="doccomment">/// Skips missed ticks and tick on the next multiple of `period` from
/// `start`.
///
/// When this strategy is used, [`Interval`] schedules the next tick to fire
/// at the next-closest tick that is a multiple of `period` away from
/// `start` (the point where [`Interval`] first ticked). Like [`Burst`], all
/// ticks remain multiples of `period` away from `start`, but unlike
/// [`Burst`], the ticks may not be *one* multiple of `period` away from the
/// last tick. Like [`Delay`], the ticks are no longer the same as they
/// would have been if ticks had not been missed, but unlike [`Delay`], and
/// like [`Burst`], the ticks may be shortened to be less than one `period`
/// away from each other.
///
/// This looks something like this:
/// ```text
/// Expected ticks: | 1 | 2 | 3 | 4 | 5 | 6 |
/// Actual ticks: | work -----| delay | work ---| work -----| work -----|
/// ```
///
/// In code:
///
/// ```
/// use tokio::time::{interval, Duration, MissedTickBehavior};
/// # async fn task_that_takes_75_millis() {}
///
/// # #[tokio::main(flavor = &quot;current_thread&quot;)]
/// # async fn main() {
/// let mut interval = interval(Duration::from_millis(50));
/// interval.set_missed_tick_behavior(MissedTickBehavior::Skip);
///
/// task_that_takes_75_millis().await;
/// // The `Interval` has missed a tick
///
/// // Since we have exceeded our timeout, this will resolve immediately
/// interval.tick().await;
///
/// // This one will resolve after 25ms, 100ms after the start of
/// // `interval`, which is the closest multiple of `period` from the start
/// // of `interval` after the call to `tick` up above.
/// interval.tick().await;
/// # }
/// ```
///
/// [`Burst`]: MissedTickBehavior::Burst
/// [`Delay`]: MissedTickBehavior::Delay
</span>Skip,
}
<span class="kw">impl </span>MissedTickBehavior {
<span class="doccomment">/// If a tick is missed, this method is called to determine when the next tick should happen.
</span><span class="kw">fn </span>next_timeout(<span class="kw-2">&amp;</span><span class="self">self</span>, timeout: Instant, now: Instant, period: Duration) -&gt; Instant {
<span class="kw">match </span><span class="self">self </span>{
<span class="self">Self</span>::Burst =&gt; timeout + period,
<span class="self">Self</span>::Delay =&gt; now + period,
<span class="self">Self</span>::Skip =&gt; {
now + period
- Duration::from_nanos(
((now - timeout).as_nanos() % period.as_nanos())
.try_into()
<span class="comment">// This operation is practically guaranteed not to
// fail, as in order for it to fail, `period` would
// have to be longer than `now - timeout`, and both
// would have to be longer than 584 years.
//
// If it did fail, there&#39;s not a good way to pass
// the error along to the user, so we just panic.
</span>.expect(
<span class="string">&quot;too much time has elapsed since the interval was supposed to tick&quot;</span>,
),
)
}
}
}
}
<span class="kw">impl </span>Default <span class="kw">for </span>MissedTickBehavior {
<span class="doccomment">/// Returns [`MissedTickBehavior::Burst`].
///
/// For most usecases, the [`Burst`] strategy is what is desired.
/// Additionally, to preserve backwards compatibility, the [`Burst`]
/// strategy must be the default. For these reasons,
/// [`MissedTickBehavior::Burst`] is the default for [`MissedTickBehavior`].
/// See [`Burst`] for more details.
///
/// [`Burst`]: MissedTickBehavior::Burst
</span><span class="kw">fn </span>default() -&gt; <span class="self">Self </span>{
<span class="self">Self</span>::Burst
}
}
<span class="doccomment">/// Interval returned by [`interval`] and [`interval_at`].
///
/// This type allows you to wait on a sequence of instants with a certain
/// duration between each instant. Unlike calling [`sleep`] in a loop, this lets
/// you count the time spent between the calls to [`sleep`] as well.
///
/// An `Interval` can be turned into a `Stream` with [`IntervalStream`].
///
/// [`IntervalStream`]: https://docs.rs/tokio-stream/latest/tokio_stream/wrappers/struct.IntervalStream.html
/// [`sleep`]: crate::time::sleep
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">pub struct </span>Interval {
<span class="doccomment">/// Future that completes the next time the `Interval` yields a value.
</span>delay: Pin&lt;Box&lt;Sleep&gt;&gt;,
<span class="doccomment">/// The duration between values yielded by `Interval`.
</span>period: Duration,
<span class="doccomment">/// The strategy `Interval` should use when a tick is missed.
</span>missed_tick_behavior: MissedTickBehavior,
<span class="attribute">#[cfg(all(tokio_unstable, feature = <span class="string">&quot;tracing&quot;</span>))]
</span>resource_span: tracing::Span,
}
<span class="kw">impl </span>Interval {
<span class="doccomment">/// Completes when the next instant in the interval has been reached.
///
/// # Cancel safety
///
/// This method is cancellation safe. If `tick` is used as the branch in a `tokio::select!` and
/// another branch completes first, then no tick has been consumed.
///
/// # Examples
///
/// ```
/// use tokio::time;
///
/// use std::time::Duration;
///
/// #[tokio::main]
/// async fn main() {
/// let mut interval = time::interval(Duration::from_millis(10));
///
/// interval.tick().await;
/// // approximately 0ms have elapsed. The first tick completes immediately.
/// interval.tick().await;
/// interval.tick().await;
///
/// // approximately 20ms have elapsed.
/// }
/// ```
</span><span class="kw">pub async fn </span>tick(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; Instant {
<span class="attribute">#[cfg(all(tokio_unstable, feature = <span class="string">&quot;tracing&quot;</span>))]
</span><span class="kw">let </span>resource_span = <span class="self">self</span>.resource_span.clone();
<span class="attribute">#[cfg(all(tokio_unstable, feature = <span class="string">&quot;tracing&quot;</span>))]
</span><span class="kw">let </span>instant = trace::async_op(
|| poll_fn(|cx| <span class="self">self</span>.poll_tick(cx)),
resource_span,
<span class="string">&quot;Interval::tick&quot;</span>,
<span class="string">&quot;poll_tick&quot;</span>,
<span class="bool-val">false</span>,
);
<span class="attribute">#[cfg(not(all(tokio_unstable, feature = <span class="string">&quot;tracing&quot;</span>)))]
</span><span class="kw">let </span>instant = poll_fn(|cx| <span class="self">self</span>.poll_tick(cx));
instant.<span class="kw">await
</span>}
<span class="doccomment">/// Polls for the next instant in the interval to be reached.
///
/// This method can return the following values:
///
/// * `Poll::Pending` if the next instant has not yet been reached.
/// * `Poll::Ready(instant)` if the next instant has been reached.
///
/// When this method returns `Poll::Pending`, the current task is scheduled
/// to receive a wakeup when the instant has elapsed. Note that on multiple
/// calls to `poll_tick`, only the [`Waker`](std::task::Waker) from the
/// [`Context`] passed to the most recent call is scheduled to receive a
/// wakeup.
</span><span class="kw">pub fn </span>poll_tick(<span class="kw-2">&amp;mut </span><span class="self">self</span>, cx: <span class="kw-2">&amp;mut </span>Context&lt;<span class="lifetime">&#39;_</span>&gt;) -&gt; Poll&lt;Instant&gt; {
<span class="comment">// Wait for the delay to be done
</span><span class="macro">ready!</span>(Pin::new(<span class="kw-2">&amp;mut </span><span class="self">self</span>.delay).poll(cx));
<span class="comment">// Get the time when we were scheduled to tick
</span><span class="kw">let </span>timeout = <span class="self">self</span>.delay.deadline();
<span class="kw">let </span>now = Instant::now();
<span class="comment">// If a tick was not missed, and thus we are being called before the
// next tick is due, just schedule the next tick normally, one `period`
// after `timeout`
//
// However, if a tick took excessively long and we are now behind,
// schedule the next tick according to how the user specified with
// `MissedTickBehavior`
</span><span class="kw">let </span>next = <span class="kw">if </span>now &gt; timeout + Duration::from_millis(<span class="number">5</span>) {
<span class="self">self</span>.missed_tick_behavior
.next_timeout(timeout, now, <span class="self">self</span>.period)
} <span class="kw">else </span>{
timeout + <span class="self">self</span>.period
};
<span class="self">self</span>.delay.as_mut().reset(next);
<span class="comment">// Return the time when we were scheduled to tick
</span>Poll::Ready(timeout)
}
<span class="doccomment">/// Resets the interval to complete one period after the current time.
///
/// This method ignores [`MissedTickBehavior`] strategy.
///
/// # Examples
///
/// ```
/// use tokio::time;
///
/// use std::time::Duration;
///
/// #[tokio::main]
/// async fn main() {
/// let mut interval = time::interval(Duration::from_millis(100));
///
/// interval.tick().await;
///
/// time::sleep(Duration::from_millis(50)).await;
/// interval.reset();
///
/// interval.tick().await;
/// interval.tick().await;
///
/// // approximately 250ms have elapsed.
/// }
/// ```
</span><span class="kw">pub fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="self">self</span>.delay.as_mut().reset(Instant::now() + <span class="self">self</span>.period);
}
<span class="doccomment">/// Returns the [`MissedTickBehavior`] strategy currently being used.
</span><span class="kw">pub fn </span>missed_tick_behavior(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; MissedTickBehavior {
<span class="self">self</span>.missed_tick_behavior
}
<span class="doccomment">/// Sets the [`MissedTickBehavior`] strategy that should be used.
</span><span class="kw">pub fn </span>set_missed_tick_behavior(<span class="kw-2">&amp;mut </span><span class="self">self</span>, behavior: MissedTickBehavior) {
<span class="self">self</span>.missed_tick_behavior = behavior;
}
<span class="doccomment">/// Returns the period of the interval.
</span><span class="kw">pub fn </span>period(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Duration {
<span class="self">self</span>.period
}
}
</code></pre></div>
</section></div></main><div id="rustdoc-vars" data-root-path="../../../" data-current-crate="tokio" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0-nightly (5c8bff74b 2022-10-21)" ></div></body></html>