>
> Consider the following case:
>
> WikiPage page = getPage(...);
> page.setAttribute("foo","bar");
> page.save();
>
> page.setAttribute("foo","blob");
>
> String attr = page.getAttribute("foo");
>
> The value of "attr" should obviously be "blob" instead of "bar".
It seems to me that the local instance of WikiPage should indeed have
a value of "blob." But as far as the JCR is concerned, it's still
"bar", because save() hadn't been called, right?
This means
> that WikiPage will internally need to check the stuff from a local cache
> before it fetches it from JCR. This is an extra hit on all getAttribute()
> requests.
I do not understand what you mean. A call to getAttribute() would
return values from the WikiPage's field variables, no? Why would it
need to consult a cache?
>
> In addition, we need to build a disk cache, managed by WikiPage for Really
> Large Binaries, including deletion when WikiPage is garbage collected, etc
> (unless we want to cache them in memory, which is something we probably
> don't want to do). Of course a ready cache library can be used to do that,
> but again, it feels a bit pointless when JCR does it for us.
You've really lost me here...
>
>> Basically, the idea is to make read-only access very cheap, but writes
>> more expensive... and to hide all of the state management details from
>> callers.
>
> I don't think we can; imagine a situation where we have something like this:
>
> WikiPage page = getPage(...)
>
> page.setAttribute("foo","bar");
>
> doThingy(page);
>
> ...
>
> public doThingy(WikiPage page) throws Exception
> {
> page.setAttribute("bar", "baz");
> }
>
> Now, if doThingy() throws an exception, it needs to do its own state
> management to clean things up before it passes it up to the caller, or else
> the state of the page is undefined when it goes up.
It seems to me that the state of the page is perfectly clear... the
save() method hasn't been called, and therefore nothing has been
committed.
>
> So we already have to do state management.
Yeah, but you've already made that assumption anyway. It seems to me
that the save() method is already a state-management method. Is
purpose is to change the state from "unsaved" to "saved," right?
>
> In addition, having a proper lifecycle means that the JCR Session can be
> released by the JCR engine when it is not used. If the ContentManager just
> holds on to the Session, it'll just keep consuming resources. Probably not
> a lot, but it's still something.
Not sure this would be a big deal if we kept references, essentially
to ThreadLocal copies of Sessions inside ContentManager -- that were
only used for retrieving Nodes.
Here's a counter-proposal for JCRNode:
0) Assume that most WikiPages will be created for read-only retrieval
1) Remove the field variable that references Node. No Node reference
means no Session, and no Session means WikiPage becomes (more)
thread-safe.
2) Store attributes, contents, title, author etc as JCRWikiPage fields
instead of manipulating the Node
3) When save() is called, start a fresh Session, retrieve the old
Node, manipulate it; commit; release Session
4) Maybe store a String or other path-like node name (WikiName?) in
JCRWikiPage so that it's obvious where it came from in the repository.
Actually I think this happens already.
5) If the save() operation fails to retrieve a page (because it was
deleted, perhaps), we throw a checked exception. Otherwise the save()
completes normally.
This is a bit different than how it works now. But if JCRWikiPage
severs the reference to Node, it also gets rid of the most obvious
thread-safety issue.