On Fri, Apr 6, 2012 at 9:16 AM, Thomas Mortagne
<[email protected]> wrote:
> On Thu, Apr 5, 2012 at 8:44 PM, Sergiu Dumitriu <[email protected]> wrote:
>> On 04/05/2012 12:51 PM, Anca Luca wrote:
>>>
>>> On 04/05/2012 06:42 PM, Vincent Massol wrote:
>>>>
>>>> Hi Sergiu,
>>>>
>>>> On Apr 5, 2012, at 5:55 PM, Sergiu Dumitriu wrote:
>>>>
>>>>> Hi devs,
>>>>>
>>>>> Currently, requesting a component instance without a hint will look
>>>>> for the implementation that uses the "default" hint, which makes it
>>>>> difficult to change the implementation in an XWiki instance. Sure, it
>>>>> is easy as long as all the implementations use the "default" hint,
>>>>> but choosing the default between alternative implementations that
>>>>> should all still be usable by themselves is not possible.
>>>>>
>>>>> Also, "default" is not really a good hint, since it describes the
>>>>> state of the implementation, not the technology, the aspect that
>>>>> makes it different from the others. It would be better to name each
>>>>> implementation with a proper hint.
>>>>>
>>>>> I propose to define a mapping that can specify which hint is the
>>>>> default for a component. In a text file,
>>>>> META-INF/component-defaults.txt, we'll keep
>>>>> componentinterface=defaulthint mappings. For example:
>>>>>
>>>>> com.xpn.xwiki.store.XWikiStoreInterface=hibernate
>>>>> com.xpn.xwiki.store.migration.DataMigrationManager=hibernate
>>>>>
>>>>> And then, when we lookup the current storage implementation, we don't
>>>>> need to check what is the configured hint in xwiki.cfg (or
>>>>> xwiki.properties), we can just request the default implementation.
>>>>>
>>>>> If there's no mapping for a component, we'll continue to use the
>>>>> "default" hint.
>>>>>
>>>>> I'm not sure where exactly to keep such files. We bundle a
>>>>> components.txt file in each jar containing component implementations.
>>>>> We could do the same for the components we consider the platform
>>>>> defaults, and allow overrides in the
>>>>> WEB-INF/classes/META-INF/component-defaults.txt file. Still, this
>>>>> means that whenever platform defaults change, we need to keep another
>>>>> special section in the release notes, to let users know about these
>>>>> changes, so that they can manually revert to the old default if they
>>>>> need to.
>>>>>
>>>>> In the future we could change existing components to give proper
>>>>> hints instead of "default", where such a change is applicable.
>>>>>
>>>>> Another idea is to not use "default" at all, and instead go for a
>>>>> generic "xwiki", "xe", "xwiki-platform" or something like that
>>>>> whenever there's just one implementation for a component and we can't
>>>>> find another hint to describe it.
>>>>>
>>>>> WDYT?
>>>>
>>>> This is not really how it's been designed ATM. Whenever you wish to
>>>> use a different implementation of a component you use a component
>>>> implementation with the same role and same hint. You then make it
>>>> available in your classpath. (Of course you can also do this at
>>>> runtime simply by registering a new implementation over the old one).
>>>>
>>>> To decide which implementation is used you use a priority order, as
>>>> described on:
>>>>
>>>> http://extensions.xwiki.org/xwiki/bin/view/Extension/Component+Module#HOverrides
>>>>
>>>>
>>>> I'd be curious to know your exact use case and understand why the
>>>> current mechanism doesn't work for it.
>>
>>
>> "...choosing the default between alternative implementations that should all
>> **still be usable by themselves** is not possible"
>>
>> The overrides mechanism allows to change which component will be returned
>> for the "default" hint, but all the others will be invisible.
>>
>>
>>> One usecase I see is that you have multiple implementations and you want
>>> to change the default one for a specific running instance of xwiki.
>>>
>>> Overwrite mechanism only allows you to say which impl should be used
>>> from the _components with the same hint_. However, you cannot change the
>>> hint of a component at configuration time, so if you have a standard
>>> distr of xwiki and you want to use ldap authentication, let's say (if
>>> only auth was impl with components), unless you do some java to add the
>>> default hint to the ldap implementation and then to specify that this
>>> one has priority over all the default ones, I don't see how you can
>>> re-wire the default.
>>
>>
>> Exactly. For most of the "services" the XWiki platform currently has
>> (storage, cache), we don't have a "default" implementation, but we rely on a
>> kind of factory to lookup the configured default. That is an actual factory
>> class in the case of the cache service, but just more code in the old
>> XWiki.java class for the storage initialization. A standard way of selecting
>> the default means that we'll need less factories, and less code is always a
>> good thing.
>>
>> Now, suppose one of the older components that had only one implementation,
>> "default", gets alternative implementations, and we want to be able to allow
>> more than one to be active in a wiki, and let the administrator decide which
>> one should be considered the default. How can we approach this? The only way
>> is indeed to have multiple hints, but last time I checked this resulted in
>> more than one instance, even for @Singleton implementations.
>
> Yep different role or hint produce different instances but AFAIK it's
> not really an explicit choose but more lazyness since it's a bit more
> complex (just a bit and is not technical reason to prevent to support
> it if we want to). The thing is that we often restraint what our CM

