chore: use `timeout_duration` types for timer fields

Fixes https://emqx.atlassian.net/browse/EMQX-10020
This commit is contained in:
Thales Macedo Garitezi 2023-06-02 12:41:21 -03:00
parent 9bd37937f1
commit 46393343e2
35 changed files with 190 additions and 61 deletions

View File

@ -187,7 +187,7 @@ fields(client_opts) ->
)}, )},
{max_retry_time, {max_retry_time,
?HOCON( ?HOCON(
emqx_schema:duration(), emqx_schema:timeout_duration(),
#{ #{
desc => ?DESC(max_retry_time), desc => ?DESC(max_retry_time),
default => <<"1h">>, default => <<"1h">>,

View File

@ -1056,7 +1056,7 @@ fields("mqtt_quic_listener") ->
)}, )},
{"idle_timeout", {"idle_timeout",
sc( sc(
duration_ms(), timeout_duration_ms(),
#{ #{
default => 0, default => 0,
desc => ?DESC(fields_mqtt_quic_listener_idle_timeout), desc => ?DESC(fields_mqtt_quic_listener_idle_timeout),
@ -1073,7 +1073,7 @@ fields("mqtt_quic_listener") ->
)}, )},
{"handshake_idle_timeout", {"handshake_idle_timeout",
sc( sc(
duration_ms(), timeout_duration_ms(),
#{ #{
default => <<"10s">>, default => <<"10s">>,
desc => ?DESC(fields_mqtt_quic_listener_handshake_idle_timeout), desc => ?DESC(fields_mqtt_quic_listener_handshake_idle_timeout),
@ -1090,7 +1090,7 @@ fields("mqtt_quic_listener") ->
)}, )},
{"keep_alive_interval", {"keep_alive_interval",
sc( sc(
duration_ms(), timeout_duration_ms(),
#{ #{
default => 0, default => 0,
desc => ?DESC(fields_mqtt_quic_listener_keep_alive_interval), desc => ?DESC(fields_mqtt_quic_listener_keep_alive_interval),

View File

@ -93,7 +93,7 @@ fields(config) ->
)}, )},
{connect_timeout, {connect_timeout,
hoconsc:mk( hoconsc:mk(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
default => <<"15s">>, default => <<"15s">>,
desc => ?DESC("connect_timeout") desc => ?DESC("connect_timeout")

View File

@ -47,7 +47,7 @@ fields(bridge_config) ->
[ [
{connect_timeout, {connect_timeout,
sc( sc(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
default => <<"15s">>, default => <<"15s">>,
desc => ?DESC("connect_timeout") desc => ?DESC("connect_timeout")
@ -80,7 +80,7 @@ fields(bridge_config) ->
)}, )},
{request_timeout, {request_timeout,
sc( sc(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
required => false, required => false,
deprecated => {since, "e5.0.1"}, deprecated => {since, "e5.0.1"},

View File

@ -144,7 +144,7 @@ request_config() ->
)}, )},
{request_timeout, {request_timeout,
mk( mk(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
default => <<"15s">>, default => <<"15s">>,
desc => ?DESC("config_request_timeout") desc => ?DESC("config_request_timeout")

View File

@ -165,20 +165,20 @@ fields("config") ->
} }
)}, )},
{connect_timeout, {connect_timeout,
mk(emqx_schema:duration_ms(), #{ mk(emqx_schema:timeout_duration_ms(), #{
default => <<"5s">>, default => <<"5s">>,
desc => ?DESC(connect_timeout) desc => ?DESC(connect_timeout)
})}, })},
{min_metadata_refresh_interval, {min_metadata_refresh_interval,
mk( mk(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
default => <<"3s">>, default => <<"3s">>,
desc => ?DESC(min_metadata_refresh_interval) desc => ?DESC(min_metadata_refresh_interval)
} }
)}, )},
{metadata_request_timeout, {metadata_request_timeout,
mk(emqx_schema:duration_ms(), #{ mk(emqx_schema:timeout_duration_ms(), #{
default => <<"5s">>, default => <<"5s">>,
desc => ?DESC(metadata_request_timeout) desc => ?DESC(metadata_request_timeout)
})}, })},

View File

