Lock avoidance using inspect:functions?
Wednesday, 25 May 2022 · 3 messages · last reply 13 Jun 2022
AB
Andy Bunce25 May 2022 10:39 #
Following Omar's message on lock management [1]
I thought I would share a technique that I have tried. It makes use of the function
inspect:functions [2].
The code below shows two versions of an eval-update function. After running each version the info.result view reports:
- local:eval-update => a global write lock.
- local:eval-update2 => no locks at all!
I am pretty sure this is a bug/oversight in inspect:functions. I suspect running it risks data integrity, so it is not a good idea.
However, I do make use of a non-updating version of this technique, as a way to do string evaluation without triggering a global read lock. If I know that no lockable resources are referenced then it seems safe to me?
Note: inspect:functions is similar to the unimplemented standard XQuery 3.1 function fn:load-xquery-module[3]
/Andy
[1]
https://mailman.uni-konstanz.de/pipermail/basex-talk/2022-May/017207.html [2] https://docs.basex.org/wiki/Inspection_Module#inspect:functions [3] https://www.w3.org/TR/xpath-functions-31/#func-load-xquery-module(:~ evaluate XQuery string, string is enriched with external variable
definitions for convenience :)
declare %updating function local:eval-update($exp as xs:string,$binds as
map(*)){
let $decl:= map:keys($binds)!``[declare variable $`{ . }`
external;]``=>string-join("")
return xquery:eval-update($decl || $exp, $binds)
};
declare %updating function local:eval-update2($exp as xs:string,$binds as
map(*)){
let $decl:= map:keys($binds)!``[let $`{ . }` :=$binds("`{ . }`")
]``=>string-join("")
let $mod:=("module namespace _='abuse'; declare %updating function
_:foo($binds){" , $decl, "return " , $exp , "};")=>string-join("")
let $p:=file:create-temp-file("APB", ".xqm")
let$_:=file:write-text($p,$mod)
return updating inspect:functions($p)($binds)
};
(: note: the bind functionality is not used in this example)
let $binds:=map{"p1":42}
let $exp:="db:replace('factbook', 'abuse.xml', '<a/>')"
return local:eval-update2($exp,$binds)CG
Christian Grün13 Jun 2022 13:17 #
Hi Andy,
Quoted text · Andy Bunce · 1 line
> I am pretty sure this is a bug/oversight in inspect:functions. I suspect running it risks data integrity, so it is not a good idea.
Good catch; and I’m somewhat sorry this bug is fixed now [1]. As we can’t assess at compile time if locking is necessary, a global read lock is now applied as soon as the function is called. The read lock is upgraded to a write lock if one of the returned functions is invoked as an updating function.
Cheers,
Christian
[1] https://github.com/BaseXdb/basex/commit/8e6ae0d02188348b7b8adb872657fc700518675b
AB
Andy Bunce13 Jun 2022 15:06 #
Hi Christian,
Quoted text · Christian Grün · 1 line
>I’m somewhat sorry this bug is fixed now
Me too :)
Quoted text · Christian Grün · 1 line
> As we can’t assess at compile time if locking is necessary.
I guess there are two compile times at play here, as with xquery-eval. It would be nice to find a way to downgrade locks as well as upgrade them. But easier said than done.
/Andy
Quoted text · Christian Grün · 19 lines
On Mon, 13 Jun 2022 at 12:17, Christian Grün <christian.gruen at gmail.com> wrote: > Hi Andy, > > > I am pretty sure this is a bug/oversight in inspect:functions. I suspect > running it risks data integrity, so it is not a good idea. > > Good catch; and I’m somewhat sorry this bug is fixed now [1]. As we > can’t assess at compile time if locking is necessary, a global read > lock is now applied as soon as the function is called. The read lock > is upgraded to a write lock if one of the returned functions is > invoked as an updating function. > > Cheers, > Christian > > [1] > https://github.com/BaseXdb/basex/commit/8e6ae0d02188348b7b8adb872657fc700518675b >
Written for BaseX 9.7. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery