[
https://issues.apache.org/jira/browse/OAK-1368?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14077565#comment-14077565
]
Michael Dürig commented on OAK-1368:
------------------------------------
Implementing this turns out to be more tricky than initially thought:
* To use the current pull based implementation would mean we'd need a way to
co-iterate over the event iterators from within a single thread. Not something
we can reasonably do without language support for continuations.
* An alternative implementation (which I POCed locally) does solve the problem
of concurrently accessing session related entities. It does not show much of a
performance gain though. The implementation does a diff per session and uses a
linked blocking queue per event listener. Once the queue becomes full, the
diffing would block until the respective listener has caught up. Due to this
running the producer and the consumer side of the queues on the same thread
pool is prone to deadlocking. Using different thread pools, there is still a
big potential of dead lock on consumer threads if they run off a bounded thread
pool with fewer threads than there are queues unless we implement some form of
work stealing, which again becomes quite complex given Java's library support.
Another problem with running multiple listeners off the same diff is avoiding
to receive events from the past. I.e. once a new listener has been registered
there might still be earlier diffs pending. Solving this involves hacking the
{{BackgroundObserver}} to support call back being placed into the queue of
pending revisions and using those to do the actual registering.
Given this cannot be fixed by improving the current implementation but rather
needs a new implementation, which most likely suffers from its own
idiosyncrasies, I'd rather stick with the current implementation and
concentrate on improving it where necessary:
* Keep an eye on the possible lock contention on the name path mapper. This
hasn't come up so far. However should we happen to see this we could implement
a snapshot mechanism where each listener would have its own snapshot copy of
the current name path mapper. The snapshot mechanism could take advantage of
the fact the change in name space mappings are rare.
* Pass a dedicated and correctly refreshed instance of a permission provider to
each listener and keep an eye on the performance impact.
* Improve event filter support so consumers can be more specific on what events
they want to receive (e.g. OAK-1978).
* If doing a separate diff for each listener turns out to be too expensive, we
could try to keep the results of diffs resulting in only in a few events in
memory: a first diff would run against a composite handler of all handles
attached to bounded queues. All queues that didn't overflow during that first
diff would be sent of to the associated event handlers. For the remaining
queues an extra diff would be run each. Such an approach would result in just a
single diff for all listeners if all of them have sufficiently strict filters
such that the number of events is lower than the size of the queue.
I'll file separate issues for above bullet points as they come up.
> Only one Observer per session
> -----------------------------
>
> Key: OAK-1368
> URL: https://issues.apache.org/jira/browse/OAK-1368
> Project: Jackrabbit Oak
> Issue Type: Improvement
> Components: jcr
> Reporter: Jukka Zitting
> Assignee: Michael Dürig
> Priority: Critical
> Labels: observation
> Fix For: 1.1, 1.0.4
>
>
> As mentioned in OAK-1332, a case where a single session registers multiple
> observation listeners can be troublesome if events are delivered concurrently
> to all of those listeners, since in such a case the {{NamePathMapper}} and
> other session internals will likely suffer from lock contention.
> A good way to avoid this would be to have all the listeners registered within
> a single session be tied to a single {{Observer}} and thus processed
> sequentially.
> Doing so would also improve performance as the listeners could leverage the
> same content diff. As the listeners come from a single session and thus
> presumably from a single client, there's no need to worry about one client
> blocking the work of another.
--
This message was sent by Atlassian JIRA
(v6.2#6252)