Reloadablility

21 05 2009

I have been using reloadability a lot recently in OSGi and its is great, but being great does depend largely on the developer. Its rather like reloading webapps. If the component is working well, and the developer hasn’t done anything to cause a problem then a bundle in OSGi will reload over and over again, if however they have captured resources and dont conform to the life-cycle methods of whichever bundle activation flavor they are using then reloading will fail. Not necessarily immediately, but at some point. For example, other bundles may depend on the reloaded bundle and they may not correctly re-set their internal state, or just occasionally some sort of lockup might happen as below.

21.05.2009 12:29:18.900 *INFO* [SCR Component Actor] org.apache.sling.servlets.resolver Service [ServletResourceProvider for Servlets at [/apps/sling/user/update.POST.servlet],141] ServiceEvent UNREGISTERING
21.05.2009 12:29:18.901 *INFO* [SCR Component Actor] org.apache.sling.servlets.resolver Service [ServletResourceProvider for Servlets at [/apps/sling/fs/folder/GET.servlet],157] ServiceEvent UNREGISTERING
21.05.2009 12:29:18.902 *INFO* [SCR Component Actor] org.apache.sling.servlets.resolver Service [ServletResourceProvider for Servlets at [/apps/sling/servlet/default/modifyAce.POST.servlet],144] ServiceEvent UNREGISTERING
21.05.2009 12:29:18.903 *ERROR* [SCR Component Actor] org.sakaiproject.kernel.messaging [org.sakaiproject.kernel.messaging.OutboxListener] The deactivate method has thrown an exception (java.lang.NullPointerException) java.lang.NullPointerException
 at org.sakaiproject.kernel.jcr.JCRServiceImpl.getObservationManager(JCRServiceImpl.java:286)
 at org.sakaiproject.kernel.messaging.OutboxListener.deactivate(OutboxListener.java:120)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:585)
 at org.apache.felix.scr.impl.ImmediateComponentManager.disposeImplementationObject(ImmediateComponentManager.java:269)
 at org.apache.felix.scr.impl.ImmediateComponentManager.deleteComponent(ImmediateComponentManager.java:150)
 at org.apache.felix.scr.impl.AbstractComponentManager.deactivateInternal(AbstractComponentManager.java:521)
 at org.apache.felix.scr.impl.AbstractComponentManager.access$200(AbstractComponentManager.java:36)
 at org.apache.felix.scr.impl.AbstractComponentManager$4.run(AbstractComponentManager.java:204)
 at org.apache.felix.scr.impl.ComponentActorThread.run(ComponentActorThread.java:85)
21.05.2009 12:29:18.904 *INFO* [SCR Component Actor] org.sakaiproject.kernel.jcr Service [org.sakaiproject.kernel.jcr.support.JCRNodeFactoryServiceImpl,165] ServiceEvent UNREGISTERING
21.05.2009 12:29:28.858 *ERROR* [FelixPackageAdmin] org.apache.sling.jcr.jackrabbit.server stopRepositoryPinger: Timed waiting for thread Thread[Repository Pinger,5,main] to terminate
^C21.05.2009 12:32:25.063 *INFO* [Sling Terminator] Java VM is shutting down
21.05.2009 12:32:25.063 *INFO* [Sling Terminator] Stopping Sling
^C

^C^C

^Z kill -9 is just about all I can do in this instance.

At the moment all the evidence is pointing to reloadability being a useful tool in development, but unless you are prepared to access unscheduled downtime, not something that should seriously be considered for production. (unless you are prepared to put in the QA effort on all bundles to check as a set any one of them will reload with no side effects).





Community behaviour and choice of scm.

14 05 2009

Coming from projects where the community is collaborative in nature, I have often wondered how the management of scm, and committer access influences the nature of the community. I wasn’t really certain that it had any impact until I tried something other than svn and cvs. IMHO, cvs is painful in the extreme for widely distributed groups, svn is better but it places some interesting barriers to creativity. With a centrally provisioned repository, personal expression and experimentation is limited. Few take branches to experiment, most work locally until they are willing to share. Developer communities resort to lazy commit consensus and/or tools like the excellent codereview app running on a Google App Engine. The former requiring commit stream discipline and the latter requiring constant searching for approval from fellow committers. So these tools are filling the holes left by a centralized scm in a distributed development environment.

