mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
Add persistent_term support to the router
This commit is contained in:
parent
7bccad4d21
commit
cf84f59d9b
5 changed files with 80 additions and 3 deletions
|
@ -210,13 +210,34 @@ Dispatch = cowboy_router:compile([
|
|||
%% {HostMatch, list({PathMatch, Handler, InitialState})}
|
||||
{'_', [{'_', my_handler, #{}}]}
|
||||
]),
|
||||
%% Name, NbAcceptors, TransOpts, ProtoOpts
|
||||
%% Name, TransOpts, ProtoOpts
|
||||
cowboy:start_clear(my_http_listener,
|
||||
[{port, 8080}],
|
||||
#{env => #{dispatch => Dispatch}}
|
||||
).
|
||||
----
|
||||
|
||||
=== Using persistent_term
|
||||
|
||||
The routes can be stored in `persistent_term` starting from
|
||||
Erlang/OTP 21.2. This may give a performance improvement when
|
||||
there are a large number of routes.
|
||||
|
||||
To use this functionality you need to compile the routes,
|
||||
store them in `persistent_term` and then inform Cowboy:
|
||||
|
||||
[source,erlang]
|
||||
----
|
||||
Dispatch = cowboy_router:compile([
|
||||
{'_', [{'_', my_handler, #{}}]}
|
||||
]),
|
||||
persistent_term:put(my_app_dispatch, Dispatch),
|
||||
cowboy:start_clear(my_http_listener,
|
||||
[{port, 8080}],
|
||||
#{env => #{dispatch => {persistent_term, my_app_dispatch}}}
|
||||
).
|
||||
----
|
||||
|
||||
=== Live update
|
||||
|
||||
You can use the `cowboy:set_env/3` function for updating the dispatch
|
||||
|
@ -228,3 +249,6 @@ Dispatch = cowboy_router:compile(Routes),
|
|||
cowboy:set_env(my_http_listener, dispatch, Dispatch).
|
||||
|
||||
Note that you need to compile the routes again before updating.
|
||||
|
||||
When using `persistent_term` there is no need to call this function,
|
||||
you can simply put the new routes in the storage.
|
||||
|
|
|
@ -13,7 +13,10 @@ The router takes the `dispatch` rules as input from the
|
|||
middleware environment. Dispatch rules are generated by
|
||||
calling the
|
||||
link:man:cowboy_router:compile(3)[cowboy_router:compile(3)]
|
||||
function.
|
||||
function. The environment can contain the rules directly
|
||||
or a tuple `{persistent_term, Key}`, in which case Cowboy
|
||||
will call `persistent_term:get(Key)` to retrieve the
|
||||
dispatch rules.
|
||||
|
||||
When a route matches, the router sets the `handler` and
|
||||
`handler_opts` middleware environment values containing
|
||||
|
|
|
@ -160,7 +160,11 @@ compile_brackets_split(<< C, Rest/bits >>, Acc, N) ->
|
|||
-spec execute(Req, Env)
|
||||
-> {ok, Req, Env} | {stop, Req}
|
||||
when Req::cowboy_req:req(), Env::cowboy_middleware:env().
|
||||
execute(Req=#{host := Host, path := Path}, Env=#{dispatch := Dispatch}) ->
|
||||
execute(Req=#{host := Host, path := Path}, Env=#{dispatch := Dispatch0}) ->
|
||||
Dispatch = case Dispatch0 of
|
||||
{persistent_term, Key} -> persistent_term:get(Key);
|
||||
_ -> Dispatch0
|
||||
end,
|
||||
case match(Dispatch, Host, Path) of
|
||||
{ok, Handler, HandlerOpts, Bindings, HostInfo, PathInfo} ->
|
||||
{ok, Req#{
|
||||
|
|
|
@ -196,6 +196,29 @@ max_frame_size_sent(Config) ->
|
|||
cowboy:stop_listener(?FUNCTION_NAME)
|
||||
end.
|
||||
|
||||
persistent_term_router(Config) ->
|
||||
doc("The router can retrieve the routes from persistent_term storage."),
|
||||
case erlang:function_exported(persistent_term, get, 1) of
|
||||
true -> do_persistent_term_router(Config);
|
||||
false -> {skip, "This test uses the persistent_term functionality added in Erlang/OTP 21.2."}
|
||||
end.
|
||||
|
||||
do_persistent_term_router(Config) ->
|
||||
persistent_term:put(?FUNCTION_NAME, init_dispatch(Config)),
|
||||
{ok, _} = cowboy:start_clear(?FUNCTION_NAME, [{port, 0}], #{
|
||||
env => #{dispatch => {persistent_term, ?FUNCTION_NAME}}
|
||||
}),
|
||||
Port = ranch:get_port(?FUNCTION_NAME),
|
||||
try
|
||||
ConnPid = gun_open([{type, tcp}, {protocol, http2}, {port, Port}|Config]),
|
||||
{ok, http2} = gun:await_up(ConnPid),
|
||||
StreamRef = gun:get(ConnPid, "/"),
|
||||
{response, nofin, 200, _} = gun:await(ConnPid, StreamRef),
|
||||
gun:close(ConnPid)
|
||||
after
|
||||
cowboy:stop_listener(?FUNCTION_NAME)
|
||||
end.
|
||||
|
||||
preface_timeout_infinity(Config) ->
|
||||
doc("Ensure infinity for preface_timeout is accepted."),
|
||||
ProtoOpts = #{
|
||||
|
|
|
@ -250,6 +250,29 @@ idle_timeout_infinity(Config) ->
|
|||
cowboy:stop_listener(?FUNCTION_NAME)
|
||||
end.
|
||||
|
||||
persistent_term_router(Config) ->
|
||||
doc("The router can retrieve the routes from persistent_term storage."),
|
||||
case erlang:function_exported(persistent_term, get, 1) of
|
||||
true -> do_persistent_term_router(Config);
|
||||
false -> {skip, "This test uses the persistent_term functionality added in Erlang/OTP 21.2."}
|
||||
end.
|
||||
|
||||
do_persistent_term_router(Config) ->
|
||||
persistent_term:put(?FUNCTION_NAME, init_dispatch(Config)),
|
||||
{ok, _} = cowboy:start_clear(?FUNCTION_NAME, [{port, 0}], #{
|
||||
env => #{dispatch => {persistent_term, ?FUNCTION_NAME}}
|
||||
}),
|
||||
Port = ranch:get_port(?FUNCTION_NAME),
|
||||
try
|
||||
ConnPid = gun_open([{type, tcp}, {protocol, http}, {port, Port}|Config]),
|
||||
{ok, http} = gun:await_up(ConnPid),
|
||||
StreamRef = gun:get(ConnPid, "/"),
|
||||
{response, nofin, 200, _} = gun:await(ConnPid, StreamRef),
|
||||
gun:close(ConnPid)
|
||||
after
|
||||
cowboy:stop_listener(?FUNCTION_NAME)
|
||||
end.
|
||||
|
||||
request_timeout_infinity(Config) ->
|
||||
doc("Ensure the request_timeout option accepts the infinity value."),
|
||||
{ok, _} = cowboy:start_clear(?FUNCTION_NAME, [{port, 0}], #{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue