Macro zng_app_context::app_local

source ·
macro_rules! app_local {
    ($(
        $(#[$meta:meta])*
        $vis:vis static $IDENT:ident : $T:ty = $(const { $init_const:expr })? $($init:expr)?;
    )+) => { ... };
}
Expand description

Declares new app local variable.

An app local is a static variable that is declared using the same syntax as thread_local!, but can be accessed by any thread in the app. In apps that only run once per process it compiles down to the equivalent of a static LOCAL: RwLock<T> = const; or static LOCAL: RwLock<Option<T>> that initializes on first usage. In test builds with multiple parallel apps it compiles to a switching storage that provides a different value depending on what app is running in the current thread.

See AppLocal<T> for more details.

§Multi App

If the crate is compiled with the "multi_app" feature a different internal implementation is used that supports multiple apps, either running in parallel in different threads or one after the other. This backing implementation has some small overhead, but usually you only want multiple app instances per-process when running tests.

The lifetime of "multi_app" locals is also more limited, trying to use an app-local before starting to build an app will panic, the app-local value will be dropped when the app is dropped. Without the "multi_app" feature the app-locals can be used at any point before or after the app lifetime, values are not explicitly dropped, just unloaded with the process.

§Const

The initialization expression can be wrapped in a const { .. } block, if the "multi_app" feature is not enabled a faster implementation is used that is equivalent to a direct static LOCAL: RwLock<T> in terms of performance.

Note that this syntax is available even if the "multi_app" feature is enabled, the expression must be const either way, but with the feature the same dynamic implementation is used.

Note that const initialization does not automatically convert the value into the static type.

§Examples

The example below declares two app locals, note that BAR init value automatically converts into the app local type.

app_local! {
    /// A public documented value.
    pub static FOO: u8 = const { 10u8 };

    // A private value.
    static BAR: String = "Into!";
}

let app = LocalContext::start_app(AppId::new_unique());

assert_eq!(10, FOO.get());

Also note that an app context is started before the first use, in multi_app builds trying to use an app local in a thread not owned by an app panics.