1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use std::sync::Arc;

use crate::error::RuntimeError;
use crate::resource::Resource;
use crate::symbol::SymbolRef;

pub use serde_yaml::Value as DriverParams;

pub trait DriverRoot: Send + Sync {
    fn get(&self, symbol: SymbolRef<'_>) -> Result<ArcDriver, RuntimeError>;
}

pub type ArcDriver = Arc<dyn Driver>;

pub trait Driver
where
    Self: Send + Sync,
{
    #[allow(unused_variables)]
    fn call(&self, func: &str, value: &Resource) -> Result<(), RuntimeError> {
        RuntimeError::unimplemented()
    }

    #[allow(unused_variables)]
    fn with(&self, value: &Resource) -> Result<Option<ArcDriver>, RuntimeError> {
        Ok(None)
    }

    /// Load the driver's current state.
    ///
    /// If there is a shortage of physical resources, hibernate drivers that are not needed.
    fn status(&self) -> Result<DriverState, RuntimeError>;

    /// Hibernate the driver.
    ///
    /// The hibernating driver must unload the heavy data from memory and be able to reload it in the wake.
    fn hibernate(&self) -> Result<(), RuntimeError> {
        Ok(())
    }

    /// Wake the hibernating driver.
    ///
    /// note: This function will **never** be called if it is already awake.
    fn wake_up(&self) -> Result<(), RuntimeError> {
        Ok(())
    }

    /// Inform the driver that a work will use it.
    fn enter(&self) -> Result<(), RuntimeError> {
        Ok(())
    }

    /// Inform the driver that the work is completed.
    fn exit(&self) -> Result<(), RuntimeError> {
        Ok(())
    }
}

pub enum DriverState {
    /// Doing nothing
    Idle,
    /// Doing something
    Running(DriverRunningState),
    /// Doing nothing but not available immediately
    Hibernated,
}

pub enum DriverRunningState {
    /// Doing something, but not critical
    Lazy,
    /// Doing something, OS interference is not a burden.
    Normal,
    /// Doing something, OS interference is burdensome
    Busy,
}

impl Default for DriverRunningState {
    fn default() -> Self {
        Self::Normal
    }
}