On Mon, Apr 13, 2009 at 17:14, Michael McCandless <luc...@mikemccandless.com> wrote: > On Mon, Apr 13, 2009 at 9:02 AM, Earwin Burrfoot <ear...@gmail.com> wrote: > >>> I think I'd lean towards only at construction. Seems dangerous to >>> allow swap in/out at some later time. >> I have several points pro-runtime: >> 1. We have a lot of static factory methods, it's gonna be a problem >> passing plugins everywhere on creation. > > "We" is who here? Couldn't "they refactor their code to callback into > those static factory methods? "We" as in "(un)fortunate users of Lucene". IndexReader.java is littered with the likes of: public static IndexReader open(final Directory directory, IndexDeletionPolicy deletionPolicy) throws CorruptIndexException, IOException;
> Presumably you'd pass into Lucene a "CreatesXYZComponent" instance > which given a SegmentInfo (or a public'd version of it, with > extensibility, etc) returns an XYZComponent. I want to pass a component into toplevel reader, it will be consequently notified of subreader creation/deletion and given a chance to reuse its instance for them, or provide a new one. >> 2. public <T extends IRP> void bindPlugin(Class<? super T> type, T >> instance) is ..er.. typesafer than passing Map<Class, IRP> in >> constructor. > > Can you make this more concrete? (I'm having trouble following... the > generics). Let's define the following: interface Plugin {} interface Service1 {} interface Service2 {} class Impl implements Plugin, Service1, Service2 {} IndexReader: public <T extends Plugin> void bindPlugin(Class<? super T> type, T instance); Now we can invoke bindPlugin like this: indexReader.bindPlugin(Service1.class, new Impl()); indexReader.bindPlugin(Service2.class, new Impl()); Nice points: It won't compile if Impl doesn't implement Plugin (which we need for attach/detach notifications). It won't compile if Impl doesn't implement the service interface we're binding it to. Service interface doesn't have to extend Plugin, so attach/detach methods that are a contract between a plugin and its host won't be visible to service consumers that will get an instance through: IndexReader: public <T> T getPlugin(Class<T> type); Service1 srv = indexReader.getPlugin(Service1.class); If you're passing all plugins as a bunch during creation, you have to use wither Map, or a List of Pairs. Map<Class, Plugin> plugins; new SegmentReader(somestuff, plugins); That way you're able to do less type checking than in previous example. >> 3. Plugins support attachment/detachment and they don't need to know >> exact reason they were attached/detached for - there should be no >> difference between closing a reader and removing plugin from it. > But what's the use case here? Why would a SegmentReader need to > detach/attach a new XYZComponent? We already have it for free. A component should receive notification when SegmentReader is created. A component should also receive notification when SegmentReader is close()d. Nobody prevents us from using these notifications at a different point in time. > And... why not simply open a new SegmentReader? With this change, > opening a new reader can be an extremely low-cost operation since you > could share already opened XYZComponents. A SegmentReader simply > becomes a set of components held together. I lean to post-construction attach/detach vs passing plugins in ctor not because I want to abuse it for inflight indexReader reconfiguration, it's just simpler to use with the way IndexReaders are created. -- Kirill Zakharenko/Кирилл Захаренко (ear...@gmail.com) Home / Mobile: +7 (495) 683-567-4 / +7 (903) 5-888-423 ICQ: 104465785 --------------------------------------------------------------------- To unsubscribe, e-mail: java-dev-unsubscr...@lucene.apache.org For additional commands, e-mail: java-dev-h...@lucene.apache.org