Ahh, I see. I can reproduce your result by omitting the %updating. I guess the store functions, like the file functions, are updating (but they just don't like to admit it 😀.)
Thanks /Andy On Mon, 27 Jan 2025 at 17:37, Marco Lettere <m.lett...@gmail.com> wrote: > Hi Andy, > > sorry for not specifying but we usually set the following property in the > .basex file in order to being able to blend updating and non updating > functions. > > # Local Options > MIXUPDATES = true > > M. > On 27/01/25 18:30, Andy Bunce wrote: > > Hi Marco, > > When I try your code (with 10.7 or 11.6 ) I get > > [XPTY0004] Function is updating: %updating fn() as empty-sequence()... > > Which is what I would expect from the hint in the documentation [1] > Do you not get this error message? > > /Andy > > [1] https://docs.basex.org/main/XQuery_Functions#xquery:fork-join > > On Mon, 27 Jan 2025 at 16:41, Marco Lettere <m.lett...@gmail.com> wrote: > >> Thanks for checking into this Christian. >> >> I'm experimenting with some sort of workflow oriented programming because >> our projects are getting more and more complex and we'd like to have a way >> of "standardizing" some patterns and getting a bit of introspection and >> observability of what happens to a complex workflow. >> >> We'd love to use the store as a shared memory among functions annotated >> as tasks for many reasons such as keeping a global log of the workflow, >> reducing dependency on function signatures or chaining together tasks >> executed in subsequent continuations (aka subworkflows). >> >> Those are kind of things that you can benefit from when using workflow >> engines. But we don't want to rely on those because they have a huge impact >> in terms of provisioning and maintenance. So we wanted to check whether a >> light weight solution in code is viable. >> >> I'm currently rewriting the code to use a DB instead of the store. But it >> would have been so nice to have it without requiring an external db >> server... But for example, as soon as I have two tasks running in parallel >> (fork-join) and they want to add a log line to the sequence of logs that >> introduces the risk of loosing data. >> >> Hope it clears up the intent even if a bit convoluted explanation. :-) >> Ciao, >> M. >> >> On 27/01/25 17:15, Christian Grün wrote: >> >> Hi Marco, >> >> even if %basex:lock can be added to specific function calls, it will only >> be considered before the full query is evaluated. As a consequence, your >> current query will only be evaluated if no other updating query with CONFIG >> locks is running at the same time. >> >> Apart from that, the store functions are not handled by our transaction >> management. Instead, they will be immediately executed, and we do our best >> to ensure that parallel store operations do not result in inconsistent >> states (basically by treating each store update as an atomic operation). We >> may need to clarify this in our documentation. >> >> What has been your motivation for adding entries to the store in parallel? >> >> Best, >> Christian >> >> >> Marco Lettere <m.lett...@gmail.com> schrieb am Mi., 22. Jan. 2025, 17:21: >> >>> Dear all, >>> >>> I'm wondering why the code in [1] is not working as expected. Expected >>> means getting back a map with 100 keys. >>> >>> Instead I get a random number of keys which denotes the fact (proved by >>> tracing) that the map in store is updated concurrently without >>> respecting the lock annotations. >>> >>> Is there a way to obtain synchronized access to key/values of the >>> default store? >>> >>> Thank you. >>> >>> Kind regards, >>> >>> Marco. >>> >>> [1] >>> >>> declare %updating %basex:lock('CONFIG') function local:write($k as >>> xs:string) { >>> store:put("config", map:put(store:get("config"), $k, >>> random:integer(10))) >>> }; >>> >>> let $s1 := store:put("config", map{}) >>> let $s2 := xquery:fork-join(for $i in (1 to 100) return function(){ >>> local:write("key" || $i) }) >>> return count(map:keys(store:get("config"))) >>> >>>