@@ -382,7 +382,7 @@ def set_up_bundle_listener
382382 @thing_type_tracker . class . field_reader :openState
383383 org . openhab . core . config . core . xml . osgi . XmlDocumentBundleTracker ::OpenState . field_reader :OPENED
384384 opened = org . openhab . core . config . core . xml . osgi . XmlDocumentBundleTracker ::OpenState . OPENED
385- sleep until @thing_type_tracker . openState == opened
385+ wait_until ( "thing type tracker open" ) { @thing_type_tracker . openState == opened }
386386 @bundle_context . bundles . each do |bundle |
387387 @thing_type_tracker . adding_bundle ( bundle , nil )
388388 end
@@ -394,7 +394,7 @@ def set_up_bundle_listener
394394 @config_description_tracker . class . field_reader :openState
395395 org . openhab . core . config . core . xml . osgi . XmlDocumentBundleTracker ::OpenState . field_reader :OPENED
396396 opened = org . openhab . core . config . core . xml . osgi . XmlDocumentBundleTracker ::OpenState . OPENED
397- sleep until @config_description_tracker . openState == opened
397+ wait_until ( "config description tracker open" ) { @config_description_tracker . openState == opened }
398398 @bundle_context . bundles . each do |bundle |
399399 @config_description_tracker . adding_bundle ( bundle , nil )
400400 end
@@ -532,7 +532,7 @@ def wait_for_service(service_name, filter: nil, &block)
532532 end
533533
534534 def wait_for_start
535- wait do |continue |
535+ wait ( timeout : 120 , label : "all bundles to start" ) do |continue |
536536 @all_bundles_continue = continue
537537 next continue . call if all_bundles_started?
538538 end
@@ -557,10 +557,11 @@ def blocked_bundle?(bundle)
557557 bundle . fragment?
558558 end
559559
560- def wait ( timeout : 30 )
560+ def wait ( timeout : 30 , label : nil )
561561 mutex = Mutex . new
562562 cond = ConditionVariable . new
563563 skip_wait = false
564+ timed_out = false
564565
565566 continue = lambda do
566567 # if continue was called synchronously, we can just return
@@ -570,8 +571,40 @@ def wait(timeout: 30)
570571 end
571572 mutex . synchronize do
572573 yield continue
573- cond . wait ( mutex , timeout ) unless skip_wait
574+ timed_out = ! cond . wait ( mutex , timeout ) unless skip_wait
574575 end
576+
577+ return unless timed_out
578+
579+ detail = label ? " while waiting for #{ label } " : ""
580+ raise "Timed out after #{ timeout } s#{ detail } . #{ bundle_state_summary } "
581+ end
582+
583+ def wait_until ( label , timeout : 30 , interval : 0.1 )
584+ deadline = Process . clock_gettime ( Process ::CLOCK_MONOTONIC ) + timeout
585+ until yield
586+ if Process . clock_gettime ( Process ::CLOCK_MONOTONIC ) >= deadline
587+ raise "Timed out after #{ timeout } s while waiting for #{ label } . #{ bundle_state_summary } "
588+ end
589+
590+ sleep interval
591+ end
592+ end
593+
594+ def bundle_state_summary
595+ return "Bundle state unavailable" unless @bundle_context
596+
597+ bundle_counts = @bundle_context . bundles . each_with_object ( Hash . new ( 0 ) ) do |bundle , counts |
598+ counts [ bundle . state ] += 1
599+ end
600+
601+ active = org . osgi . framework . Bundle ::ACTIVE
602+ resolved = org . osgi . framework . Bundle ::RESOLVED
603+ starting = org . osgi . framework . Bundle ::STARTING
604+ installed = org . osgi . framework . Bundle ::INSTALLED
605+
606+ "Bundles: active=#{ bundle_counts [ active ] } , resolved=#{ bundle_counts [ resolved ] } , " \
607+ "starting=#{ bundle_counts [ starting ] } , installed=#{ bundle_counts [ installed ] } , total=#{ @bundle_context . bundles . length } "
575608 end
576609
577610 def link_osgi
0 commit comments