HTTP, engines and timeouts

Because of some strange interaction between http and engines, the following very simple server

:- use_module(library(http/http_server)).
:- use_module(library(http/http_error)).

:- http_handler(root(test), test, []). 

test(_Request) :-
    engine_create(X, p(X), ID),
    engine_next(ID, A),
    format('Content-type: text/plain; charset=UTF-8~n~n'),
    writeln(A).
    
p(a).

:- http_server(http_dispatch, [port(3010)]).

either throws

Domain error: `alarm' expected, found `'$alarm'(1007232)'

or crashes SWI-Prolog when a request comes in:

SWI-Prolog [thread 10 () at Tue Dec 17 17:37:02 2019]: received fatal signal 11 (segv)
C-stack trace labeled "crash":
  [0] /Applications/SWI-Prolog.app/Contents/Frameworks/libswipl.8.1.15.dylib(save_backtrace+0xee) [0x10e0b1d3e]
  [1] /Applications/SWI-Prolog.app/Contents/Frameworks/libswipl.8.1.15.dylib(sigCrashHandler+0xad) [0x10e0b235d]
  [2] /Applications/SWI-Prolog.app/Contents/Frameworks/libswipl.8.1.15.dylib(dispatch_signal+0x236) [0x10e0325c6]
  [3] /usr/lib/system/libsystem_platform.dylib(_sigtramp+0x1d) [0x7fff6d1e6b5d]
  [5] /Applications/SWI-Prolog.app/Contents/Frameworks/libswipl.8.1.15.dylib(PL_next_solution+0xd634) [0x10dfafff4]
  [6] /Applications/SWI-Prolog.app/Contents/Frameworks/libswipl.8.1.15.dylib(callCleanupHandler+0x364) [0x10dfcb404]
  [7] /Applications/SWI-Prolog.app/Contents/Frameworks/libswipl.8.1.15.dylib(PL_next_solution+0xe474) [0x10dfb0e34]
  [8] /Applications/SWI-Prolog.app/Contents/Frameworks/libswipl.8.1.15.dylib(callProlog+0x15a) [0x10e00f54a]
  [9] /Applications/SWI-Prolog.app/Contents/Frameworks/libswipl.8.1.15.dylib(start_thread+0x20d) [0x10e04bf7d]
  [10] /usr/lib/system/libsystem_pthread.dylib(_pthread_body+0x7e) [0x7fff6d1ef2eb]
  [11] /usr/lib/system/libsystem_pthread.dylib(_pthread_start+0x42) [0x7fff6d1f2249]
  [12] /usr/lib/system/libsystem_pthread.dylib(thread_start+0xd) [0x7fff6d1ee40d]
Running on_halt hooks with status 139
Killing 40764 with default signal handlers
Segmentation fault: 11

@jan once said something about engines and timeouts not playing nicely, so I tried to set time_limit to infinite, like so

:- http_handler(root(test), test, [time_limit(infinite)]).

and that did indeed fix the problem. Two questions:

  1. Is this an SWI-Prolog bug that can be fixed, or is it something that comes with the way engines work?

  2. If not a bug, what if I want a time limit? Is there still a way to have that?

I don’t know …

It might in general make sense to do the time limitation inside the engine, the same way we do that in Pengines and to not apply time limits in the HTTP part. A running engine should be happy to work with time limits and can use the timeout option of thread_get_message/3 to act on lack of communication (the idle limit for Pengines). I think a timeout inside an engine should work fine as long as you do not yield while inside the limited goal.

Thanks Jan, I will think about this for a while… :slight_smile:

See https://github.com/SWI-Prolog/swipl-devel/issues/638