Просмотр исходного кода

feat(quic): conditionally build/start quicer app

William Yang 4 лет назад
Родитель
Сommit
1f20bae392

+ 0 - 1
apps/emqx/rebar.config

@@ -20,7 +20,6 @@
     , {pbkdf2, {git, "https://github.com/emqx/erlang-pbkdf2.git", {branch, "2.0.4"}}}
     , {recon, {git, "https://github.com/ferd/recon", {tag, "2.5.1"}}}
     , {snabbkaffe, {git, "https://github.com/kafka4beam/snabbkaffe.git", {tag, "0.13.0"}}}
-    , {quicer, {git, "https://github.com/emqx/quic.git", {tag, "0.0.5"}}}
     ]}.
 
 {plugins, [rebar3_proper]}.

+ 29 - 10
apps/emqx/rebar.config.script

@@ -1,11 +1,30 @@
+IsCentos6 = fun() ->
+                case file:read_file("/etc/centos-release") of
+                    {ok, <<"CentOS release 6", _/binary >>} ->
+                        true;
+                    _ ->
+                        false
+                end
+            end,
+
+IsWin32 = fun() ->
+                win32 =:= element(1, os:type())
+          end,
+
+IsQuicSupp = fun() ->
+                not (IsCentos6() orelse IsWin32() orelse
+                     false =/= os:getenv("EMQX_BUILD_WITHOUT_QUIC")
+                    )
+             end,
+
 Bcrypt = {bcrypt, {git, "https://github.com/emqx/erlang-bcrypt.git", {branch, "0.6.0"}}},
-AddBcrypt = fun(C) ->
-    {deps, Deps0} = lists:keyfind(deps, 1, C),
-    Deps = [Bcrypt | Deps0],
-    lists:keystore(deps, 1, C, {deps, Deps})
-end,
-
-case os:type() of
-    {win32, _} -> CONFIG;
-    _ -> AddBcrypt(CONFIG)
-end.
+Quicer = {quicer, {git, "https://github.com/emqx/quic.git", {branch, "main"}}},
+
+ExtraDeps = fun(C) ->
+                {deps, Deps0} = lists:keyfind(deps, 1, C),
+                Deps = Deps0 ++ [Bcrypt || not IsWin32()] ++
+                [ Quicer || IsQuicSupp()],
+                lists:keystore(deps, 1, C, {deps, Deps})
+            end,
+
+ExtraDeps(CONFIG).

+ 1 - 1
apps/emqx/src/emqx.app.src

@@ -4,7 +4,7 @@
   {vsn, "5.0.0"}, % strict semver, bump manually!
   {modules, []},
   {registered, []},
-  {applications, [kernel,stdlib,gproc,gen_rpc,esockd,cowboy,sasl,os_mon,quicer,jiffy]},
+  {applications, [kernel,stdlib,gproc,gen_rpc,esockd,cowboy,sasl,os_mon,jiffy]},
   {mod, {emqx_app,[]}},
   {env, []},
   {licenses, ["Apache-2.0"]},

+ 2 - 0
apps/emqx/src/emqx_app.erl

@@ -49,6 +49,8 @@ start(_Type, _Args) ->
     _ = load_ce_modules(),
     ekka:start(),
     ok = ekka_rlog:wait_for_shards(?EMQX_SHARDS, infinity),
+    false == os:getenv("EMQX_NO_QUIC")
+        andalso application:ensure_all_started(quicer),
     {ok, Sup} = emqx_sup:start_link(),
     ok = start_autocluster(),
     % ok = emqx_plugins:init(),

+ 29 - 19
apps/emqx/src/emqx_listeners.erl

@@ -106,6 +106,8 @@ format_listen_on(ListenOn) -> format(ListenOn).
 start_listener(#{proto := Proto, name := Name, listen_on := ListenOn, opts := Options}) ->
     ID = identifier(Proto, Name),
     case start_listener(Proto, ListenOn, Options) of
+        {ok, skipped} ->
+            console_print("Start ~s listener on ~s skpped.~n", [ID, format(ListenOn)]);
         {ok, _} ->
             console_print("Start ~s listener on ~s successfully.~n", [ID, format(ListenOn)]);
         {error, Reason} ->
@@ -123,7 +125,7 @@ console_print(_Fmt, _Args) -> ok.
 
 %% Start MQTT/TCP listener
 -spec(start_listener(esockd:proto(), esockd:listen_on(), [esockd:option()])
-      -> {ok, pid()} | {error, term()}).
+      -> {ok, pid() | skipped} | {error, term()}).
 start_listener(tcp, ListenOn, Options) ->
     start_mqtt_listener('mqtt:tcp', ListenOn, Options);
 
@@ -143,24 +145,32 @@ start_listener(Proto, ListenOn, Options) when Proto == https; Proto == wss ->
 
 %% Start MQTT/QUIC listener
 start_listener(quic, ListenOn, Options) ->
