@@ -155,6 +155,7 @@ pub struct Client {
155155 init_state : Arc < AtomicUsize > ,
156156 started : AtomicBool ,
157157 offline : bool ,
158+ daemon_mode : bool ,
158159 sdk_key : String ,
159160 shutdown_broadcast : broadcast:: Sender < ( ) > ,
160161 runtime : RwLock < Option < Runtime > > ,
@@ -165,6 +166,8 @@ impl Client {
165166 pub fn build ( config : Config ) -> Result < Self , BuildError > {
166167 if config. offline ( ) {
167168 info ! ( "Started LaunchDarkly Client in offline mode" ) ;
169+ } else if config. daemon_mode ( ) {
170+ info ! ( "Started LaunchDarkly Client in daemon mode" ) ;
168171 }
169172
170173 let tags = config. application_tag ( ) ;
@@ -210,6 +213,7 @@ impl Client {
210213 init_state : Arc :: new ( AtomicUsize :: new ( ClientInitState :: Initializing as usize ) ) ,
211214 started : AtomicBool :: new ( false ) ,
212215 offline : config. offline ( ) ,
216+ daemon_mode : config. daemon_mode ( ) ,
213217 sdk_key : config. sdk_key ( ) . into ( ) ,
214218 shutdown_broadcast : shutdown_tx,
215219 runtime : RwLock :: new ( None ) ,
@@ -297,7 +301,7 @@ impl Client {
297301 }
298302
299303 async fn initialized_async_internal ( & self ) -> bool {
300- if self . offline {
304+ if self . offline || self . daemon_mode {
301305 return true ;
302306 }
303307
@@ -316,7 +320,9 @@ impl Client {
316320 /// In the case of unrecoverable errors in establishing a connection it is possible for the
317321 /// SDK to never become initialized.
318322 pub fn initialized ( & self ) -> bool {
319- self . offline || ClientInitState :: Initialized == self . init_state . load ( Ordering :: SeqCst )
323+ self . offline
324+ || self . daemon_mode
325+ || ClientInitState :: Initialized == self . init_state . load ( Ordering :: SeqCst )
320326 }
321327
322328 /// Close shuts down the LaunchDarkly client. After calling this, the LaunchDarkly client
@@ -872,7 +878,7 @@ mod tests {
872878
873879 #[ tokio:: test]
874880 async fn client_asynchronously_initializes ( ) {
875- let ( client, _event_rx) = make_mocked_client_with_delay ( 1000 , false ) ;
881+ let ( client, _event_rx) = make_mocked_client_with_delay ( 1000 , false , false ) ;
876882 client. start_with_default_executor ( ) ;
877883
878884 let now = Instant :: now ( ) ;
@@ -885,7 +891,7 @@ mod tests {
885891
886892 #[ tokio:: test]
887893 async fn client_asynchronously_initializes_within_timeout ( ) {
888- let ( client, _event_rx) = make_mocked_client_with_delay ( 1000 , false ) ;
894+ let ( client, _event_rx) = make_mocked_client_with_delay ( 1000 , false , false ) ;
889895 client. start_with_default_executor ( ) ;
890896
891897 let now = Instant :: now ( ) ;
@@ -900,7 +906,7 @@ mod tests {
900906
901907 #[ tokio:: test]
902908 async fn client_asynchronously_initializes_slower_than_timeout ( ) {
903- let ( client, _event_rx) = make_mocked_client_with_delay ( 2000 , false ) ;
909+ let ( client, _event_rx) = make_mocked_client_with_delay ( 2000 , false , false ) ;
904910 client. start_with_default_executor ( ) ;
905911
906912 let now = Instant :: now ( ) ;
@@ -915,7 +921,23 @@ mod tests {
915921
916922 #[ tokio:: test]
917923 async fn client_initializes_immediately_in_offline_mode ( ) {
918- let ( client, _event_rx) = make_mocked_client_with_delay ( 1000 , true ) ;
924+ let ( client, _event_rx) = make_mocked_client_with_delay ( 1000 , true , false ) ;
925+ client. start_with_default_executor ( ) ;
926+
927+ assert ! ( client. initialized( ) ) ;
928+
929+ let now = Instant :: now ( ) ;
930+ let initialized = client
931+ . wait_for_initialization ( Duration :: from_millis ( 2000 ) )
932+ . await ;
933+ let elapsed_time = now. elapsed ( ) ;
934+ assert_eq ! ( initialized, Some ( true ) ) ;
935+ assert ! ( elapsed_time. as_millis( ) < 500 )
936+ }
937+
938+ #[ tokio:: test]
939+ async fn client_initializes_immediately_in_daemon_mode ( ) {
940+ let ( client, _event_rx) = make_mocked_client_with_delay ( 1000 , false , true ) ;
919941 client. start_with_default_executor ( ) ;
920942
921943 assert ! ( client. initialized( ) ) ;
@@ -1393,6 +1415,30 @@ mod tests {
13931415 assert_eq ! ( event_rx. iter( ) . count( ) , 0 ) ;
13941416 }
13951417
1418+ #[ test]
1419+ fn variation_detail_handles_daemon_mode ( ) {
1420+ let ( client, event_rx) = make_mocked_client_with_delay ( 1000 , false , true ) ;
1421+ client. start_with_default_executor ( ) ;
1422+
1423+ let context = ContextBuilder :: new ( "bob" )
1424+ . build ( )
1425+ . expect ( "Failed to create context" ) ;
1426+
1427+ let detail = client. variation_detail ( & context, "myFlag" , FlagValue :: Bool ( false ) ) ;
1428+
1429+ assert ! ( !detail. value. unwrap( ) . as_bool( ) . unwrap( ) ) ;
1430+ assert ! ( matches!(
1431+ detail. reason,
1432+ Reason :: Error {
1433+ error: eval:: Error :: FlagNotFound
1434+ }
1435+ ) ) ;
1436+ client. flush ( ) ;
1437+ client. close ( ) ;
1438+
1439+ assert_eq ! ( event_rx. iter( ) . count( ) , 2 ) ;
1440+ }
1441+
13961442 #[ test]
13971443 fn variation_handles_off_flag_without_variation ( ) {
13981444 let ( client, event_rx) = make_mocked_client ( ) ;
@@ -1612,7 +1658,7 @@ mod tests {
16121658
16131659 #[ tokio:: test]
16141660 async fn variation_detail_handles_client_not_ready ( ) {
1615- let ( client, event_rx) = make_mocked_client_with_delay ( u64:: MAX , false ) ;
1661+ let ( client, event_rx) = make_mocked_client_with_delay ( u64:: MAX , false , false ) ;
16161662 client. start_with_default_executor ( ) ;
16171663 let context = ContextBuilder :: new ( "bob" )
16181664 . build ( )
@@ -2475,12 +2521,17 @@ mod tests {
24752521 }
24762522 }
24772523
2478- fn make_mocked_client_with_delay ( delay : u64 , offline : bool ) -> ( Client , Receiver < OutputEvent > ) {
2524+ fn make_mocked_client_with_delay (
2525+ delay : u64 ,
2526+ offline : bool ,
2527+ daemon_mode : bool ,
2528+ ) -> ( Client , Receiver < OutputEvent > ) {
24792529 let updates = Arc :: new ( MockDataSource :: new_with_init_delay ( delay) ) ;
24802530 let ( event_sender, event_rx) = create_event_sender ( ) ;
24812531
24822532 let config = ConfigBuilder :: new ( "sdk-key" )
24832533 . offline ( offline)
2534+ . daemon_mode ( daemon_mode)
24842535 . data_source ( MockDataSourceBuilder :: new ( ) . data_source ( updates) )
24852536 . event_processor (
24862537 EventProcessorBuilder :: < HttpConnector > :: new ( ) . event_sender ( Arc :: new ( event_sender) ) ,
@@ -2494,10 +2545,10 @@ mod tests {
24942545 }
24952546
24962547 fn make_mocked_offline_client ( ) -> ( Client , Receiver < OutputEvent > ) {
2497- make_mocked_client_with_delay ( 0 , true )
2548+ make_mocked_client_with_delay ( 0 , true , false )
24982549 }
24992550
25002551 fn make_mocked_client ( ) -> ( Client , Receiver < OutputEvent > ) {
2501- make_mocked_client_with_delay ( 0 , false )
2552+ make_mocked_client_with_delay ( 0 , false , false )
25022553 }
25032554}
0 commit comments