Open spring-projects-issues opened 4 years ago
John Blum commented
Argh!
I am beginning to understand why I designed/built the LocatorFactoryBean
class in SDG as I did.
Currently, the LocatorFactoryBean.afterPropertiesSet()
method (technically, via the init()
method) "starts" the Locator
. This was necessary in order to get a reference to the Locator
object, which may be injected into other Spring managed application components (i.e. beans), no matter how unlikely.
The LocatorLauncher
class does not initialize a reference to a Locator
object until the Locator
is "started", as seen here. That is because, once again, Apache Geode's internal APIs (i.e. InternalLocator
in this case) are 1) broken and 2) not open for extension.
Ideally, a Locator
object could be fully constructed (i.e. created and initialized) and then "started" (when it is technically "safe" to do so) separately, as it should be! In that way, SDG's LocatorFactoryBean
class could construct the Locator
in afterProperties()
(allowing a reference to the single Locator
object to be passed and injected into other Spring managed application components, etc) and then "start" the Locator
in Lifecycle.start()
, at the appropriate moment.
John Blum commented
UPDATE: I have altered the description, slightly!
I have decided to use the Proxy pattern to solve this problem.
Essentially, the problem stems from GemFire/Geode's APIs (and specifically the Locator
API) since it does not cleanly separate the construction (creation & initialization) of a Locator
from starting the Locator
. These 2 concerns are naively combined into a single call, using (e.g.) a factory method. This hinders proper lifecycle management in different contexts, like the Spring container.
Unfortunately, the InternalLocator
class (the GemFire/Geode provided implementation of Locator
) and API 1) offers no relief (essentially has the same code smells as the abstract Locator
class) and 2) is part of the "internal" API, making its use risky!
In order to preserve the same behavior as experienced by SDG users today from priorreleases experienced , the default behavior of LocatorFactoryBean
will be to not wait on the Locator
to stop. This means users must do 1 of 2 things:
1) Explicitly set the new waitOnLocator
attribute when using the @LocatorApplication
annotation, or...
2) Implement some means to cause the Locator
based application to block, preventing the JVM from exiting. For example along with this.
This is pertinent since any means to "wait on the Locator
" is subject to the vagaries of the OS Scheduler and platform Thread implementation, which can vary from platform to platform (particularly when using native Threads). Java's Project Loom should (eventually) help in this regard. Therefore, when the waitOnLocator
attribute of the @LocatorApplication
annotation is explicitly set, SDG will make a best effort to block the JVM from exiting. Again, there is no absolute guarantee.
By making this behavior optional rather than the default, it affords the developer the means to use the feature when required or implement their own approach (perhaps similar to the example above) as needed in a way that satisfies the application's requirements.
John Blum opened DATAGEODE-361 and commented
Currently, when users declare the
@LocatorApplication
annotation on a Spring main class (e.g. a main class annotated with@SpringBootApplication
), Spring will configure and bootstrap aLocator
instance successfully, but then fall straight through, causing the JVM to exit (with exit code 0).This improvement will couple the
Locator
instancestart
andstop
operations with Spring's Lifecycle management capabilities using theLifecycle
, or alternatively theSmartLifecycle
interface.Technically, this means the
LocatorLaucher.start()
andLocatorLauncher.waitOnLocator()
methods will be called inLifecycle.start()
andLocatorLauncher.stop()
will be called inLifecycle.stop()
, while the (perceived) construction of theLocator
object representing the distribution locator and location services will occur after initialization, as before.Additional attributes will be added to the
@LocatorApplication
to control this behavior:phase
- giving users precise control over when theLocator
will start and stop during the Spring container lifecycle.waitOnLocator
- allowing the Locator JVM process to be blocked waiting for the Locator be be stopped, which will be useful in production Use Cases.Affects: 2.4 M1 (2020.0.0), 2.2.9 (Moore SR9), 2.3.2 (Neumann SR2)
Reference URL: https://stackoverflow.com/questions/63197753/locatorapplication-starts-and-then-immediately-stops