@ -62,7 +62,7 @@ fields(config) ->
)}, )},
{connect_timeout, {connect_timeout,
mk( mk(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
default => <<"5s">>, default => <<"5s">>,
desc => ?DESC("connect_timeout") desc => ?DESC("connect_timeout")
@ -86,11 +86,12 @@ fields(producer_opts) ->
default => <<"1MB">>, desc => ?DESC("producer_send_buffer") default => <<"1MB">>, desc => ?DESC("producer_send_buffer")
})}, })},
{sync_timeout, {sync_timeout,
mk(emqx_schema:duration_ms(), #{ mk(emqx_schema:timeout_duration_ms(), #{
default => <<"3s">>, desc => ?DESC("producer_sync_timeout") default => <<"3s">>, desc => ?DESC("producer_sync_timeout")
})}, })},
{retention_period, {retention_period,
mk( mk(
%% not used in a `receive ... after' block, just timestamp comparison
hoconsc:union([infinity, emqx_schema:duration_ms()]), hoconsc:union([infinity, emqx_schema:duration_ms()]),
#{default => infinity, desc => ?DESC("producer_retention_period")} #{default => infinity, desc => ?DESC("producer_retention_period")}
)}, )},

View File

@ -84,7 +84,7 @@ fields(config) ->
)}, )},
{timeout, {timeout,
hoconsc:mk( hoconsc:mk(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
default => <<"5s">>, default => <<"5s">>,
desc => ?DESC("timeout") desc => ?DESC("timeout")
@ -100,7 +100,7 @@ fields(config) ->
)}, )},
{publish_confirmation_timeout, {publish_confirmation_timeout,
hoconsc:mk( hoconsc:mk(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
default => <<"30s">>, default => <<"30s">>,
desc => ?DESC("timeout") desc => ?DESC("timeout")
@ -117,7 +117,7 @@ fields(config) ->
)}, )},
{heartbeat, {heartbeat,
hoconsc:mk( hoconsc:mk(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
default => <<"30s">>, default => <<"30s">>,
desc => ?DESC("heartbeat") desc => ?DESC("heartbeat")

View File

@ -58,12 +58,12 @@ fields(config) ->
mk(binary(), #{default => <<>>, desc => ?DESC(security_token), sensitive => true})}, mk(binary(), #{default => <<>>, desc => ?DESC(security_token), sensitive => true})},
{sync_timeout, {sync_timeout,
mk( mk(
emqx_schema:duration(), emqx_schema:timeout_duration(),
#{default => <<"3s">>, desc => ?DESC(sync_timeout)} #{default => <<"3s">>, desc => ?DESC(sync_timeout)}
)}, )},
{refresh_interval, {refresh_interval,
mk( mk(
emqx_schema:duration(), emqx_schema:timeout_duration(),
#{default => <<"3s">>, desc => ?DESC(refresh_interval)} #{default => <<"3s">>, desc => ?DESC(refresh_interval)}
)}, )},
{send_buffer, {send_buffer,

View File

@ -528,7 +528,7 @@ fields("node") ->
)}, )},
{"crash_dump_seconds", {"crash_dump_seconds",
sc( sc(
emqx_schema:duration_s(), emqx_schema:timeout_duration_s(),
#{ #{
mapping => "vm_args.-env ERL_CRASH_DUMP_SECONDS", mapping => "vm_args.-env ERL_CRASH_DUMP_SECONDS",
default => <<"30s">>, default => <<"30s">>,
@ -550,7 +550,7 @@ fields("node") ->
)}, )},
{"dist_net_ticktime", {"dist_net_ticktime",
sc( sc(
emqx_schema:duration_s(), emqx_schema:timeout_duration_s(),
#{ #{
mapping => "vm_args.-kernel net_ticktime", mapping => "vm_args.-kernel net_ticktime",
default => <<"2m">>, default => <<"2m">>,
@ -821,7 +821,7 @@ fields("rpc") ->
)}, )},
{"socket_keepalive_idle", {"socket_keepalive_idle",
sc( sc(
emqx_schema:duration_s(), emqx_schema:timeout_duration_s(),
#{ #{
mapping => "gen_rpc.socket_keepalive_idle", mapping => "gen_rpc.socket_keepalive_idle",
default => <<"15m">>, default => <<"15m">>,
@ -830,7 +830,7 @@ fields("rpc") ->
)}, )},
{"socket_keepalive_interval", {"socket_keepalive_interval",
sc( sc(
emqx_schema:duration_s(), emqx_schema:timeout_duration_s(),
#{ #{
mapping => "gen_rpc.socket_keepalive_interval", mapping => "gen_rpc.socket_keepalive_interval",
default => <<"75s">>, default => <<"75s">>,
@ -972,7 +972,7 @@ fields("log_overload_kill") ->
)}, )},
{"restart_after", {"restart_after",
sc( sc(
hoconsc:union([emqx_schema:duration_ms(), infinity]), hoconsc:union([emqx_schema:timeout_duration_ms(), infinity]),
#{ #{
default => <<"5s">>, default => <<"5s">>,
desc => ?DESC("log_overload_kill_restart_after") desc => ?DESC("log_overload_kill_restart_after")

View File

@ -67,7 +67,7 @@ fields(config) ->
[ [
{connect_timeout, {connect_timeout,
sc( sc(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
default => <<"15s">>, default => <<"15s">>,
desc => ?DESC("connect_timeout") desc => ?DESC("connect_timeout")
@ -80,7 +80,7 @@ fields(config) ->
)}, )},
{retry_interval, {retry_interval,
sc( sc(
emqx_schema:duration(), emqx_schema:timeout_duration(),
#{deprecated => {since, "5.0.4"}} #{deprecated => {since, "5.0.4"}}
)}, )},
{pool_type, {pool_type,
@ -138,7 +138,7 @@ fields("request") ->
)}, )},
{request_timeout, {request_timeout,
sc( sc(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
required => false, required => false,
desc => ?DESC("request_timeout") desc => ?DESC("request_timeout")

View File

@ -201,5 +201,5 @@ port(type) -> integer();
port(default) -> 389; port(default) -> 389;
port(_) -> undefined. port(_) -> undefined.
duration(type) -> emqx_schema:duration_ms(); duration(type) -> emqx_schema:timeout_duration_ms();
duration(_) -> undefined. duration(_) -> undefined.

View File

@ -108,7 +108,7 @@ fields(topology) ->
{wait_queue_timeout_ms, duration("wait_queue_timeout")}, {wait_queue_timeout_ms, duration("wait_queue_timeout")},
{heartbeat_frequency_ms, {heartbeat_frequency_ms,
hoconsc:mk( hoconsc:mk(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
default => <<"200s">>, default => <<"200s">>,
desc => ?DESC("heartbeat_period") desc => ?DESC("heartbeat_period")
@ -422,7 +422,7 @@ r_mode(_) -> undefined.
duration(Desc) -> duration(Desc) ->
#{ #{
type => emqx_schema:duration_ms(), type => emqx_schema:timeout_duration_ms(),
required => false, required => false,
desc => ?DESC(Desc) desc => ?DESC(Desc)
}. }.

View File

@ -38,7 +38,7 @@ fields("dashboard") ->
{default_password, fun default_password/1}, {default_password, fun default_password/1},
{sample_interval, {sample_interval,
?HOCON( ?HOCON(
emqx_schema:duration_s(), emqx_schema:timeout_duration_s(),
#{ #{
default => <<"10s">>, default => <<"10s">>,
desc => ?DESC(sample_interval), desc => ?DESC(sample_interval),

View File

@ -829,6 +829,12 @@ typename_to_spec("duration_s()", _Mod) ->
#{type => string, example => <<"1h">>}; #{type => string, example => <<"1h">>};
typename_to_spec("duration_ms()", _Mod) -> typename_to_spec("duration_ms()", _Mod) ->
#{type => string, example => <<"32s">>}; #{type => string, example => <<"32s">>};
typename_to_spec("timeout_duration()", _Mod) ->
#{type => string, example => <<"12m">>};
typename_to_spec("timeout_duration_s()", _Mod) ->
#{type => string, example => <<"1h">>};
typename_to_spec("timeout_duration_ms()", _Mod) ->
#{type => string, example => <<"32s">>};
typename_to_spec("percent()", _Mod) -> typename_to_spec("percent()", _Mod) ->
#{type => number, example => <<"12%">>}; #{type => number, example => <<"12%">>};
typename_to_spec("file()", _Mod) -> typename_to_spec("file()", _Mod) ->

View File

@ -32,7 +32,7 @@ fields("root") ->
)}, )},
{default_username, fun default_username/1}, {default_username, fun default_username/1},
{default_password, fun default_password/1}, {default_password, fun default_password/1},
{sample_interval, mk(emqx_schema:duration_s(), #{default => <<"10s">>})}, {sample_interval, mk(emqx_schema:timeout_duration_s(), #{default => <<"10s">>})},
{token_expired_time, mk(emqx_schema:duration(), #{default => <<"30m">>})} {token_expired_time, mk(emqx_schema:duration(), #{default => <<"30m">>})}
]; ];
fields("ref1") -> fields("ref1") ->

View File

@ -751,7 +751,7 @@ schema("/object") ->
{per_page, mk(range(1, 100), #{required => true, desc => <<"good per page desc">>})}, {per_page, mk(range(1, 100), #{required => true, desc => <<"good per page desc">>})},
{timeout, {timeout,
mk( mk(
hoconsc:union([infinity, emqx_schema:duration_s()]), hoconsc:union([infinity, emqx_schema:timeout_duration_s()]),
#{default => 5, required => true} #{default => 5, required => true}
)}, )},
{inner_ref, mk(hoconsc:ref(?MODULE, good_ref), #{})} {inner_ref, mk(hoconsc:ref(?MODULE, good_ref), #{})}
@ -761,7 +761,7 @@ schema("/nest/object") ->
{per_page, mk(range(1, 100), #{desc => <<"good per page desc">>})}, {per_page, mk(range(1, 100), #{desc => <<"good per page desc">>})},
{timeout, {timeout,
mk( mk(
hoconsc:union([infinity, emqx_schema:duration_s()]), hoconsc:union([infinity, emqx_schema:timeout_duration_s()]),
#{default => 5, required => true} #{default => 5, required => true}
)}, )},
{nest_object, [ {nest_object, [
@ -785,7 +785,7 @@ schema("/ref/array/with/key") ->
{per_page, mk(range(1, 100), #{desc => <<"good per page desc">>})}, {per_page, mk(range(1, 100), #{desc => <<"good per page desc">>})},
{timeout, {timeout,
mk( mk(
hoconsc:union([infinity, emqx_schema:duration_s()]), hoconsc:union([infinity, emqx_schema:timeout_duration_s()]),
#{default => 5, required => true} #{default => 5, required => true}
)}, )},
{array_refs, mk(hoconsc:array(hoconsc:ref(?MODULE, good_ref)), #{})} {array_refs, mk(hoconsc:array(hoconsc:ref(?MODULE, good_ref)), #{})}

View File

@ -573,7 +573,7 @@ schema("/object") ->
{per_page, mk(range(1, 100), #{required => true, desc => <<"good per page desc">>})}, {per_page, mk(range(1, 100), #{required => true, desc => <<"good per page desc">>})},
{timeout, {timeout,
mk( mk(
hoconsc:union([infinity, emqx_schema:duration_s()]), hoconsc:union([infinity, emqx_schema:timeout_duration_s()]),
#{default => 5, required => true} #{default => 5, required => true}
)}, )},
{inner_ref, mk(hoconsc:ref(?MODULE, good_ref), #{})} {inner_ref, mk(hoconsc:ref(?MODULE, good_ref), #{})}
@ -584,7 +584,7 @@ schema("/nest/object") ->
{per_page, mk(range(1, 100), #{desc => <<"good per page desc">>})}, {per_page, mk(range(1, 100), #{desc => <<"good per page desc">>})},
{timeout, {timeout,
mk( mk(
hoconsc:union([infinity, emqx_schema:duration_s()]), hoconsc:union([infinity, emqx_schema:timeout_duration_s()]),
#{default => 5, required => true} #{default => 5, required => true}
)}, )},
{nest_object, [ {nest_object, [
@ -613,13 +613,14 @@ schema("/ref/array/with/key") ->
{per_page, mk(range(1, 100), #{desc => <<"good per page desc">>})}, {per_page, mk(range(1, 100), #{desc => <<"good per page desc">>})},
{timeout, {timeout,
mk( mk(
hoconsc:union([infinity, emqx_schema:duration_s()]), hoconsc:union([infinity, emqx_schema:timeout_duration_s()]),
#{default => 5, required => true} #{default => 5, required => true}
)}, )},
{assert, mk(float(), #{desc => <<"money">>})}, {assert, mk(float(), #{desc => <<"money">>})},
{number_ex, mk(number(), #{desc => <<"number example">>})}, {number_ex, mk(number(), #{desc => <<"number example">>})},
{percent_ex, mk(emqx_schema:percent(), #{desc => <<"percent example">>})}, {percent_ex, mk(emqx_schema:percent(), #{desc => <<"percent example">>})},
{duration_ms_ex, mk(emqx_schema:duration_ms(), #{desc => <<"duration ms example">>})}, {duration_ms_ex,
mk(emqx_schema:timeout_duration_ms(), #{desc => <<"duration ms example">>})},
{atom_ex, mk(atom(), #{desc => <<"atom ex">>})}, {atom_ex, mk(atom(), #{desc => <<"atom ex">>})},
{array_refs, mk(hoconsc:array(hoconsc:ref(?MODULE, good_ref)), #{})} {array_refs, mk(hoconsc:array(hoconsc:ref(?MODULE, good_ref)), #{})}
]); ]);

View File

@ -1,7 +1,7 @@
%% -*- mode: erlang -*- %% -*- mode: erlang -*-
{application, emqx_exhook, [ {application, emqx_exhook, [
{description, "EMQX Extension for Hook"}, {description, "EMQX Extension for Hook"},
{vsn, "5.0.12"}, {vsn, "5.0.13"},
{modules, []}, {modules, []},
{registered, []}, {registered, []},
{mod, {emqx_exhook_app, []}}, {mod, {emqx_exhook_app, []}},

View File

@ -63,7 +63,7 @@ fields(server) ->
example => <<"http://127.0.0.1:9000">> example => <<"http://127.0.0.1:9000">>
})}, })},
{request_timeout, {request_timeout,
?HOCON(emqx_schema:duration(), #{ ?HOCON(emqx_schema:timeout_duration(), #{
default => <<"5s">>, default => <<"5s">>,
desc => ?DESC(request_timeout) desc => ?DESC(request_timeout)
})}, })},
@ -74,7 +74,7 @@ fields(server) ->
default => #{<<"keepalive">> => true, <<"nodelay">> => true} default => #{<<"keepalive">> => true, <<"nodelay">> => true}
})}, })},
{auto_reconnect, {auto_reconnect,
?HOCON(hoconsc:union([false, emqx_schema:duration()]), #{ ?HOCON(hoconsc:union([false, emqx_schema:timeout_duration()]), #{
default => <<"60s">>, default => <<"60s">>,
desc => ?DESC(auto_reconnect) desc => ?DESC(auto_reconnect)
})}, })},

View File

@ -66,7 +66,7 @@ fields(file_transfer) ->
)}, )},
{init_timeout, {init_timeout,
mk( mk(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
desc => ?DESC("init_timeout"), desc => ?DESC("init_timeout"),
required => false, required => false,
@ -75,7 +75,7 @@ fields(file_transfer) ->
)}, )},
{store_segment_timeout, {store_segment_timeout,
mk( mk(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
desc => ?DESC("store_segment_timeout"), desc => ?DESC("store_segment_timeout"),
required => false, required => false,
@ -84,7 +84,7 @@ fields(file_transfer) ->
)}, )},
{assemble_timeout, {assemble_timeout,
mk( mk(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
desc => ?DESC("assemble_timeout"), desc => ?DESC("assemble_timeout"),
required => false, required => false,
@ -195,7 +195,7 @@ fields(local_storage_segments_gc) ->
[ [
{interval, {interval,
mk( mk(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
desc => ?DESC("storage_gc_interval"), desc => ?DESC("storage_gc_interval"),
required => false, required => false,
@ -204,6 +204,7 @@ fields(local_storage_segments_gc) ->
)}, )},
{maximum_segments_ttl, {maximum_segments_ttl,
mk( mk(
%% not used in a `receive ... after' block, just timestamp comparison
emqx_schema:duration_s(), emqx_schema:duration_s(),
#{ #{
desc => ?DESC("storage_gc_max_segments_ttl"), desc => ?DESC("storage_gc_max_segments_ttl"),
@ -213,6 +214,7 @@ fields(local_storage_segments_gc) ->
)}, )},
{minimum_segments_ttl, {minimum_segments_ttl,
mk( mk(
%% not used in a `receive ... after' block, just timestamp comparison
emqx_schema:duration_s(), emqx_schema:duration_s(),
#{ #{
desc => ?DESC("storage_gc_min_segments_ttl"), desc => ?DESC("storage_gc_min_segments_ttl"),

View File

@ -107,7 +107,7 @@ request_body() ->
[ [
{token, mk(binary(), #{desc => ?DESC(token)})}, {token, mk(binary(), #{desc => ?DESC(token)})},
{method, mk(enum([get, put, post, delete]), #{desc => ?DESC(method)})}, {method, mk(enum([get, put, post, delete]), #{desc => ?DESC(method)})},
{timeout, mk(emqx_schema:duration_ms(), #{desc => ?DESC(timeout)})}, {timeout, mk(emqx_schema:timeout_duration_ms(), #{desc => ?DESC(timeout)})},
{content_type, {content_type,
mk( mk(
enum(['text/plain', 'application/json', 'application/octet-stream']), enum(['text/plain', 'application/json', 'application/octet-stream']),

View File

@ -1,6 +1,6 @@
{application, emqx_node_rebalance, [ {application, emqx_node_rebalance, [
{description, "EMQX Node Rebalance"}, {description, "EMQX Node Rebalance"},
{vsn, "5.0.1"}, {vsn, "5.0.2"},
{registered, [ {registered, [
emqx_node_rebalance_sup, emqx_node_rebalance_sup,
emqx_node_rebalance, emqx_node_rebalance,

View File

@ -356,7 +356,7 @@ fields(rebalance_start) ->
[ [
{"wait_health_check", {"wait_health_check",
mk( mk(
emqx_schema:duration_s(), emqx_schema:timeout_duration_s(),
#{ #{
desc => ?DESC(wait_health_check), desc => ?DESC(wait_health_check),
required => false required => false
@ -414,7 +414,7 @@ fields(rebalance_start) ->
)}, )},
{"wait_takeover", {"wait_takeover",
mk( mk(
emqx_schema:duration_s(), emqx_schema:timeout_duration_s(),
#{ #{
desc => ?DESC(wait_takeover), desc => ?DESC(wait_takeover),
required => false required => false

View File

@ -2,7 +2,7 @@
{application, emqx_prometheus, [ {application, emqx_prometheus, [
{description, "Prometheus for EMQX"}, {description, "Prometheus for EMQX"},
% strict semver, bump manually! % strict semver, bump manually!
{vsn, "5.0.11"}, {vsn, "5.0.12"},
{modules, []}, {modules, []},
{registered, [emqx_prometheus_sup]}, {registered, [emqx_prometheus_sup]},
{applications, [kernel, stdlib, prometheus, emqx, emqx_management]}, {applications, [kernel, stdlib, prometheus, emqx, emqx_management]},

View File

@ -48,7 +48,7 @@ fields("prometheus") ->
)}, )},
{interval, {interval,
?HOCON( ?HOCON(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
default => <<"15s">>, default => <<"15s">>,
required => true, required => true,

View File

@ -76,18 +76,18 @@ worker_pool_size(default) -> ?WORKER_POOL_SIZE;
worker_pool_size(required) -> false; worker_pool_size(required) -> false;
worker_pool_size(_) -> undefined. worker_pool_size(_) -> undefined.
resume_interval(type) -> emqx_schema:duration_ms(); resume_interval(type) -> emqx_schema:timeout_duration_ms();
resume_interval(importance) -> ?IMPORTANCE_HIDDEN; resume_interval(importance) -> ?IMPORTANCE_HIDDEN;
resume_interval(desc) -> ?DESC("resume_interval"); resume_interval(desc) -> ?DESC("resume_interval");
resume_interval(required) -> false; resume_interval(required) -> false;
resume_interval(_) -> undefined. resume_interval(_) -> undefined.
metrics_flush_interval(type) -> emqx_schema:duration_ms(); metrics_flush_interval(type) -> emqx_schema:timeout_duration_ms();
metrics_flush_interval(importance) -> ?IMPORTANCE_HIDDEN; metrics_flush_interval(importance) -> ?IMPORTANCE_HIDDEN;
metrics_flush_interval(required) -> false; metrics_flush_interval(required) -> false;
metrics_flush_interval(_) -> undefined. metrics_flush_interval(_) -> undefined.
health_check_interval(type) -> emqx_schema:duration_ms(); health_check_interval(type) -> emqx_schema:timeout_duration_ms();
health_check_interval(desc) -> ?DESC("health_check_interval"); health_check_interval(desc) -> ?DESC("health_check_interval");
health_check_interval(default) -> ?HEALTHCHECK_INTERVAL_RAW; health_check_interval(default) -> ?HEALTHCHECK_INTERVAL_RAW;
health_check_interval(required) -> false; health_check_interval(required) -> false;
@ -115,7 +115,7 @@ start_after_created(default) -> ?START_AFTER_CREATED_RAW;
start_after_created(required) -> false; start_after_created(required) -> false;
start_after_created(_) -> undefined. start_after_created(_) -> undefined.
start_timeout(type) -> emqx_schema:duration_ms(); start_timeout(type) -> emqx_schema:timeout_duration_ms();
start_timeout(desc) -> ?DESC("start_timeout"); start_timeout(desc) -> ?DESC("start_timeout");
start_timeout(default) -> ?START_TIMEOUT_RAW; start_timeout(default) -> ?START_TIMEOUT_RAW;
start_timeout(required) -> false; start_timeout(required) -> false;
@ -133,7 +133,7 @@ query_mode(default) -> async;
query_mode(required) -> false; query_mode(required) -> false;
query_mode(_) -> undefined. query_mode(_) -> undefined.
request_ttl(type) -> hoconsc:union([emqx_schema:duration_ms(), infinity]); request_ttl(type) -> hoconsc:union([emqx_schema:timeout_duration_ms(), infinity]);
request_ttl(aliases) -> [request_timeout]; request_ttl(aliases) -> [request_timeout];
request_ttl(desc) -> ?DESC("request_ttl"); request_ttl(desc) -> ?DESC("request_ttl");
request_ttl(default) -> ?DEFAULT_REQUEST_TTL_RAW; request_ttl(default) -> ?DEFAULT_REQUEST_TTL_RAW;
@ -166,7 +166,7 @@ batch_size(default) -> ?DEFAULT_BATCH_SIZE;
batch_size(required) -> false; batch_size(required) -> false;
batch_size(_) -> undefined. batch_size(_) -> undefined.
batch_time(type) -> emqx_schema:duration_ms(); batch_time(type) -> emqx_schema:timeout_duration_ms();
batch_time(desc) -> ?DESC("batch_time"); batch_time(desc) -> ?DESC("batch_time");
batch_time(default) -> ?DEFAULT_BATCH_TIME_RAW; batch_time(default) -> ?DEFAULT_BATCH_TIME_RAW;
batch_time(required) -> false; batch_time(required) -> false;
@ -196,6 +196,10 @@ desc("creation_opts") -> ?DESC("creation_opts").
get_value_with_unit(Value) when is_integer(Value) -> get_value_with_unit(Value) when is_integer(Value) ->
<<(erlang:integer_to_binary(Value))/binary, "ms">>; <<(erlang:integer_to_binary(Value))/binary, "ms">>;
get_value_with_unit(Value) when is_list(Value) ->
%% Must ensure it's a binary, otherwise formatting the error
%% message will fail.
list_to_binary(Value);
get_value_with_unit(Value) -> get_value_with_unit(Value) ->
Value. Value.

View File

@ -0,0 +1,108 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2023 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%--------------------------------------------------------------------
-module(emqx_resource_schema_tests).
-include_lib("eunit/include/eunit.hrl").
-include_lib("common_test/include/ct.hrl").
%%===========================================================================
%% Test cases
%%===========================================================================
health_check_interval_validator_test_() ->
[
?_assertMatch(
#{<<"resource_opts">> := #{<<"health_check_interval">> := 150_000}},
parse_and_check_webhook_bridge(webhook_bridge_health_check_hocon(<<"150s">>))
),
?_assertMatch(
#{<<"resource_opts">> := #{<<"health_check_interval">> := 3_600_000}},
parse_and_check_webhook_bridge(webhook_bridge_health_check_hocon(<<"3600000ms">>))
),
?_assertThrow(
{_, [
#{
kind := validation_error,
reason := <<"Health Check Interval (3600001ms) is out of range", _/binary>>,
value := 3600001
}
]},
parse_and_check_webhook_bridge(webhook_bridge_health_check_hocon(<<"3600001ms">>))
),
{"bad parse: negative number",
?_assertThrow(
{_, [
#{
kind := validation_error,
reason := <<"Health Check Interval (-10ms) is out of range", _/binary>>,
value := "-10ms"
}
]},
parse_and_check_webhook_bridge(webhook_bridge_health_check_hocon(<<"-10ms">>))
)},
{"bad parse: underscores",
?_assertThrow(
{_, [
#{
kind := validation_error,
reason :=
<<"Health Check Interval (3_600_000ms) is out of range", _/binary>>,
value := "3_600_000ms"
}
]},
parse_and_check_webhook_bridge(webhook_bridge_health_check_hocon(<<"3_600_000ms">>))
)},
?_assertThrow(
#{exception := "timeout value too large" ++ _},
parse_and_check_webhook_bridge(
webhook_bridge_health_check_hocon(<<"150000000000000s">>)
)
)
].
%%===========================================================================
%% Helper functions
%%===========================================================================
parse_and_check_webhook_bridge(Hocon) ->
#{<<"bridges">> := #{<<"webhook">> := #{<<"simple">> := Conf}}} = check(parse(Hocon)),
Conf.
parse(Hocon) ->
{ok, Conf} = hocon:binary(Hocon),
Conf.
check(Conf) when is_map(Conf) ->
hocon_tconf:check_plain(emqx_bridge_schema, Conf).
%%===========================================================================
%% Data section
%%===========================================================================
%% erlfmt-ignore
webhook_bridge_health_check_hocon(HealthCheckInterval) ->
io_lib:format(
"""
bridges.webhook.simple {
url = \"http://localhost:4000\"
body = \"body\"
resource_opts {
health_check_interval = \"~s\"
}
}
""",
[HealthCheckInterval]).

View File

@ -45,13 +45,14 @@ fields("retainer") ->
{enable, sc(boolean(), enable, true)}, {enable, sc(boolean(), enable, true)},
{msg_expiry_interval, {msg_expiry_interval,
sc( sc(
%% not used in a `receive ... after' block, just timestamp comparison
emqx_schema:duration_ms(), emqx_schema:duration_ms(),
msg_expiry_interval, msg_expiry_interval,
<<"0s">> <<"0s">>
)}, )},
{msg_clear_interval, {msg_clear_interval,
sc( sc(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
msg_clear_interval, msg_clear_interval,
<<"0s">> <<"0s">>
)}, )},

