If you have a builder which creates a config then switch can also be let to the app which would be highly cleaner imo since you wouldnt suppose anything and either lock too much or not enough. Le 26 févr. 2015 22:39, "Anatole Tresch" <[email protected]> a écrit :
> *A: Basically you can name it builder or whatever. I try to summarize a few > things again*: > > 1) Previously I could already add additional PropertySource instances > programmatically (on the ConfigurationContext). > 2) I stated that, if I get a mechanism to be able to basically configure > the whole ConfigurationContext, I would be able to implement an updater for > changed configurations, since I then can adapt the property sources that > have changed, were removed, or provide additional ones. Now given a clear > requirement for doing this in a thread-safe manner, I proposed to add an > additional ConfigurationContextUpdater, which we agreed, can be a simple > ConfigurationContextBuilder, which creates a new (adapoted) instance of a > ConfigurationContext. > 3) Given that new ConfigurationContext, I must be able to apply it, so I > have a control about synchronization that never a inconsistent state > (inconsistgent because of intermediate state within a configuration update > only) is created. > > *B: *Alternatively I could also add an more *event-styled update mechanism > to the API, e.g. to the ConfigurationProvider:* > > 1) The ConfigurationContextChange "event" then must have the following > features at least: > - additional PropertySources (e.g. for new configuration resources > detected) > - PropertySources that were updated (e.g. for changed files detected). > - names of the PropertySources to be removed (e.g. for removed config > files). > > We can discuss if we also need the possibility to change filters and the > combination policy during runtime. IMO not necessarily. > > Given that all the rest of the event update and config update feature can > be implemented as extension (I already have it running, but still I am > waiting with the commit, so we have enough time to discuss the API part > first). > > I wil leave now for some sports and be curious if you guys prefer A or B or > if you see better ways solving this problem... > > Cheers, > Anatole > > > 2015-02-26 20:18 GMT+01:00 Mark Struberg <[email protected]>: > > > Yes but the builder originally was intentionally left out at all… > > > > LieGrue, > > strub > > > > > Am 26.02.2015 um 11:58 schrieb Anatole Tresch <[email protected]>: > > > > > > Basically only an interface for the ConfigurationContextBuilder. > Nothing > > more... > > > > > > - > > > Anatole Tresch > > > Glärnischweg 10 > > > 8620 Wetzikon > > > Tel +41 (43) 317 05 30 > > > - > > > Send from Mobile > > > > > >> Am 26.02.2015 um 11:07 schrieb Mark Struberg <[email protected]>: > > >> > > >> I smell some kind of overcomplicating things? > > >> > > >> How many classes would that add to our API? > > >> And what is the benefit? > > >> > > >> LieGrue, > > >> strub > > >> > > >> > > >>> Am 24.02.2015 um 14:19 schrieb Anatole Tresch <[email protected]>: > > >>> > > >>> Yes, makes sense, so I would refine my proposal to: > > >>> > > >>> - Create a ConfigurationContextBuilder. > > >>> - We could hereby access a new ConfigurationContextBuilder from the > > >>> ConfigurationProvider. > > >>> - Extend the ConfigurationProvider with the > > switch(ConfigurationContext) > > >>> method. > > >>> > > >>> > > >>> > > >>> 2015-02-24 14:11 GMT+01:00 Romain Manni-Bucau <[email protected] > >: > > >>> > > >>>> Hmm > > >>>> > > >>>> Personally I'd prefer a builder (+ a clear lifecycle of the app > build > > >>>> phase) and a switch(ConfigContext) method to mutate it at runtime > > >>>> build behing handled by the builder. switch would just be > responsible > > >>>> to 1) check the new config if needed, 2) fire the event(s) of the > > >>>> update 3) do the real mutation > > >>>> > > >>>> said otherwise builder extracts the config of the config in its own > > >>>> part and decorelate it from runtime > > >>>> > > >>>> wdyt? > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> Romain Manni-Bucau > > >>>> @rmannibucau > > >>>> http://www.tomitribe.com > > >>>> http://rmannibucau.wordpress.com > > >>>> https://github.com/rmannibucau > > >>>> > > >>>> > > >>>> 2015-02-24 14:01 GMT+01:00 Anatole Tresch <[email protected]>: > > >>>>> See inline... > > >>>>> > > >>>>> 2015-02-24 13:39 GMT+01:00 Romain Manni-Bucau < > [email protected] > > >: > > >>>>> > > >>>>>> Ok so ConfigurationContextUpdates is "part of the SPI" thanks to > > >>>>>> ConfigurationContext itself, am I right? > > >>>>> Yep. Also adding property sources already was there... > > >>>>> > > >>>>> > > >>>>> > > >>>>> > > >>>>>> That said seeing it I really think we should just use a builder > > where > > >>>>>> custom extensions (ServiceLoader in SE, events in CDI, > getBeanOfType > > >>>>>> in Spring) can add/remove components during "build" phase. > > >>>>> > > >>>>> The problem is that configuration changes during runtime exactly > > change > > >>>>> these things. E.g. > > >>>>> > > >>>>> - 1) > > >>>>> a file could be removed -> the according propertysource > > >>>>> ( > > >>>>> s > > >>>>> ) > > >>>>> must be removed. > > >>>>> - 2) a file could be added -> additional property source(s) must be > > >>>>> registered. > > >>>>> > > >>>>> - 3) a file was updated -> coud simply be an update of the > > >>>>> propertysource, but it could also mean that the ordinal has been > > >>>> changed, > > >>>>> so the whole chain must be reordered. In case a file produces > entries > > >>>> with > > >>>>> different ordinals, multiple propertysources may be affected, > > mappping > > >>>>> logically to 1 and 2 again. > > >>>>> > > >>>>> So if we agree (and many people want that) that configuration can > > change > > >>>>> during runtime, we must allow this. > > >>>>> If we want to prevent that we can simply never return a > > >>>>> ConfigurationContextUpdate instance, everything will stay > read-only. > > >>>>> Breaking things basically is still a question of adding good > default > > >>>>> entries. Of course, if someone also removes the defaults, things > may > > get > > >>>>> out of order, but I assume this is not a common case... > > >>>>> > > >>>>> Doing everything with a bulder is possible. We would then add > > according > > >>>>> methods > > >>>>> > > >>>>> ConfigurationContextBuilder getBuilder(); > > >>>>> void apply(ConfigurationContext context); > > >>>>> > > >>>>> to the ConfigurationContext. WDYT? > > >>>>> > > >>>>> > > >>>>> > > >>>>>> Why I worry about it is this kind of thing: > > >>>>>> > > >>>>>> 1) start a context > > >>>>>> 2) start to use the config > > >>>>>> 3) wow this is awesome > > >>>>>> 4) a part of the app modify it > > >>>>>> 5) oops 2 and 3 are broken > > >>>>>> > > >>>>>> builder creating immutable objects sounds far better to me (by > > itself, > > >>>>>> then you can still mutate sources/converters if that's what you > want > > >>>>>> but that's not what we provide) > > >>>>>> > > >>>>>> > > >>>>>> > > >>>>>> > > >>>>>> > > >>>>>> Romain Manni-Bucau > > >>>>>> @rmannibucau > > >>>>>> http://www.tomitribe.com > > >>>>>> http://rmannibucau.wordpress.com > > >>>>>> https://github.com/rmannibucau > > >>>>>> > > >>>>>> > > >>>>>> 2015-02-24 13:24 GMT+01:00 Anatole Tresch <[email protected]>: > > >>>>>>> Hi Roamin > > >>>>>>> > > >>>>>>> not sure, if I get your concerns: > > >>>>>>> > > >>>>>>> - the ConfigurationContext already is part of the current SPI. > > >>>>>>> > > >>>>>>> - the only change is that I extracted the methods for changing > the > > >>>>>> context > > >>>>>>> into a separate process step/artifact with a fluent API style to > > have > > >>>>>> more > > >>>>>>> control on changes applied. And I added additional functions, so > I > > >>>> also > > >>>>>> can > > >>>>>>> remove PropertySources, and have similar mechanisms for filters > and > > >>>> the > > >>>>>>> other aspects. From what I wanted to achieve, currently only > > >>>>>> PropertySource > > >>>>>>> management per se, would be enough. But for me it would look > > somehow > > >>>>>>> weired, if I can change PropertySources, but not the rest... > > >>>>>>> > > >>>>>>> Anatole > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> 2015-02-24 11:57 GMT+01:00 Romain Manni-Bucau < > > [email protected] > > >>>>> : > > >>>>>>> > > >>>>>>>> Hmm > > >>>>>>>> > > >>>>>>>> I have to admit I'm a bit lost, is the SPI useful then? Do we > need > > >>>>>>>> another spi? Maybe to start we shouldnt use any spi then move to > > spi > > >>>>>>>> once API is finished > > >>>>>>>> > > >>>>>>>> That said this update new class looks like a builder to get > > context > > >>>>>>>> immutable which sounds more common and easier to understand to > me > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> Romain Manni-Bucau > > >>>>>>>> @rmannibucau > > >>>>>>>> http://www.tomitribe.com > > >>>>>>>> http://rmannibucau.wordpress.com > > >>>>>>>> https://github.com/rmannibucau > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> 2015-02-24 10:30 GMT+01:00 Anatole Tresch <[email protected]>: > > >>>>>>>>> Hi all > > >>>>>>>>> > > >>>>>>>>> I would like to propose a small but effective change in the > > >>>>>>>>> ConfigurationContext SPI (the explanation why comes later in > this > > >>>>>> email). > > >>>>>>>>> Currently > > >>>>>>>>> it is defined as: > > >>>>>>>>> > > >>>>>>>>> *public interface *ConfigurationContext { > > >>>>>>>>> > > >>>>>>>>> *void *addPropertySources(PropertySource... > > propertySourcesToAdd); > > >>>>>>>>> List<PropertySource> getPropertySources(); > > >>>>>>>>> <T> *void *addPropertyConverter(TypeLiteral<T> typeToConvert, > > >>>>>>>>> PropertyConverter<T> propertyConverter); > > >>>>>>>>> <T> List<PropertyConverter<T>> > > getPropertyConverters(TypeLiteral<T> > > >>>>>>>> type); > > >>>>>>>>> List<PropertyFilter> getPropertyFilters(); > > >>>>>>>>> PropertyValueCombinationPolicy > > getPropertyValueCombinationPolicy(); > > >>>>>>>>> > > >>>>>>>>> } > > >>>>>>>>> > > >>>>>>>>> My proposal is add an additional ConfigurationContextUpdates > > >>>>>> interface, > > >>>>>>>>> that allows to apply multiple changes to a ConfigurationContext > > and > > >>>>>>>> finally > > >>>>>>>>> apply the changes, once they are done. So the interface would > be > > >>>>>> changed > > >>>>>>>> as > > >>>>>>>>> follows: > > >>>>>>>>> > > >>>>>>>>> *public interface *ConfigurationContext { > > >>>>>>>>> > > >>>>>>>>> List<PropertySource> getPropertySources(); > > >>>>>>>>> <T> List<PropertyConverter<T>> > > getPropertyConverters(TypeLiteral<T> > > >>>>>>>> type); > > >>>>>>>>> List<PropertyFilter> getPropertyFilters(); > > >>>>>>>>> PropertyValueCombinationPolicy > > getPropertyValueCombinationPolicy(); > > >>>>>>>>> > > >>>>>>>>> // moved methods: > > >>>>>>>>> *// void *addPropertySources(PropertySource... > > >>>> propertySourcesToAdd); > > >>>>>>>>> // <T> *void *addPropertyConverter(TypeLiteral<T> > typeToConvert, > > >>>>>>>>> // PropertyConverter<T> > > >>>>>> propertyConverter); > > >>>>>>>>> *ConfigurationContextUpdates startUpdate(); // new* > > >>>>>>>>> > > >>>>>>>>> } > > >>>>>>>>> > > >>>>>>>>> ConfigurationContextUpdates would be defined as follows: > > >>>>>>>>> > > >>>>>>>>> *public interface *ConfigurationContextUpdates { > > >>>>>>>>> > > >>>>>>>>> ConfigurationContext getContext(); > > >>>>>>>>> > > >>>>>>>>> *default *ConfigurationContextUpdates > > >>>>>>>>> addPropertySources(PropertySource... propertySourcesToAdd); > > >>>>>>>>> ConfigurationContextUpdates > > >>>>>>>>> addPropertySources(Collection<PropertySource> > > >>>> propertySourcesToAdd); > > >>>>>>>>> *default *ConfigurationContextUpdates > > >>>>>>>>> removePropertySources(PropertySource... > propertySourcesToRemove); > > >>>>>>>>> ConfigurationContextUpdates > > >>>>>>>>> removePropertySources(Collection<PropertySource> > > >>>>>>>> propertySourcesToRemove); > > >>>>>>>>> * default *ConfigurationContextUpdates > > >>>>>>>>> removePropertySources(Predicate<PropertySource> selector); > > >>>>>>>>> > > >>>>>>>>> *default *ConfigurationContextUpdates > > >>>>>>>>> addPropertyFilters(PropertyFilter... filters); > > >>>>>>>>> ConfigurationContextUpdates > > >>>>>>>>> addPropertyFilters(Collection<PropertyFilter> filters); > > >>>>>>>>> *default *ConfigurationContextUpdates > > >>>>>>>>> removePropertyFilters(PropertyFilter... filters); > > >>>>>>>>> *default *ConfigurationContextUpdates > > >>>>>>>>> removePropertyFilters(Predicate<PropertyFilter> selector); > > >>>>>>>>> ConfigurationContextUpdates > > >>>>>>>>> removePropertyFilters(Collection<PropertyFilter> filters); > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> <T> ConfigurationContextUpdates > > >>>>>> addPropertyConverter(TypeLiteral<T> > > >>>>>>>>> typeToConvert, > > >>>>>>>>> > > >>>>>>>>> PropertyConverter<T> propertyConverter); > > >>>>>>>>> *default *ConfigurationContextUpdates > > >>>>>>>>> removePropertyConverters(PropertyConverter<?>... converters); > > >>>>>>>>> ConfigurationContextUpdates > > >>>>>>>>> removePropertyConverters(Collection<PropertyConverter<?>> > > >>>> converters); > > >>>>>>>>> > > >>>>>>>>> ConfigurationContextUpdates > > >>>>>>>>> > setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy > > >>>>>> policy); > > >>>>>>>>> > > >>>>>>>>> /** > > >>>>>>>>> * Apply all the changes to the underlying context. > > >>>>>>>>> * @throws java.lang.IllegalStateException if the operation is > > >>>>>> called > > >>>>>>>>> multiple times, or another update was already > > >>>>>>>>> * applied before. > > >>>>>>>>> */ > > >>>>>>>>> *void *apply(); > > >>>>>>>>> } > > >>>>>>>>> > > >>>>>>>>> Now here are the reasons, why I think this makes sense: > > >>>>>>>>> > > >>>>>>>>> - it is much more easy to lock/synchronize the current state of > > >>>> a > > >>>>>>>>> ConfigurationContext, since only for the time where the apply() > > >>>> is > > >>>>>>>>> running special synchronization logi > > >>>>>>>>> - a configuration context can not support being mutable at all > > >>>> by > > >>>>>>>> simply > > >>>>>>>>> throwing a UnsupportedMethodException, when startUpdate() is > > >>>>>> called. > > >>>>>>>>> - Changing a ConfigurationContext, e.g. for testing can now be > > >>>> as > > >>>>>>>>> flexible as using CDIUnit for CDI. The regarding test support > > >>>>>>>> flexibility > > >>>>>>>>> is easy to achieve. > > >>>>>>>>> - *But most of all (and that was the reason, why I started to > > >>>>>> think on > > >>>>>>>>> this enhancements), we can implement automatic configuration > > >>>>>> updates, > > >>>>>>>> e.g. > > >>>>>>>>> based on new files added to a configuration directory or added > > >>>> to a > > >>>>>>>>> database table, by implementing the mechanism as part of an > > >>>> "event" > > >>>>>>>> module. > > >>>>>>>>> The event listener can determine from the change event the > > >>>> affected > > >>>>>>>>> PropertySource, compare with the PropertySource already > > >>>> registered > > >>>>>> in > > >>>>>>>> the > > >>>>>>>>> context(s) and remove/add/update new PropertySources as needed > > >>>> for > > >>>>>> the > > >>>>>>>>> affected contexts. *This module currently is in development, > > >>>> and as > > >>>>>>>> soon > > >>>>>>>>> as we would agree on this proposal I can add (and test it > > >>>> before), > > >>>>>> so > > >>>>>>>> we > > >>>>>>>>> have an initial version for supporting configuration updates. > > >>>>>>>>> > > >>>>>>>>> WDYT? > > >>>>>>>>> > > >>>>>>>>> Anatole > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> -- > > >>>>>>> *Anatole Tresch* > > >>>>>>> Java Engineer & Architect, JSR Spec Lead > > >>>>>>> Glärnischweg 10 > > >>>>>>> CH - 8620 Wetzikon > > >>>>>>> > > >>>>>>> *Switzerland, Europe Zurich, GMT+1* > > >>>>>>> *Twitter: @atsticks* > > >>>>>>> *Blogs: **http://javaremarkables.blogspot.ch/ > > >>>>>>> <http://javaremarkables.blogspot.ch/>* > > >>>>>>> > > >>>>>>> *Google: atsticksMobile +41-76 344 62 79* > > >>>>> > > >>>>> > > >>>>> > > >>>>> -- > > >>>>> *Anatole Tresch* > > >>>>> Java Engineer & Architect, JSR Spec Lead > > >>>>> Glärnischweg 10 > > >>>>> CH - 8620 Wetzikon > > >>>>> > > >>>>> *Switzerland, Europe Zurich, GMT+1* > > >>>>> *Twitter: @atsticks* > > >>>>> *Blogs: **http://javaremarkables.blogspot.ch/ > > >>>>> <http://javaremarkables.blogspot.ch/>* > > >>>>> > > >>>>> *Google: atsticksMobile +41-76 344 62 79* > > >>> > > >>> > > >>> > > >>> -- > > >>> *Anatole Tresch* > > >>> Java Engineer & Architect, JSR Spec Lead > > >>> Glärnischweg 10 > > >>> CH - 8620 Wetzikon > > >>> > > >>> *Switzerland, Europe Zurich, GMT+1* > > >>> *Twitter: @atsticks* > > >>> *Blogs: **http://javaremarkables.blogspot.ch/ > > >>> <http://javaremarkables.blogspot.ch/>* > > >>> > > >>> *Google: atsticksMobile +41-76 344 62 79* > > >> > > > > > > > -- > *Anatole Tresch* > Java Engineer & Architect, JSR Spec Lead > Glärnischweg 10 > CH - 8620 Wetzikon > > *Switzerland, Europe Zurich, GMT+1* > *Twitter: @atsticks* > *Blogs: **http://javaremarkables.blogspot.ch/ > <http://javaremarkables.blogspot.ch/>* > > *Google: atsticksMobile +41-76 344 62 79* >
