Are local pengines correctly removed?

I tried to start a few pengines locally (namely, 3 because that is the maximum default).

I have found out that, once the pengines exit (because their idle time has been reached), the “pengine count” stays at 3, so replacement pengines cannot be started.

Maybe I’m forgetting a cleanup manoeuver? Or maybe I shouldn’t set at_exit :thinking: (Update: No, tested, that’s not it).

Here is a test:

:- use_module(library(pengines)).
:- use_module(library(settings)).

attempt :-

   set_setting(pengine_sandbox:idle_limit, 3),   % default is 5 mins, shorten to 2s 
   setting(pengine_sandbox:slave_limit,Max),     % check out the (trigger warning) slave limit
   format("One can create ~d server/slave pengines~n",Max),

   % create maximum engines

   length(PengineIds,Max),
   maplist(
      [PengineId]>>pengine_create(
                         [
                         id(PengineId),
                         at_exit(format('Adios!~n',[]))
                         ]),
      PengineIds
   ),
   maplist(      
      [PengineId]>>format("Created Pengine: ~q~n",PengineId),
      PengineIds),      

   % write out what we know about active threads

   format("Current threads~n",[]),      
   forall(  
      thread_property(ThreadId,id(NumThreadId)),
      format("   ~q ~q~n",[ThreadId,NumThreadId])),

   % wait for engines to exit due to exceeing their idle time

   aggregate_all(count, pengines:child(_,_), CountBefore),
   format("There are ~d pengines~n",CountBefore),
   sleep(5),
   % There will be 3 x "Adios" on the screen.
   aggregate_all(count, pengines:child(_,_), CountAfter),
   format("There are ~d pengines~n",CountAfter),

   % But now it's no longer possible to start a pengine...

   \+ pengine_create(
                      [
                      id(PengineId),
                      at_exit(format('Adios!~n',[]))
                      ]).

Running the above:

?- [attempt].
true.

?- attempt.
One can create 3 server/slave pengines
Created Pengine: '1e075589-33a0-4d7c-864b-834e1269d8ca'
Created Pengine: '14250aa2-4979-449d-8ea4-30fb23ccf125'
Created Pengine: 'b2e58c98-527d-4811-a4da-62b84ea93675'
Current threads
   main 1
   gc 2
   '__thread_pool_manager' 3
   <thread>(4,0x7f5b08025780) 4
   <thread>(5,0x7f5b080260d0) 5
   <thread>(6,0x7f5b0800a030) 6
There are 3 pengines
Adios!
Adios!
Adios!
There are 3 pengines
ERROR: Not enough resources: max_pengines

So, all the pengines exited, however, the system still thinks there are “not enough resources”.

Additionally, at some point I got the weird situation where format/2 wouldn’t print and just failed. I suppose some mutex hadn’t been cleared. I was unable to reproduce that though. On the terminal:

?- format("").
true.

?- format("",[]).
false.

?- help(format/2).
true.

?- format("",[]). 
false.

?- format("",[a]).
false.

The damnedest thing.

Not really checked, but I think you cannot use the at_exit option for creating pengines as this is used by the cleanup mechanism. The format issue could be coming from the fact that Pengines redefine the I/O predicates. That was all designed with remote pengines in mind. Local pengines have been out of fashion for a while. In most cases where you might want to use them engines are probably a way more efficient choice. These didn’t exist when Pengines were invented …