zadean / xqerl

Erlang XQuery 3.1 Processor

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Stop, start xqerl service fails to maintain restXQ state.

grantmacken opened this issue · comments

If I don't recompile, after restarting xqerl my previously compiled restXQ routes don't resolve.
e.g. A restarted xqerl service, where the restXQ file has been previously compiled.

> curl -v http://example.com:8081
*   Trying 127.0.0.1:8081...
* Connected to example.com (127.0.0.1) port 8081 (#0)
> GET / HTTP/1.1
> Host: example.com:8081
> User-Agent: curl/7.79.1
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 500 Internal Server Error
< content-length: 0

And from the journalctl logged error from this request.

> journalctl -f --output cat -u  xqerl
                         id => xqerl_handler,level => all,
                         module => logger_std_h},
                       #{}]}},
              {restart_type,temporary},
              {significant,false},
              {shutdown,2000},
              {child_type,worker}]
=PROGRESS REPORT==== 8-Nov-2021::15:05:20.198954 ===
    application: xqerl
    started_at: 'xqerl@127.0.0.1'
=CRASH REPORT==== 8-Nov-2021::15:06:22.320919 ===
  crasher:
    initial call: cowboy_stream_h:request_process/3
    pid: <0.1010.0>
    registered_name: []
    exception error: undefined function 'http___example.com_#routes':init/2
      in function  cowboy_handler:execute/2 (/home/gmack/projects/grantmacken/xqerl/_build/default/lib/cowboy/src/cowboy_handler.erl, line 37)
      in call from cowboy_stream_h:execute/3 (/home/gmack/projects/grantmacken/xqerl/_build/default/lib/cowboy/src/cowboy_stream_h.erl, line 306)
      in call from cowboy_stream_h:request_process/3 (/home/gmack/projects/grantmacken/xqerl/_build/default/lib/cowboy/src/cowboy_stream_h.erl, line 295)
    ancestors: [<0.1009.0>,<0.964.0>,<0.962.0>,<0.961.0>,ranch_sup,
                  <0.907.0>]
    message_queue_len: 0
    messages: []
    links: [<0.1009.0>]
    dictionary: []
    trap_exit: false
    status: running
    heap_size: 987
    stack_size: 29
    reductions: 316
  neighbours:
=ERROR REPORT==== 8-Nov-2021::15:06:22.321711 ===
Ranch listener xqerl_listener, connection process <0.1009.0>, stream 1 had its request process <0.1010.0> exit with reason undef and stacktrace [{'http___example.com_#routes',init,[#{bindings => #{},body_length => 0,cert => undefined,has_body => false,headers => #{<<"accept">> => <<"*/*">>,<<"host">> => <<"example.com:8081">>,<<"user-agent">> => <<"curl/7.79.1">>},host => <<"example.com">>,host_info => undefined,method => <<"GET">>,path => <<"/">>,path_info => undefined,peer => {{127,0,0,1},35958},pid => <0.1009.0>,port => 8081,qs => <<>>,ref => xqerl_listener,scheme => <<"http">>,sock => {{127,0,0,1},8081},streamid => 1,version => 'HTTP/1.1'},#{get => #{input_media_types => [{'*',rest_wrap__22}],output_media_types => [{{<<"text">>,<<"html">>,[]},rest_wrap__22}]},head => #{input_media_types => [{'*',rest_wrap__22}],output_media_types => [{{<<"text">>,<<"html">>,[]},rest_wrap__22}]}}],[]},{cowboy_handler,execute,2,[{file,"/home/gmack/projects/grantmacken/xqerl/_build/default/lib/cowboy/src/cowboy_handler.erl"},{line,37}]},{cowboy_stream_h,execute,3,[{file,"/home/gmack/projects/grantmacken/xqerl/_build/default/lib/cowboy/src/cowboy_stream_h.erl"},{line,306}]},{cowboy_stream_h,request_process,3,[{file,"/home/gmack/projects/grantmacken/xqerl/_build/default/lib/cowboy/src/cowboy_stream_h.erl"},{line,295}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,226}]}]

As can be seen above the ranch listener knows about the compiled restXQ routes and the rest_wrap function

If I compile the file again.

(xqerl@127.0.0.1)1> xqerl:compile("/home/gmack/projects/grantmacken/podx/src/code/routes.xqm").

Then the restXQ routes are resolved.

 curl -v http://example.com:8081
*   Trying 127.0.0.1:8081...
* Connected to example.com (127.0.0.1) port 8081 (#0)
> GET / HTTP/1.1
> Host: example.com:8081
> User-Agent: curl/7.79.1
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-length: 180
< content-type: text/html
< date: Mon, 08 Nov 2021 02:22:10 GMT
< server: Cowboy
< 
<!DOCTYPE html>
* Connection #0 to host example.com left intact
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>nowhere</title></head>

Hmmm. I've seen this too and thought it was something on my local...

I'll take a look ( unless someone beats me to it :-) ). Guessing it has something to do with the routes being written to file and that not being loaded in the correct order on start up.

I have been reading up on and playing with cowboy rest handlers.
Apart from compiled restXQ files the xqerl code server does not need the cowboy http service to be running .
Without the http service due to the xqerl_code_server magic, any user compiled xquery library MFAs (module, function, args) will still be callable. The cowboy http service could supervised as a separate concern under the xqerl app.
Cowboy HTTP request routes could be defined dynamical via calling something like routes:register/1 and routes:unregister/1,
which would compile the restXQ file into cowboy routes.

restXQ is a convenient way to map a http request and the rest constraints to the restxq module signatures, however this HTTP route to xquery MFA mapping could be also defined in user defined cowboy handlers modules or even in escript after the xqerl service starts.

The default cowboy http service could provide a default static files handler for the priv dir.
So when a user starts an xqerl app, without any configuration.
http://localhost:8081 will resolve to a xqerl greeting from
'priv/static/assets/index.html'.

I think that #40 will fix the need to recompile things on restart. For some reason the code path xqerl uses isn't being checked for beam files.

Thanks, will I will clone and try later on.