blob: 4e96cf8313641c2a360e74b76e1ed5d7fbc803ca [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="Abstracting over accessing parts of stored value."><meta name="keywords" content="rust, rustlang, rust-lang, access"><title>arc_swap::access - Rust</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="../../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 mod"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle">&#9776;</button><a class="sidebar-logo" href="../../arc_swap/index.html"><div class="logo-container"><img class="rust-logo" src="../../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../arc_swap/index.html"><div class="logo-container"><img class="rust-logo" src="../../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">Module access</a></h2><div class="sidebar-elems"><section><ul class="block"><li><a href="#structs">Structs</a></li><li><a href="#traits">Traits</a></li></ul></section></div></nav><main><div class="width-limiter"><nav class="sub"><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="main-heading"><h1 class="fqn">Module <a href="../index.html">arc_swap</a>::<wbr><a class="mod" href="#">access</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../../src/arc_swap/access.rs.html#1-544">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">&#x2212;</span>]</a></span></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Abstracting over accessing parts of stored value.</p>
<p>Sometimes, there’s a big globalish data structure (like a configuration for the whole program).
Then there are parts of the program that need access to up-to-date version of their <em>part</em> of
the configuration, but for reasons of code separation and reusability, it is not desirable to
pass the whole configuration to each of the parts.</p>
<p>This module provides means to grant the parts access to the relevant subsets of such global
data structure while masking the fact it is part of the bigger whole from the component.</p>
<p>Note that the <a href="../cache/index.html" title="crate::cache"><code>cache</code></a> module has its own <a href="../cache/trait.Access.html" title="crate::cache::Access"><code>Access</code></a> trait
that serves a similar purpose, but with cached access. The signatures are different, therefore
an incompatible trait.</p>
<h2 id="the-general-idea"><a href="#the-general-idea">The general idea</a></h2>
<p>Each part of the code accepts generic <a href="trait.Access.html" title="Access"><code>Access&lt;T&gt;</code></a> for the <code>T</code> of its interest. This
provides means to load current version of the structure behind the scenes and get only the
relevant part, without knowing what the big structure is.</p>
<p>For technical reasons, the <a href="trait.Access.html" title="Access"><code>Access</code></a> trait is not object safe. If type erasure is desired, it
is possible use the <a href="trait.DynAccess.html" title="crate::access::DynAccess"><code>DynAccess</code></a> instead, which is object safe, but
slightly slower.</p>
<p>For some cases, it is possible to use <a href="../struct.ArcSwapAny.html#method.map" title="ArcSwapAny::map"><code>ArcSwapAny::map</code></a>. If that is not flexible enough, the
<a href="struct.Map.html" title="Map"><code>Map</code></a> type can be created directly.</p>
<p>Note that the <a href="trait.Access.html" title="Access"><code>Access</code></a> trait is also implemented for <a href="../struct.ArcSwapAny.html" title="ArcSwapAny"><code>ArcSwapAny</code></a> itself. Additionally,
there’s the <a href="struct.Constant.html" title="crate::access::Constant"><code>Constant</code></a> helper type, which is useful mostly for
testing (it doesn’t allow reloading).</p>
<h2 id="performance"><a href="#performance">Performance</a></h2>
<p>In general, these utilities use <a href="../struct.ArcSwapAny.html#method.load" title="ArcSwapAny::load"><code>ArcSwapAny::load</code></a> internally and then apply the provided
transformation. This has several consequences:</p>
<ul>
<li>Limitations of the <a href="../struct.ArcSwapAny.html#method.load" title="ArcSwapAny::load"><code>load</code></a> apply ‒ including the recommendation to not
hold the returned guard object for too long, but long enough to get consistency.</li>
<li>The transformation should be cheap ‒ optimally just borrowing into the structure.</li>
</ul>
<h2 id="examples"><a href="#examples">Examples</a></h2>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>std::sync::Arc;
<span class="kw">use </span>std::thread::{<span class="self">self</span>, JoinHandle};
<span class="kw">use </span>std::time::Duration;
<span class="kw">use </span>arc_swap::ArcSwap;
<span class="kw">use </span>arc_swap::access::{Access, Constant, Map};
<span class="kw">fn </span>work_with_usize&lt;A: Access&lt;usize&gt; + Send + <span class="lifetime">&#39;static</span>&gt;(a: A) -&gt; JoinHandle&lt;()&gt; {
thread::spawn(<span class="kw">move </span>|| {
<span class="kw">let </span><span class="kw-2">mut </span>value = <span class="number">0</span>;
<span class="kw">while </span>value != <span class="number">42 </span>{
<span class="kw">let </span>guard = a.load();
value = <span class="kw-2">*</span>guard;
<span class="macro">println!</span>(<span class="string">&quot;{}&quot;</span>, value);
<span class="comment">// Not strictly necessary, but dropping the guard can free some resources, like
// slots for tracking what values are still in use. We do it before the sleeping,
// not at the end of the scope.
</span>drop(guard);
thread::sleep(Duration::from_millis(<span class="number">50</span>));
}
})
}
<span class="comment">// Passing the whole thing directly
// (If we kept another Arc to it, we could change the value behind the scenes)
</span>work_with_usize(Arc::new(ArcSwap::from_pointee(<span class="number">42</span>))).join().unwrap();
<span class="comment">// Passing a subset of a structure
</span><span class="kw">struct </span>Cfg {
value: usize,
}
<span class="kw">let </span>cfg = Arc::new(ArcSwap::from_pointee(Cfg { value: <span class="number">0 </span>}));
<span class="kw">let </span>thread = work_with_usize(Map::new(Arc::clone(<span class="kw-2">&amp;</span>cfg), |cfg: <span class="kw-2">&amp;</span>Cfg| <span class="kw-2">&amp;</span>cfg.value));
cfg.store(Arc::new(Cfg { value: <span class="number">42 </span>}));
thread.join().unwrap();
<span class="comment">// Passing a constant that can&#39;t change. Useful mostly for testing purposes.
</span>work_with_usize(Constant(<span class="number">42</span>)).join().unwrap();</code></pre></div>
</div></details><h2 id="structs" class="small-section-header"><a href="#structs">Structs</a></h2><div class="item-table"><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.AccessConvert.html" title="arc_swap::access::AccessConvert struct">AccessConvert</a></div><div class="item-right docblock-short"><a href="trait.DynAccess.html" title="DynAccess">DynAccess</a> to <a href="trait.Access.html" title="Access">Access</a> wrapper.</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.Constant.html" title="arc_swap::access::Constant struct">Constant</a></div><div class="item-right docblock-short">Access to an constant.</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.Map.html" title="arc_swap::access::Map struct">Map</a></div><div class="item-right docblock-short">An adaptor to provide access to a part of larger structure.</div></div></div><h2 id="traits" class="small-section-header"><a href="#traits">Traits</a></h2><div class="item-table"><div class="item-row"><div class="item-left module-item"><a class="trait" href="trait.Access.html" title="arc_swap::access::Access trait">Access</a></div><div class="item-right docblock-short">Abstracts over ways code can get access to a value of type <code>T</code>.</div></div><div class="item-row"><div class="item-left module-item"><a class="trait" href="trait.DynAccess.html" title="arc_swap::access::DynAccess trait">DynAccess</a></div><div class="item-right docblock-short">An object-safe version of the <a href="trait.Access.html" title="Access"><code>Access</code></a> trait.</div></div></div></section></div></main><div id="rustdoc-vars" data-root-path="../../" data-current-crate="arc_swap" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0-nightly (5c8bff74b 2022-10-21)" ></div></body></html>