22#![ allow( clippy:: upper_case_acronyms) ]
33
44//! This crate provides a basis for creating new Temporal SDKs without completely starting from
5- //! scratch
5+ //! scratch.
6+ //!
7+ //! ## Optional features
8+ //! - `antithesis_assertions`: Enables integration with Antithesis' Rust SDK. When active, core
9+ //! initialization calls `antithesis_sdk::antithesis_init` and critical invariants emit
10+ //! Antithesis assertions to aid fuzzing campaigns.
611
712#[ cfg( test) ]
813#[ macro_use]
@@ -12,6 +17,7 @@ extern crate tracing;
1217extern crate core;
1318
1419mod abstractions;
20+ mod antithesis;
1521#[ cfg( feature = "debug-plugin" ) ]
1622pub mod debug_client;
1723#[ cfg( feature = "ephemeral-server" ) ]
@@ -86,8 +92,18 @@ pub fn init_worker<CT>(
8692where
8793 CT : Into < sealed:: AnyClient > ,
8894{
95+ crate :: antithesis:: ensure_init ( ) ;
8996 let namespace = worker_config. namespace . clone ( ) ;
9097 if namespace. is_empty ( ) {
98+ #[ cfg( feature = "antithesis_assertions" ) ]
99+ crate :: antithesis:: assert_always_failure (
100+ "worker namespace must not be empty" ,
101+ :: serde_json:: json!( {
102+ "namespace" : namespace. clone( ) ,
103+ "task_queue" : worker_config. task_queue. clone( ) ,
104+ "has_identity_override" : worker_config. client_identity_override. is_some( ) ,
105+ } ) ,
106+ ) ;
91107 bail ! ( "Worker namespace cannot be empty" ) ;
92108 }
93109
@@ -103,6 +119,14 @@ where
103119 let sticky_q = sticky_q_name_for_worker ( & client_ident, worker_config. max_cached_workflows ) ;
104120
105121 if client_ident. is_empty ( ) {
122+ #[ cfg( feature = "antithesis_assertions" ) ]
123+ crate :: antithesis:: assert_always_failure (
124+ "client identity must not be empty" ,
125+ :: serde_json:: json!( {
126+ "namespace" : namespace. clone( ) ,
127+ "task_queue" : worker_config. task_queue. clone( ) ,
128+ } ) ,
129+ ) ;
106130 bail ! ( "Client identity cannot be empty. Either lang or user should be setting this value" ) ;
107131 }
108132
@@ -132,6 +156,7 @@ pub fn init_replay_worker<I>(rwi: ReplayWorkerInput<I>) -> Result<Worker, anyhow
132156where
133157 I : Stream < Item = HistoryForReplay > + Send + ' static ,
134158{
159+ crate :: antithesis:: ensure_init ( ) ;
135160 info ! (
136161 task_queue = rwi. config. task_queue. as_str( ) ,
137162 "Registering replay worker"
@@ -290,6 +315,7 @@ impl CoreRuntime {
290315 where
291316 F : Fn ( ) + Send + Sync + ' static ,
292317 {
318+ crate :: antithesis:: ensure_init ( ) ;
293319 let telemetry = telemetry_init ( runtime_options. telemetry_options ) ?;
294320 let subscriber = telemetry. trace_subscriber ( ) ;
295321 let runtime = tokio_builder
@@ -317,6 +343,7 @@ impl CoreRuntime {
317343 /// # Panics
318344 /// If there is no currently active Tokio runtime
319345 pub fn new_assume_tokio ( runtime_options : RuntimeOptions ) -> Result < Self , anyhow:: Error > {
346+ crate :: antithesis:: ensure_init ( ) ;
320347 let telemetry = telemetry_init ( runtime_options. telemetry_options ) ?;
321348 Ok ( Self :: new_assume_tokio_initialized_telem (
322349 telemetry,
@@ -333,6 +360,7 @@ impl CoreRuntime {
333360 telemetry : TelemetryInstance ,
334361 heartbeat_interval : Option < Duration > ,
335362 ) -> Self {
363+ crate :: antithesis:: ensure_init ( ) ;
336364 let runtime_handle = tokio:: runtime:: Handle :: current ( ) ;
337365 if let Some ( sub) = telemetry. trace_subscriber ( ) {
338366 set_trace_subscriber_for_current_thread ( sub) ;
0 commit comments