Can persistency to different files be used from two pengine sessions concurrently?

I am currently accessing SWI Prolog from Python using pyswip but have hit many issues and so am trying to convert to running SWI Prolog as a service and calling it from Python.

My application stores its state in:

  • globals using nb_getval/2 and friends for values that only need to be accessed temporarily for a particular query (like returning information about why a query failed)
  • using persistency for all other application state

My hope was to use pengines. I wanted to have a pengine session (using Destroy=False) represent a running instance of the app that could be accessed from the Python client using Python pengines. The idea being that when a new pengine is created, it would use db_attach/2 to load the state for that user’s session.

It appears that persistency asserts into the persistency module which means that the persistency engine will not be able to be used from two different pengines (storing state in to different files) at the same time. Am I misunderstanding? It there a way to get this to work?

?- db_attach("/.../test99.db", []).
true.

?- listing(db_file).
:- dynamic persistency:db_file/5.

persistency:db_file(user,
                    "/.../test99.db",
                    0,
                    0,
                    0).

true.

I set up a non-sandboxed application called ‘adventure’ like this to test:

:- multifile pengines:authentication_hook/3.
:- pengine_application(adventure).

pengines:authentication_hook(_Request, adventure, User) :-
    User = test,
    !.
pengines:authentication_hook(_Request, adventure, User) :-
    throw(http_reply(forbidden(/))).

:- multifile pengines:not_sandboxed/2.
pengines:not_sandboxed(_User, adventure).

:- multifile pengines:prepare_goal/3.
pengines:prepare_goal(G, G, _) :-
    debug(pengine(_), "Goal ~w", G).

server(Port) :-
    http_server(http_dispatch, [port(Port)]).

And here is my Python test client:

from pengines.Builder import PengineBuilder
from pengines.Pengine import Pengine

queryAssertFoo1 = "assert(test(foo1))"
queryCheckFoo = "test(X)"

pengine_builder1 = PengineBuilder(
   urlserver="http://localhost:4242", 
   application="adventure", 
   destroy=False)
pengine = Pengine(builder=pengine_builder1)
runQuery(pengine, queryAssertFoo1)
runQuery(pengine, queryCheckFoo)