s/restraint/restrain/

> can do because there is still the idea that it's a (starting to be
> old) "temporary" implementation and that we would move to another
> implementation like Guice, OSGI, etc. at one point.
>
>> Another
>> approach is to deprecate the direct dependency declaration and instead
>> introduce a factory that is responsible for selecting the default, but this
>> breaks backwards compatibility.
>>
>> The "I don't care, just give me the default" strategy works as long as the
>> component implementation is self-contained and doesn't involve data
>> communication. Let's take an example, PDF export.
>>
>> Currently the PDF export is only possible via FOP. If we were to convert the
>> current interface + implementation class into a proper component, we'd name
>> it "default", since it's the only one and who needs a factory for only one
>> implementation. People use it and they're happy because it just works. But
>> we might soon add support for export via an office server. Suppose we want
>> either FOP or Office to be usable as the default PDF export implementation.
>> And suppose we'll want to keep both types of export active, so that we can
>> use either one as the implementation for the default export of documents,
>> the FOP implementation for exporting some kinds of documents like scientific
>> articles, and the office connector for generating PDFs for presentations.
>> Using the overrides mechanism we can only have one active at the same time,
>> unless we introduce yet another factory which we can bypass using manual
>> component lookup.
>>
>> If at some point we decide that the office implementation works better, we
>> might consider changing the default implementation for the pdf component.
>> This means that we'll change the hint of the FOP implementation from
>> "default" to "fop", change the hint of the Office implementation from
>> "office" to "default", and our new version of XE works great if people read
>> the installation guide and properly configure the office connector. But what
>> about those that want to upgrade, but are happy with the older FOP
>> implementation and don't want to add support for the office connector?
>> They'll have to use patched versions of the two component implementations
>> where their hints are reverted back to the old values. Easy? No. And even
>> though "default" means "I don't care what the implementation does", here it
>> does matter a lot which implementation you're using. They have different
>> requirements, and it's important to know if the implementation will require
>> an office instance or not.
>>
>> Saying that this won't happen since we're all really careful when designing
>> our components is wishful thinking. We've refactored other more critical
>> pieces of code than providing alternative implementations for a component,
>> so we will find ourselves in situations where we'll have to switch from only
>> one "default" implementation to several. Designing our component manager to
>> make it easy to transition is the right thing to do.
>>
>> Still, my major problem is not about overrides, but about the semantics of
>> "default" (or lack of it). This says nothing about the actual mechanisms
>> behind the implementation, it just reflects the state of that particular
>> component implementation: it's the default at the moment. Not caring what
>> the implementation actually does works only when there is indeed just one
>> possible implementation that is straight-forward. But in most cases, we do
>> rely on another library that does the work for us, and libraries die, better
>> alternatives come along, and changing that internal aspect of the
>> implementation will sometimes be backwards incompatible, or have a different
>> behavior. Sure, it does the same job, but it does it so differently that
>> some will prefer to use the other approach. We have to let users decide
>> which is their "default", and having multiple implementations with the
>> "default" hint but different priorities is not very intuitive. Why not make
>> everything default and remove hints completely if we don't really put any
>> meaning into the hint?
>>
>> And "default" adds another assumption: XWiki Enterprise is the ultimate
>> target. Our defaults are the only ones that matter. As an example, all the
>> *Configuration components have just one "default" implementation, which
>> relies on xwiki.properties, XWiki.XWikiPreferences etc. Doesn't that tie the
>> platform to the XWiki Enterprise wiki? It's not a direct dependency visible
>> at compilation time, it's worse, and invisible assumption about the final
>> runtime. It's certainly not the default for other types of users that want
>> to embed xwiki-commons or xwiki-platform components in a different type of
>> end product. To me this isn't the default configuration, this is the default
>> configuration used by XWiki Enterprise, thus my proposal of using something
>> else as the generic component hint instead of "default".
>>
>> --
>> Sergiu Dumitriu
>> http://purl.org/net/sergiu/
>> _______________________________________________
>> devs mailing list
>> [email protected]
>> http://lists.xwiki.org/mailman/listinfo/devs
>
>
>
> --
> Thomas Mortagne



-- 
Thomas Mortagne
_______________________________________________
devs mailing list
[email protected]
http://lists.xwiki.org/mailman/listinfo/devs

Reply via email to