Skip to main content

harmos_runtime/state/
managed.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10/* === Modules === */
11
12/* === Re-Exports === */
13
14/* === Imports === */
15
16// Standard Library Imports
17use std::sync::Arc;
18
19// Third Party Imports
20
21// Local Imports
22use super::{At, Error, Origin, Position, TrackedState};
23use crate::Application;
24
25/* === Constants === */
26
27/* === Macros === */
28
29/* === Type Aliases === */
30
31/* === Structs === */
32
33pub struct ManagedState<A: Application> {
34    tracked: Arc<TrackedState<A>>,
35}
36
37/* === Enums === */
38
39/* === Traits === */
40
41/* === Implementations === */
42
43impl<A: Application> ManagedState<A> {
44    pub(super) fn new(tracked: Arc<TrackedState<A>>) -> Self {
45        Self { tracked }
46    }
47
48    pub async fn read<R>(&self, read: impl FnOnce(&A::State) -> R) -> Result<At<R>, Error> {
49        if self.tracked.poisoned() {
50            return Err(self.tracked.unavailable());
51        }
52        let state = self.tracked.state.read().await;
53        // The Writer May Have Panicked While This Reader Awaited The Lock.
54        if self.tracked.poisoned() {
55            return Err(self.tracked.unavailable());
56        }
57
58        Ok(At { value: read(&state.value), position: state.position })
59    }
60
61    pub async fn at(&self, origin: Origin<A::State>, at: Position) -> Result<At<A::State>, Error> {
62        if self.tracked.poisoned() {
63            return Err(self.tracked.unavailable());
64        }
65
66        {
67            let tail = self.tracked.tail.read().await;
68            if tail.splits_commit(at) || tail.splits_commit(origin.position) {
69                return Err(Error::IncompleteCommit);
70            }
71        }
72        self.tracked.reads.state(origin, at).await
73    }
74}
75
76impl<A: Application> Clone for ManagedState<A> {
77    fn clone(&self) -> Self {
78        Self::new(Arc::clone(&self.tracked))
79    }
80}
81
82/* === Public Functions === */
83
84/* === Private Functions === */
85
86/* === Tests === */