We had a private discussion with Selcuk about blocking reconfigurations while Partitions are on use and came up with this approach.

Every operation into Partitions are going through DefaultOperationManager.We'll maintain one main RWLock for ComponentHub and then in every operation in OperationManager we lock on read-mode, and in while reconfiguring some component in ComponentHub we get exclusive lock. This is more simple to implement in my first proposed rwlock per component approach. And because reconfigurations are not likely to occur frequently and they are occuring one by one, this will not create any contention on server at all.

We might move the locking point to RequestHandler level in LdapServer to catch some minor inconsisteny points. I'll further investigate LdapServer code to evaluate necessity for this.

WDYT about this solution?

And with this issue solved, we can move into real reconfiguration task of JdbmPartition as it is throwing exceptions right now once it is initialized. I'm pasting my previous main's contents here to refresh the topic here.

Here is the current configuration points for JdbmPartition:
Currently cacheSize and optimizerEnabled properties are enabled to changed at runtime. Others call checkInitialized() first and throws exception. How should i progress through changing other properties to be reconfigurable at runtime and does not break anything?


On Thu, May 17, 2012 at 9:35 PM, Göktürk Gezer <gokturk.gezer@gmail.com> wrote:

On May 17, 2012 8:18 PM, "Selcuk AYA" <ayaselcuk@gmail.com> wrote:
> On Thu, May 17, 2012 at 2:37 AM, Göktürk Gezer <gokturk.gezer@gmail.com> wrote:
> > Hi,
> >
> > To let all of us think in a way that is compatible with new design. I felt
> > like i have to share some basic knowledge of how it works.
> >
> > Every entry in config partition is tried to be instantiated by
> > component-hub. There are some things that need to be satisfied to be able to
> > instantiate an entry into an actual object, like its complex typed
> > dependencies(component or collection) must be instantiated first and of
> > course the ComponentFactory owning that entry must be present in OSGI. These
> > aspects and some more are tracked by ComponentHub and the corresponding
> > DirectoryComponent reference is activated and deactivated in regard.
> >
> > DirectoryComponent is an base type for handling components in and outside
> > the ComponentHub. It's a container of information for component containing
> > type,configuration,nature and runtime attachments of component.
> >
> > To access these DirectoryComponent references in ComponentHub one must
> > register AbstractHubClient implementation with the ComponentHub. For
> > example:
> >
> > InterceptorHubClient ic;
> > hub.registerHubClient(ic, Interceptor.class);
> >
> > after this registration, 'ic' reference will begin receiving events of
> > DirectoryComponent wrappers of Interceptor implementations as they're
> > activated and deactivated by ComponentHub.
> >
> > Then some HubClient can call DirectoryComponent.getRuntime().getPojo()
> > method to access actual Object, cast it to Interceptor and use it as normal
> > Interceptor. Casting will succeed, which is ensured by ComponentHub.
> >
> > So with these basic knowledges in mind. i've come up with two ideas in mind,
> > !!! again, these are in case if it's not possible to handle reconfigurations
> > in JdbmPartition concurrently. !!!
> >
> > 1- Currently AbstractHubClient references are used to track only
> > ACTIVATED,DEACTIVATED and DEACTIVATING events for DirectoryComponents. Only
> > special event here is DEACTIVATING which is sent when it is possible to
> > abort deactivation of component, for example when user is deleting
> > component's corresponding entry in DIT, so HubClient can abort this deletion
> > if it's going to put server in inconsistent configuration.
> >
> > We can add two more event here, RECONFIGURING and RECONFIGURED. So with this
> > event in pocket, HubClient for Partition.class (which will be heavily
> > connected with PartitionNexus, or we can implement it right inside
> > PartitionNexus) can choose to detach reconfiguring Partition from
> > PartitionNexus and attach it again when UPDATED event is received. While
> > HubClient implementation for Partition.class works that way, we can just
> > ignore UPDATE* events in HubClient for Interceptor.class
> >
> > Pros:
> >  * We can keep accesses to components as native Object references
> > Cons:
> >  * We have to add some more methods in PartitionNexus to deactivate and
> > activate Partitions without initializing them at activation.
> >
> > 2- We insert an additional RWLock into every DirectoryComponent. And keep
> > components as DirectoryComponent in code(DirectoryService and PartitionNexus
> > mainly). So when PartitionNexus access one of its Partition reference to
> > proxy some operation, it first locks on read-mode on its wrapping
> > DirectoryComponent. And all reconfigurations on ComponentHub side locks on
> > write-mode.
> If this read write lock is implemented at the level when nexus
> interfaces the partitions, it might not be possible for a single
> operation to see a consistent state of the server. This is because a
> single operation might come down to nexus level several times.
I have some questions...

Are these multiple nexus level accesses are coming from interceptors?

Is it inconsistent or inconvenient. I mean when some operation O access the partition at X and Y times, if we for example update user attribute indexes between X and Y, is there a possibility for Y to fail? Or is there any configuration change type which can cause Y to fail?

> 1)One way to handle this would be to detect the configuration change
> and abort the operation and retry it. This would be possible to do
> with txns.
Yeah absolutely.

> 2) Another would be to use the RW lock in such a way that all
> operations are quiesced before they begin executing within the server.
> >
I don't know right know if there is a spot where I can put locks to ensure this behaviour. I'll look into that.

> > Pros:
> >  * No attachment and detachment of components(Partitions) from their holder.
> > Cons:
> >  * We must keep DirectoryComponent reference rather than their native
> > reference type to access their lock.(Actually in HubClient for
> > Partition.class, we can embed this lock into JdbmPartition reference once we
> > got its DirectoryComponent reference, and we just change PartitionNexus to
> > retrieve Lock objects of AbstractBTreePartition references just before
> > invoking their operations. So this approach invalidated the need of keeping
> > DirectoryComponent reference with this approach, just with a minimal cost to
> > change AbstractBTreePartition code to have an additional RWLock object)
> >
> >
> > Thoughts?
> >
> > Regards,
> > Gokturk
> thanks
> Selcuk