use super::{
WorkflowContextKey, WorkflowContextValueStore, WorkflowRandomState, WorkflowRandomStream,
WorkflowRandomStreamSource,
};
use std::{
cell::RefCell,
rc::Rc,
time::{Duration, SystemTime},
};
use temporalio_common_wasm::{
Memo, Priority, RetryPolicy, WorkflowExecution,
data_converters::{PayloadConverter, SerializationContextData, WorkflowSerializationContext},
protos::coresdk::{
common::NamespacedWorkflowExecution, workflow_activation::InitializeWorkflow,
},
search_attributes::SearchAttributes,
};
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct WorkflowContextView {
raw: InitializeWorkflow,
namespace: String,
task_queue: String,
run_id: String,
payload_converter: PayloadConverter,
requires_replay_safety: bool,
workflow_random: Option<Rc<RefCell<WorkflowRandomState>>>,
context_values: WorkflowContextValueStore,
}
impl WorkflowContextView {
pub(crate) fn new(
namespace: String,
task_queue: String,
run_id: String,
raw: InitializeWorkflow,
payload_converter: PayloadConverter,
requires_replay_safety: bool,
workflow_random: Option<Rc<RefCell<WorkflowRandomState>>>,
) -> Self {
Self {
raw,
namespace,
task_queue,
run_id,
payload_converter,
requires_replay_safety,
workflow_random,
context_values: WorkflowContextValueStore::default(),
}
}
pub(super) fn with_context_values(mut self, context_values: WorkflowContextValueStore) -> Self {
self.context_values = context_values;
self
}
pub(super) fn into_parts(self) -> (String, String, String, InitializeWorkflow) {
(self.namespace, self.task_queue, self.run_id, self.raw)
}
pub fn workflow_id(&self) -> &str {
&self.raw.workflow_id
}
pub fn run_id(&self) -> &str {
&self.run_id
}
pub fn workflow_type(&self) -> &str {
&self.raw.workflow_type
}
pub fn task_queue(&self) -> &str {
&self.task_queue
}
pub fn namespace(&self) -> &str {
&self.namespace
}
pub fn attempt(&self) -> u32 {
self.raw.attempt as u32
}
pub fn first_execution_run_id(&self) -> &str {
&self.raw.first_execution_run_id
}
pub fn continued_from_run_id(&self) -> Option<&str> {
(!self.raw.continued_from_execution_run_id.is_empty())
.then_some(self.raw.continued_from_execution_run_id.as_str())
}
pub fn start_time(&self) -> Option<SystemTime> {
self.raw.start_time.and_then(|time| time.try_into().ok())
}
pub fn execution_timeout(&self) -> Option<Duration> {
self.raw
.workflow_execution_timeout
.and_then(|timeout| timeout.try_into().ok())
}
pub fn run_timeout(&self) -> Option<Duration> {
self.raw
.workflow_run_timeout
.and_then(|timeout| timeout.try_into().ok())
}
pub fn task_timeout(&self) -> Option<Duration> {
self.raw
.workflow_task_timeout
.and_then(|timeout| timeout.try_into().ok())
}
pub fn parent(&self) -> Option<NamespacedWorkflowInfo> {
self.raw
.parent_workflow_info
.clone()
.map(NamespacedWorkflowInfo::from_raw)
}
pub fn root(&self) -> Option<WorkflowExecution> {
self.raw.root_workflow.clone().map(Into::into)
}
pub fn retry_policy(&self) -> Option<RetryPolicy> {
self.raw.retry_policy.clone().map(Into::into)
}
pub fn cron_schedule(&self) -> Option<&str> {
(!self.raw.cron_schedule.is_empty()).then_some(self.raw.cron_schedule.as_str())
}
pub fn priority(&self) -> Priority {
self.raw.priority.clone().unwrap_or_default().into()
}
pub fn memo(&self) -> Memo {
Memo::from_raw(
self.raw.memo.clone(),
self.payload_converter.clone(),
SerializationContextData::Workflow(WorkflowSerializationContext::new()),
)
}
pub fn search_attributes(&self) -> Option<SearchAttributes> {
self.raw
.search_attributes
.as_ref()
.map(SearchAttributes::from_proto)
}
pub fn context_value<K: WorkflowContextKey>(&self) -> Option<Rc<K::Value>> {
self.context_values.context_value::<K>()
}
#[allow(
dead_code,
reason = "used by SDK-provided interceptors built separately from this change"
)]
pub(crate) fn random_stream(&self, name: impl Into<String>) -> WorkflowRandomStream {
let source = if self.requires_replay_safety {
WorkflowRandomStreamSource::Workflow(
self.workflow_random
.clone()
.expect("replay-safe context views must have workflow randomness"),
)
} else {
super::system_random_stream_source()
};
WorkflowRandomStream {
source,
name: name.into(),
}
}
pub fn raw(&self) -> &InitializeWorkflow {
&self.raw
}
pub fn into_raw(self) -> InitializeWorkflow {
self.raw
}
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct NamespacedWorkflowInfo {
raw: NamespacedWorkflowExecution,
}
impl NamespacedWorkflowInfo {
fn from_raw(raw: NamespacedWorkflowExecution) -> Self {
Self { raw }
}
pub fn workflow_id(&self) -> &str {
&self.raw.workflow_id
}
pub fn run_id(&self) -> &str {
&self.raw.run_id
}
pub fn namespace(&self) -> &str {
&self.raw.namespace
}
pub fn raw(&self) -> &NamespacedWorkflowExecution {
&self.raw
}
pub fn into_raw(self) -> NamespacedWorkflowExecution {
self.raw
}
}