You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a configuration bean, marked with @ConfigurationProperties and a @Refreshable bean which is injected with the config bean in its constructor, and remembers configuration value, i.e. name (originally it happened to me with a refreshable DataSource factory that was called with the configuration bean).
Since the refresh, and discard of an old bean instance is initiated by configuration change in the beans' specific property subset, I would expect that the bean gets new configuration injected into its constructor (or factory for the bean), so when the @Refreshable bean is re-created after RefreshEvent, it remembers the new values from the @ConfigurationProperties bean.
Actual Behaviour
There's race condition between
the time the @Refreshable bean is destroyed and
the time the @ConfigurationReader bean values are re-read from the property values.
If a service happens to dereference @Refreshable proxy between (1) and (2), for example during processing of an incoming request, a new instance of @Refreshable bean
is created, but the Config bean values are still old, not updated at the time of bean creation. Should the bean configure itself or act upon the Config bean values in the constructor, or @PostCreate, its state becomes inconsistent with the ApplicationContext properties - as they were not yet loaded info the Config bean.
The demo application demonstrates that, creating race condition by using DestroyedBean listener (to act timely between (1) and (2)). Two calues are reported. "Initial" is a value from RacebugConfig bean captured in the constructor; "fresh" is the value directly read from the bean.
This is a snippet from the demo application:
14:17:32.268 [scheduled-executor-thread-9] INFO com.example.racebug.EagerService - Periodic check: of racebug initial name: "foobar", current name "foobar", from refreshable #2
14:18:02.269 [scheduled-executor-thread-10] INFO com.example.racebug.EagerService - Periodic check: of racebug initial name: "foobar", current name "foobar", from refreshable #2
14:18:02.270 [scheduled-executor-thread-4] INFO c.e.c.PeriodicConfigRefresh - Start periodic config refresh
14:18:02.272 [scheduled-executor-thread-4] INFO c.e.c.PeriodicConfigRefresh - Keys of changed properties: [racebug-config.name]
14:18:02.273 [scheduled-executor-thread-4] INFO com.example.racebug.EagerTrigger - Reloaded racebug property name DURING refresh: Optional["foo"]
14:18:02.274 [scheduled-executor-thread-4] INFO com.example.racebug.EagerTrigger - Racebug name DURING refresh: initial "foobar", fresh "foobar"
14:18:02.275 [scheduled-executor-thread-4] INFO com.example.racebug.EagerTrigger - Reloaded racebug property nameAFTER refresh: Optional["foo"]
14:18:02.275 [scheduled-executor-thread-4] INFO com.example.racebug.EagerTrigger - Reloaded racebug CONFIG name AFTER refresh: "foo"
14:18:02.275 [scheduled-executor-thread-4] INFO com.example.racebug.EagerTrigger - Racebug name AFTER refresh initial: "foobar", fresh: "foo"
14:18:32.270 [scheduled-executor-thread-11] INFO com.example.racebug.EagerService - Periodic check: of racebug initial name: "foobar", current name "foo", from refreshable #3
Initially the refreshable bean reports initial/fresh name "foobar", as it was originally configured. After change in the config file and re-load, the @Refreshable bean is re-created, but now reports different initial and fresh names (see the last line).
Expected Behavior
I have a configuration bean, marked with
@ConfigurationProperties
and a@Refreshable
bean which is injected with the config bean in its constructor, and remembers configuration value, i.e. name (originally it happened to me with a refreshable DataSource factory that was called with the configuration bean).Since the refresh, and discard of an old bean instance is initiated by configuration change in the beans' specific property subset, I would expect that the bean gets new configuration injected into its constructor (or factory for the bean), so when the
@Refreshable
bean is re-created afterRefreshEvent
, it remembers the new values from the@ConfigurationProperties
bean.Actual Behaviour
There's race condition between
@Refreshable
bean is destroyed and@ConfigurationReader
bean values are re-read from the property values.If a service happens to dereference
@Refreshable
proxy between (1) and (2), for example during processing of an incoming request, a new instance of@Refreshable
beanis created, but the Config bean values are still old, not updated at the time of bean creation. Should the bean configure itself or act upon the Config bean values in the constructor, or
@PostCreate
, its state becomes inconsistent with the ApplicationContext properties - as they were not yet loaded info the Config bean.The demo application demonstrates that, creating race condition by using DestroyedBean listener (to act timely between (1) and (2)). Two calues are reported. "Initial" is a value from RacebugConfig bean captured in the constructor; "fresh" is the value directly read from the bean.
This is a snippet from the demo application:
Initially the refreshable bean reports initial/fresh name "foobar", as it was originally configured. After change in the config file and re-load, the
@Refreshable
bean is re-created, but now reports different initial and fresh names (see the last line).Steps To Reproduce
refreshable-config
racebugConfig.name
inconfig/application.properties
Environment Information
Example Application
https://github.com/sdedic/micronaut-dbbugs2
Version
4.7.6
The text was updated successfully, but these errors were encountered: