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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
use derive_more::Display;
use spacetimedb_lib::Address;
use spacetimedb_metrics::impl_prometheusvalue_string;
use spacetimedb_metrics::typed_prometheus::AsPrometheusLabel;
/// Represents the context under which a database runtime method is executed.
/// In particular it provides details about the currently executing txn to runtime operations.
/// More generally it acts as a container for information that database operations may require to function correctly.
#[derive(Default)]
pub struct ExecutionContext<'a> {
/// The database on which a transaction is being executed.
database: Address,
/// The reducer from which the current transaction originated.
reducer: Option<&'a str>,
/// The type of workload that is being executed.
workload: WorkloadType,
}
/// Classifies a transaction according to its workload.
/// A transaction can be executing a reducer.
/// It can be used to satisfy a one-off sql query or subscription.
/// It can also be an internal operation that is not associated with a reducer or sql request.
#[derive(Clone, Copy, Display, Hash, PartialEq, Eq)]
pub enum WorkloadType {
Reducer,
Sql,
Subscribe,
Update,
Internal,
}
impl_prometheusvalue_string!(WorkloadType);
impl Default for WorkloadType {
fn default() -> Self {
Self::Internal
}
}
impl<'a> ExecutionContext<'a> {
/// Returns an [ExecutionContext] for a reducer transaction.
pub fn reducer(database: Address, name: &'a str) -> Self {
Self {
database,
reducer: Some(name),
workload: WorkloadType::Reducer,
}
}
/// Returns an [ExecutionContext] for a one-off sql query.
pub fn sql(database: Address) -> Self {
Self {
database,
reducer: None,
workload: WorkloadType::Sql,
}
}
/// Returns an [ExecutionContext] for an initial subscribe call.
pub fn subscribe(database: Address) -> Self {
Self {
database,
reducer: None,
workload: WorkloadType::Subscribe,
}
}
/// Returns an [ExecutionContext] for a subscription update.
pub fn incremental_update(database: Address) -> Self {
Self {
database,
reducer: None,
workload: WorkloadType::Update,
}
}
/// Returns an [ExecutionContext] for an internal database operation.
pub fn internal(database: Address) -> Self {
Self {
database,
reducer: None,
workload: WorkloadType::Internal,
}
}
/// Returns the address of the database on which we are operating.
#[inline]
pub fn database(&self) -> Address {
self.database
}
/// If this is a reducer context, returns the name of the reducer.
#[inline]
pub fn reducer_name(&self) -> &str {
self.reducer.unwrap_or_default()
}
/// Returns the type of workload that is being executed.
#[inline]
pub fn workload(&self) -> WorkloadType {
self.workload
}
}