Currently most Jena implementations use a multiple read one write
solution. However, I think that it is possible (with minimal work) do
provide a solution that would allow for multiple writers by using lower
level locks.
I take inspiration from the Privileges code. That code allows privileges
to be determined down to the triple level. Basically it does the following
{noformat}
start
|
v
may user perform operation on graph? → (no) (restrict)
|
v
(yes)
may user perform operation on any triple in graph → (yes) (allow)
|
v
(no)
may user perform operation on the specific triple in graph → (yes) (allow)
|
v
(no) (restrict)
{noformat}
My thought is that the locking may work much the same way. Once one thread
has the objects locked the any other thread may not lock the object. The
process would be something like:
Graph locking would require exclusive lock or non-exclusive lock. If the
entire graph were to be locked for writing (as in the current system) then
the request would be for an exclusive write-lock on the graph. Once an
exclusive write lock has been established no other write lock may be
applied to the graph or any of its triples by any other thread.
If a thread only wanted to lock part of the graph, for example all triples
matching <u:foo ANY ANY>, the thread would first acquire a non-exclusive
write lock on the graph. It would then acquire an exclusive write lock on
all triples matching <u:foo ANY ANY>. Once that triple match lock was
acquired no other thread would be able to lock any triple who's subject was
u:foo.
The lock request would need to contain the graph name and (in the case of a
partial graph lock) a set of triple patterns to lock. The flow for the
lock would be something like:
{noformat}
start
|
v
does the thread hold an exclusive graph lock → (yes) (success)
|
v
(no)
does the thread want an exclusive graph lock → (yes) (go to ex graph lock)
|
v
(no)
does the thread hold a non-exclusive graph lock → (no) (go to nonex graph
lock)
|
v
(yes) (lbl:lock acquired)
can the thread acquire all the triple locks → (yes) (success)
|
v
(no) (failure)
(lbl: nonex graph lock)
does any thread hold an exclusive graph lock → (yes) (failure)
|
v
(no)
acquire non-exclusive graph lock
(goto lock acquired)
(lbl: ex graph lock)
does any thread hold an exclusive graph lock → (yes) (failure)
|
v
(no)
does any thread hold a non-exclusive graph lock → (yes) (failure)
|
v
(no)
acquire exclusive graph lock
(success)
{noformat}
The permissions system uses an abstract engine to determine if the user has
access to the triples. For the locking mechanism the system needs to track
graph locks and triple patterns locked. If a new request for a triple
pattern matches any existing (already locked) pattern the lock request
fails.
The simple releaseLock() will release all locks the thread holds.
Note that the locking system does not check the graph being locked to see
if the items exist in the graph it is simply tracking patterns of locks and
determining if there are any conflicts between the patterns.
Because this process can duplicate the current locking strategy it can be
used as a drop in replacement in the current code. So current code would
continue to operate as it does currently but future development could be
more sensitive to locking named graphs, and partial updates to provide
multi-thread updates.
Thoughts?
Claude
--
I like: Like Like - The likeliest place on the web
<http://like-like.xenei.com>
LinkedIn: http://www.linkedin.com/in/claudewarren