Folks,

I've got a bit of a problem with respect to the JCR integration. I will write a lengthy email explaining my current thoughts on the subject partly to get your ideas, and partly to clarify my own thoughts on the subject.

Our current model is stateless in the sense that the repository is open all the time, and you just access the pages with a String handle (pagename).

However, JCR model is stateful. That is you first get a Session object, through which you manipulate the contents of the repository, and once you're done, you release that object. This is similar to Hibernate, though JCR Sessions are not threadsafe (and assumed to be bound to a single Thread even, so they can't even be shared when synchronized).

So logically we *could* have ContentManager have a single ThreadLocal which keeps the Session object. However, since a Session gathers all of the changes, it means that in case of e.g. exceptions, the old data would still remain somewhere in the Session, and upon a new save, some old, obsolete data would be saved as well. This is obviously not a good thing.

No, we can't empty the Session with Session.refresh() before access simply because we don't know when access begins - it could start even with a simple getPage() - and obviously it's not a good thing if you call getPage() multiple times during a single access.

So, it seems to me that in order to avoid side effects, we need to have some sort of session management - which means acquiring a session to the JSPWiki repository, and then also releasing it. The WikiEngine object would be an obvious place for it, since it's what's being passed around anyway.

So the proposal would be to have a WikiEngineFactory object, which you would call as follows:

WikIEngine engine = WikiEngineFactory.getEngine();

try
{
   WikiPage page = engine.getPage(...);
}
finally
{
   engine.release();
}

The WikiPage object (and so the would not be valid after engine.release().

Now, this does not mean that the Factory will create new WikiEngines, but it'll probably set up some ThreadLocals so that it'll work properly. If we had separate WikiEngine objects, we would need to recreate all of our Manager classes. This unfortunately means that WikiEngine is for all intents and purposes currently a singleton. However, this approach would work, since you can't get to the managers without getting a WikiEngine first.

Anybody see any serious problems with this approach? Anything that'll break (other than every single plugin/Task which holds a reference to a WikiPage or WikiContext object, but those can be refactored away)?

/Janne

Reply via email to