-    %% @fixme unsure why we need reopen lib and reopen config.
-    quicer_nif:open_lib(),
-    quicer_nif:reg_open(),
-    SSLOpts = proplists:get_value(ssl_options, Options),
-    DefAcceptors = erlang:system_info(schedulers_online) * 8,
-    ListenOpts = [ {cert, proplists:get_value(certfile, SSLOpts)}
-                 , {key, proplists:get_value(keyfile, SSLOpts)}
-                 , {alpn, ["mqtt"]}
-                 , {conn_acceptors, proplists:get_value(acceptors, Options, DefAcceptors)}
-                 , {idle_timeout_ms, proplists:get_value(idle_timeout, Options, 60000)}
-                 ],
-    ConnectionOpts = [ {conn_callback, emqx_quic_connection}
-                     , {peer_unidi_stream_count, 1}
-                     , {peer_bidi_stream_count, 10}
-                       | Options
-                     ],
-    StreamOpts = [],
-    quicer:start_listener('mqtt:quic', ListenOn, {ListenOpts, ConnectionOpts, StreamOpts}).
+    IsQuicEnabled = false == os:getenv("EMQX_NO_QUIC"),
+    case [ A || {quicer, _, _} = A<-application:which_applications() ] of
+        [_] when IsQuicEnabled ->
+            %% @fixme unsure why we need reopen lib and reopen config.
+            quicer_nif:open_lib(),
+            quicer_nif:reg_open(),
+            SSLOpts = proplists:get_value(ssl_options, Options),
+            DefAcceptors = erlang:system_info(schedulers_online) * 8,
+            ListenOpts = [ {cert, proplists:get_value(certfile, SSLOpts)}
+                         , {key, proplists:get_value(keyfile, SSLOpts)}
+                         , {alpn, ["mqtt"]}
+                         , {conn_acceptors, proplists:get_value(acceptors, Options, DefAcceptors)}
+                         , {idle_timeout_ms, proplists:get_value(idle_timeout, Options, 60000)}
+                         ],
+            ConnectionOpts = [ {conn_callback, emqx_quic_connection}
+                             , {peer_unidi_stream_count, 1}
+                             , {peer_bidi_stream_count, 10}
+                             | Options
+                             ],
+            StreamOpts = [],
+            quicer:start_listener('mqtt:quic', ListenOn, {ListenOpts, ConnectionOpts, StreamOpts});
+        [] ->
+            io:format(standard_error, "INFO: quicer application is unavailable/disabled~n",
+                      []),
+            {ok, skipped}
+    end.
 
 replace(Opts, Key, Value) -> [{Key, Value} | proplists:delete(Key, Opts)].
 

+ 0 - 2
rebar.config

@@ -63,8 +63,6 @@
     , {snabbkaffe, {git, "https://github.com/kafka4beam/snabbkaffe.git", {tag, "0.13.0"}}}
     , {hocon, {git, "https://github.com/emqx/hocon.git", {tag, "0.9.0"}}}
     , {emqx_http_lib, {git, "https://github.com/emqx/emqx_http_lib.git", {tag, "0.2.1"}}}
-    %, {quicer, {git, "https://github.com/emqx/quic.git", {tag, "0.0.5"}}}
-    , {quicer, {git, "https://github.com/emqx/quic.git", {branch, "main"}}}
     ]}.
 
 {xref_ignores,

+ 25 - 5
rebar.config.erl

@@ -15,12 +15,14 @@ do(Dir, CONFIG) ->
 bcrypt() ->
     {bcrypt, {git, "https://github.com/emqx/erlang-bcrypt.git", {branch, "0.6.0"}}}.
 
+quicer() ->
+    %% @todo use tag
+    {quicer, {git, "https://github.com/emqx/quic.git", {branch, "main"}}}.
+
 deps(Config) ->
     {deps, OldDeps} = lists:keyfind(deps, 1, Config),
-    MoreDeps = case provide_bcrypt_dep() of
-        true -> [bcrypt()];
-        false -> []
-    end,
+    MoreDeps = [bcrypt() || provide_bcrypt_dep()] ++
+        [quicer() || is_quicer_supported()],
     {HasElixir, ExtraDeps} = extra_deps(),
     {HasElixir, lists:keystore(deps, 1, Config, {deps, OldDeps ++ MoreDeps ++ ExtraDeps})}.
 
@@ -78,6 +80,24 @@ is_cover_enabled() ->
 is_enterprise() ->
     filelib:is_regular("EMQX_ENTERPRISE").
 
+is_quicer_supported() ->
+    not (false =/= os:getenv("BUILD_WITHOUT_QUIC") orelse
+         is_win32() orelse is_centos_6()
+        ).
+
+is_centos_6() ->
+    %% reason:
+    %% glibc is too old
+    case file:read_file("/etc/centos-release") of
+        {ok, <<"CentOS release 6", _/binary >>} ->
+            true;
+        _ ->
+            false
+    end.
+
+is_win32() ->
+    win32 =:= element(1, os:type()).
+
 project_app_dirs() ->
     ["apps/*"] ++
     case is_enterprise() of
@@ -242,7 +262,6 @@ relx_apps(ReleaseType) ->
     , compiler
     , runtime_tools
     , cuttlefish
-    , quicer
     , emqx
     , {mnesia, load}
     , {ekka, load}
@@ -263,6 +282,7 @@ relx_apps(ReleaseType) ->
     , emqx_retainer
     , emqx_statsd
     ]
+    ++ [quicer || is_quicer_supported()]
     ++ [emqx_telemetry || not is_enterprise()]
     ++ [emqx_license || is_enterprise()]
     ++ [bcrypt || provide_bcrypt_release(ReleaseType)]