Governator is a library of extensions and utilities that enhance Google Guice to provide: classpath scanning and automatic binding, lifecycle management, configuration to field mapping, field validation and parallelized object warmup.
Problem caused by a LifecycleListener that, when added / started, creates additional LifecycleListeners that would also like to added and started. This operation works fine, if there's just one thread involved and the synchronized 'LifecycleListener.addListener()' method can be invoked. If LifecycleListener.onStarted() causes additional LifecycleListeners to be created by different threads, then LifecycleListener.addListener() results in deadlock.
Addressed by locking the 'listeners' collection only when adding / removing an element; invocation of LifecycleListener methods is performed outside of locking using a safe copy of the 'listeners' set.
Also merged the function of the 'Running' field into 'State'; no need for two 'state'-ish indicators in the same class.
Problem caused by a LifecycleListener that, when added / started, creates additional LifecycleListeners that would also like to added and started. This operation works fine, if there's just one thread involved and the synchronized 'LifecycleListener.addListener()' method can be invoked. If LifecycleListener.onStarted() causes additional LifecycleListeners to be created by different threads, then LifecycleListener.addListener() results in deadlock.
Addressed by locking the 'listeners' collection only when adding / removing an element; invocation of LifecycleListener methods is performed outside of locking using a safe copy of the 'listeners' set.
Also merged the function of the 'Running' field into 'State'; no need for two 'state'-ish indicators in the same class.