Then there there are the distributed scm’s like git. It no surprise that git was written by a benevolent dictator. The model of distributed scm’s tempts anyone participating to become a benevolent dictator, with the feeling that the branch they own is the master branch and everyone should follow them. The interesting thing about truly distributed scm’s is that although they encourage those thoughts, the dictator is only able to satisfy their megalomaniac tendencies if they are given that power by their collaborators. In a distributed scm, someone has to take responsibility for pulling together the trusted stream of patches. If they do a bad job and don’t serve their community, the community can easily switch their allegiances and trust someone else’s master branch.

The contributing developer, being part of a community can now  create their own local branches to experiment. They can push all their branches early and often to let others see what they are doing. The committer status is dissolved since all developers have commit to their own set of branches. Those upstream become far more diligent in code review, since they now have the tools to perform that review and they generally feel much more responsible for the stream of patches they accept into their code base. The ability to change the core code is no longer embedded in central repository but in the hands of those elected to manage the trusted branch. Unfortunately, good though git is at super fast merged on large sets of commits, I would like to experience what it would be like on the receiving end of 50+ contributors patch streams before volunteering to be a benevolent dictator, especially as most dictators get lynched in the end.





Dynamic Groups

7 05 2009

We have been looking hard at how AuthZ works in Jackrabbit and Sling. Not least that JCR Sessions are considered expensive objects, even though they typically take < 1ms to initialize. The reason they are considered expensive, is not the cost of creating one, but the potential long term cost. Hence sessions are pooled for reuse but the selection strategy looks for a free session bound to the user before taking one from the pool of all sessions. Obviously the session is cleaned prior to being bound to another user.

So what’s being stored in the session? The Jackrabbit AccessControlManager and SecurtityManager works in such a way as new instances of these classes are created for every session. This generates the opportunity to cache access control information bound to the session, which is one of the things that makes the DefautlAccessManager very fast in both Jackrabbit 1.5 and later, and the new JCR2 implementation in trunk. This structure gives some insight into the way that access control is going in Jackrabbit for the JSR-283 implementation. The particularly interesting part is that this access control mechanism, bound to the user session, compiles the access control list at any one node for the user into a bitmap. This makes the resolution of permissions a fast bitwise or of permission. This compiled access control list for the node is cached with the user bound session, resulting in much faster ACL resolution.

So how does this compare with the AuthZ mechanism that was created for Kernel2. Well its faster for starters, but it doesn’t have quite as wide a capability. Since the compiled access control list is a bitwise or, it has no order. This makes it harder to deny access since the mechanism tends to grant rather than deny. The approach does however make the permissions simpler in nature since the processing order does not matter. The other main different is that the users, in the Jackrabbit/Sling world have a pre-defined set of Principals that can be determined. Only entries in the access control list marked with a principal that the user has are applicable to the user. You can think of a Principal and a group interchangeably. So in Jackrabbit/Sling Principals that a user has is deterministic within the Jackrabbit instance. ie “Give me all the groups I am a member of” generates a static list of group.

This sounds fine for Sling but in Sakai we have a number of use cases where the membership is not static. We have groups where you only know you are a member of that group by asking the question “Am I a member of group B?” because group B does not appear in the answer to “Which groups am I a member of ?”. This is particularly true if the system that can answer the “Am I .. ” question is external and only has that form of query. These are Dynamic Groups.

Another form of Dynamic Group is the a group where membership depends on context. eg “Am I a member of this Group B at 11:23 on a Monday morning ?”, or “Am I a member of Group C if I wanted to look at this Blog posting ?”. It may be hard to visualize why the question is being asked. Group C can allows a user to edit their own blog posts.

At the moment, I think Dynamic Groups are achievable with a small patch to Jackrabbit. The full impact of this is being looked at now, but its clear that with Dynamic Groups, the DefaultAccessManager in Jackrabbit 1.5 and the future Jackrabbit 2/JSR-283 will work for Sakai. The advantages of this are wide reaching since it means that much of the basic plubming code required for Sakai Kernel 2 is already present in Sling, leaving us, the future Sakai community to focus on teaching and research applications.