View File

@ -216,7 +216,7 @@ rule_engine_settings() ->
?HOCON(boolean(), #{default => true, desc => ?DESC("rule_engine_ignore_sys_message")})}, ?HOCON(boolean(), #{default => true, desc => ?DESC("rule_engine_ignore_sys_message")})},
{jq_function_default_timeout, {jq_function_default_timeout,
?HOCON( ?HOCON(
emqx_schema:duration_ms(), emqx_schema:timeout_duration_ms(),
#{ #{
default => <<"10s">>, default => <<"10s">>,
desc => ?DESC("rule_engine_jq_function_default_timeout") desc => ?DESC("rule_engine_jq_function_default_timeout")

View File

@ -1,6 +1,6 @@
{application, emqx_s3, [ {application, emqx_s3, [
{description, "EMQX S3"}, {description, "EMQX S3"},
{vsn, "5.0.7"}, {vsn, "5.0.8"},
{modules, []}, {modules, []},
{registered, [emqx_s3_sup]}, {registered, [emqx_s3_sup]},
{applications, [ {applications, [

View File

@ -68,6 +68,7 @@ fields(s3) ->
)}, )},
{url_expire_time, {url_expire_time,
mk( mk(
%% not used in a `receive ... after' block, just timestamp comparison
emqx_schema:duration_s(), emqx_schema:duration_s(),
#{ #{
default => "1h", default => "1h",

View File

@ -1,7 +1,7 @@
{application, emqx_slow_subs, [ {application, emqx_slow_subs, [
{description, "EMQX Slow Subscribers Statistics"}, {description, "EMQX Slow Subscribers Statistics"},
% strict semver, bump manually! % strict semver, bump manually!
{vsn, "1.0.5"}, {vsn, "1.0.6"},
{modules, []}, {modules, []},
{registered, [emqx_slow_subs_sup]}, {registered, [emqx_slow_subs_sup]},
{applications, [kernel, stdlib, emqx]}, {applications, [kernel, stdlib, emqx]},

View File

@ -30,12 +30,14 @@ fields("slow_subs") ->
{enable, sc(boolean(), false, enable)}, {enable, sc(boolean(), false, enable)},
{threshold, {threshold,
sc( sc(
%% not used in a `receive ... after' block, just timestamp comparison
emqx_schema:duration_ms(), emqx_schema:duration_ms(),
<<"500ms">>, <<"500ms">>,
threshold threshold
)}, )},
{expire_interval, {expire_interval,
sc( sc(
%% not used in a `receive ... after' block, just timestamp comparison
emqx_schema:duration_ms(), emqx_schema:duration_ms(),
<<"300s">>, <<"300s">>,
expire_interval expire_interval

View File

@ -0,0 +1,3 @@
Added a schema validation for values that might be used in timeouts to avoid invalid values.
Before this fix, it was possible to use absurd values in the schema that would exceed the system limit, causing a crash.