Don't get me wrong ;-) I am fine with the builder pattern and yes, it gives us additional flexibility as a collateral side effect, which may also be very useful in alternate use cases/runtime scenarios... I just wanted to layout/relayout the options discussed so far, hoping Mark jumps on the train as well ;)
2015-02-27 0:12 GMT+01:00 Romain Manni-Bucau <[email protected]>: > 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* > > > -- *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*
