New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential way to manage unloading beans #424

Closed
jtreher opened this Issue Feb 10, 2016 · 1 comment

Comments

Projects
None yet
2 participants
@jtreher

jtreher commented Feb 10, 2016

When the framework is reloaded, setupApplicationWrapper() is called. At this point, any reference to the prior instance of the beanFactory is lost. This is problematic for any services that need to run shutdown logic, such as services who are maintaining references to connection pools. Ideally, you'd want to do this sort of thing in setupApplication(), but wrapper has already lost your reference.

The very simple solution would be to just provide a hook to for users to override, such as onFrameworkReload() to manually handle safely shutting down services for those that need it.

The more complex solution would be to have DI/1 register singleton objects as "unloadable" as they are created via checking for the unload method. Inject One could then invoke the shutdown methods on all registered objects upon receiving instruction to shutdown. FW/1 could call shutdown on the beanfactory (if it has it) during a reload request before instantiating a new instance of the beanfactory. FW/1 could also include similar logic via onApplicationEnd(). I'm not sure if would make use of an overridable setupOnApplicationEnd()/onApplicationEndWrapper() as is done for the other built in ...Start() methods but at least the skeleton is there.

Known workaround : Don't have DI/1 manage the service and handle the logic one off in onApplicationStart()/onApplicationEnd() and have a secondary reload to call onApplicationStart().

@seancorfield

This comment has been minimized.

Show comment
Hide comment
@seancorfield

seancorfield Dec 29, 2016

Member

I finally got around to looking at this recently and the bottom line is: this is tricky. Having looked over how FW/1 manages the bean factories it creates, it would be very hard for FW/1 to correctly "shutdown" those bean factories at the right time and in the right order.

Subsystem bean factories are created on demand, so they may or may not exist at any given point, and because each of them has the default bean factory as a parent, they must be "shutdown" prior to "shutting down" the default bean factory.

FW/1 is also bean factory agnostic so I would rather not build too much special behavior in around DI/1 that would make it more difficult for users to replicate that functionality when they are managing their own bean factory (even if they are using DI/1 outside of FW/1's immediate control).

I think having an onReload() extension point is about the most that FW/1 can realistically do for users in general. It would be called on a reload request, immediately prior to the call to setupApplicationWrapper() and users could override it to do whatever they needed at that point.

Note: if you services need to do housekeeping for a prior instance some time before a new instance initializes itself, one thing to consider is that the bean's constructor could stash this in some application scope variable and, if that exists when init() is called, it does whatever necessary to the previous instance before constructing the new instance. That would allow a bean to be self-contained, and manage its own special lifecycle, under any circumstance -- including standalone testing, outside of a bean factory.

Member

seancorfield commented Dec 29, 2016

I finally got around to looking at this recently and the bottom line is: this is tricky. Having looked over how FW/1 manages the bean factories it creates, it would be very hard for FW/1 to correctly "shutdown" those bean factories at the right time and in the right order.

Subsystem bean factories are created on demand, so they may or may not exist at any given point, and because each of them has the default bean factory as a parent, they must be "shutdown" prior to "shutting down" the default bean factory.

FW/1 is also bean factory agnostic so I would rather not build too much special behavior in around DI/1 that would make it more difficult for users to replicate that functionality when they are managing their own bean factory (even if they are using DI/1 outside of FW/1's immediate control).

I think having an onReload() extension point is about the most that FW/1 can realistically do for users in general. It would be called on a reload request, immediately prior to the call to setupApplicationWrapper() and users could override it to do whatever they needed at that point.

Note: if you services need to do housekeeping for a prior instance some time before a new instance initializes itself, one thing to consider is that the bean's constructor could stash this in some application scope variable and, if that exists when init() is called, it does whatever necessary to the previous instance before constructing the new instance. That would allow a bean to be self-contained, and manage its own special lifecycle, under any circumstance -- including standalone testing, outside of a bean factory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment