From 90d0081df4d24ebefda1a33bbac69f8ccae76485 Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Fri, 1 Dec 2023 13:39:21 +0800 Subject: [PATCH 01/10] feat: upgrade greptimedb and client --- .ci/docker-compose-file/docker-compose-greptimedb.yaml | 2 +- apps/emqx_bridge_greptimedb/rebar.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/docker-compose-file/docker-compose-greptimedb.yaml b/.ci/docker-compose-file/docker-compose-greptimedb.yaml index 8980c946d..6813b4983 100644 --- a/.ci/docker-compose-file/docker-compose-greptimedb.yaml +++ b/.ci/docker-compose-file/docker-compose-greptimedb.yaml @@ -4,7 +4,7 @@ services: greptimedb: container_name: greptimedb hostname: greptimedb - image: greptime/greptimedb:0.3.2 + image: greptime/greptimedb:v0.4.4 expose: - "4000" - "4001" diff --git a/apps/emqx_bridge_greptimedb/rebar.config b/apps/emqx_bridge_greptimedb/rebar.config index f0942f910..f9a482faf 100644 --- a/apps/emqx_bridge_greptimedb/rebar.config +++ b/apps/emqx_bridge_greptimedb/rebar.config @@ -6,7 +6,7 @@ {emqx_connector, {path, "../../apps/emqx_connector"}}, {emqx_resource, {path, "../../apps/emqx_resource"}}, {emqx_bridge, {path, "../../apps/emqx_bridge"}}, - {greptimedb, {git, "https://github.com/GreptimeTeam/greptimedb-client-erl", {tag, "v0.1.2"}}} + {greptimedb, {git, "https://github.com/GreptimeTeam/greptimedb-client-erl", {tag, "v0.1.3"}}} ]}. {plugins, [rebar3_path_deps]}. {project_plugins, [erlfmt]}. From 8bc874c2618ce489c4df4f49312cc98b8ccaee7d Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Fri, 1 Dec 2023 17:31:31 +0800 Subject: [PATCH 02/10] feat: supports async mode for greptimedb data bridge --- .../src/emqx_bridge_greptimedb_connector.erl | 73 ++++++++++++++++++- .../test/emqx_bridge_greptimedb_SUITE.erl | 59 +++++++++++++-- 2 files changed, 126 insertions(+), 6 deletions(-) diff --git a/apps/emqx_bridge_greptimedb/src/emqx_bridge_greptimedb_connector.erl b/apps/emqx_bridge_greptimedb/src/emqx_bridge_greptimedb_connector.erl index d588f7f8c..af42dac52 100644 --- a/apps/emqx_bridge_greptimedb/src/emqx_bridge_greptimedb_connector.erl +++ b/apps/emqx_bridge_greptimedb/src/emqx_bridge_greptimedb_connector.erl @@ -21,8 +21,11 @@ on_stop/2, on_query/3, on_batch_query/3, + on_query_async/4, + on_batch_query_async/4, on_get_status/2 ]). +-export([reply_callback/2]). -export([ roots/0, @@ -57,7 +60,7 @@ %% ------------------------------------------------------------------------------------------------- %% resource callback -callback_mode() -> always_sync. +callback_mode() -> async_if_possible. on_start(InstId, Config) -> %% InstID as pool would be handled by greptimedb client @@ -110,6 +113,49 @@ on_batch_query(InstId, BatchData, _State = #{write_syntax := SyntaxLines, client {error, {unrecoverable_error, Reason}} end. +on_query_async( + InstId, + {send_message, Data}, + {ReplyFun, Args}, + _State = #{write_syntax := SyntaxLines, client := Client} +) -> + case data_to_points(Data, SyntaxLines) of + {ok, Points} -> + ?tp( + greptimedb_connector_send_query, + #{points => Points, batch => false, mode => async} + ), + do_async_query(InstId, Client, Points, {ReplyFun, Args}); + {error, ErrorPoints} = Err -> + ?tp( + greptimedb_connector_send_query_error, + #{batch => false, mode => async, error => ErrorPoints} + ), + log_error_points(InstId, ErrorPoints), + Err + end. + +on_batch_query_async( + InstId, + BatchData, + {ReplyFun, Args}, + #{write_syntax := SyntaxLines, client := Client} +) -> + case parse_batch_data(InstId, BatchData, SyntaxLines) of + {ok, Points} -> + ?tp( + greptimedb_connector_send_query, + #{points => Points, batch => true, mode => async} + ), + do_async_query(InstId, Client, Points, {ReplyFun, Args}); + {error, Reason} -> + ?tp( + greptimedb_connector_send_query_error, + #{batch => true, mode => async, error => Reason} + ), + {error, {unrecoverable_error, Reason}} + end. + on_get_status(_InstId, #{client := Client}) -> case greptimedb:is_alive(Client) of true -> @@ -344,6 +390,31 @@ do_query(InstId, Client, Points) -> end end. +do_async_query(InstId, Client, Points, ReplyFunAndArgs) -> + ?SLOG(info, #{ + msg => "greptimedb_write_point_async", + connector => InstId, + points => Points + }), + WrappedReplyFunAndArgs = {fun ?MODULE:reply_callback/2, [ReplyFunAndArgs]}, + ok = greptimedb:async_write_batch(Client, Points, WrappedReplyFunAndArgs). + +reply_callback(ReplyFunAndArgs, {error, {unauth, _, _}}) -> + ?tp(greptimedb_connector_do_query_failure, #{error => <<"authorization failure">>}), + Result = {error, {unrecoverable_error, <<"authorization failure">>}}, + emqx_resource:apply_reply_fun(ReplyFunAndArgs, Result); +reply_callback(ReplyFunAndArgs, {error, Reason} = Error) -> + case is_unrecoverable_error(Error) of + true -> + Result = {error, {unrecoverable_error, Reason}}, + emqx_resource:apply_reply_fun(ReplyFunAndArgs, Result); + false -> + Result = {error, {recoverable_error, Reason}}, + emqx_resource:apply_reply_fun(ReplyFunAndArgs, Result) + end; +reply_callback(ReplyFunAndArgs, Result) -> + emqx_resource:apply_reply_fun(ReplyFunAndArgs, Result). + %% ------------------------------------------------------------------------------------------------- %% Tags & Fields Config Trans diff --git a/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl b/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl index f9d8854ac..a07283f16 100644 --- a/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl +++ b/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl @@ -25,16 +25,23 @@ groups() -> TCs = emqx_common_test_helpers:all(?MODULE), [ {with_batch, [ - {group, sync_query} + {group, sync_query}, + {group, async_query} ]}, {without_batch, [ - {group, sync_query} + {group, sync_query}, + {group, async_query} ]}, {sync_query, [ {group, grpcv1_tcp} %% uncomment tls when we are ready %% {group, grpcv1_tls} ]}, + {async_query, [ + {group, grpcv1_tcp} + %% uncomment tls when we are ready + %% {group, grpcv1_tls} + ]}, {grpcv1_tcp, TCs} %%{grpcv1_tls, TCs} ]. @@ -130,6 +137,8 @@ init_per_group(GreptimedbType, Config0) when end; init_per_group(sync_query, Config) -> [{query_mode, sync} | Config]; +init_per_group(async_query, Config) -> + [{query_mode, async} | Config]; init_per_group(with_batch, Config) -> [{batch_size, 100} | Config]; init_per_group(without_batch, Config) -> @@ -420,6 +429,9 @@ t_start_ok(Config) -> ?check_trace( begin case QueryMode of + async -> + ?assertMatch(ok, send_message(Config, SentData)), + ct:sleep(500); sync -> ?assertMatch({ok, _}, send_message(Config, SentData)) end, @@ -666,6 +678,9 @@ t_const_timestamp(Config) -> <<"timestamp">> => erlang:system_time(millisecond) }, case QueryMode of + async -> + ?assertMatch(ok, send_message(Config, SentData)), + ct:sleep(500); sync -> ?assertMatch({ok, _}, send_message(Config, SentData)) end, @@ -709,9 +724,12 @@ t_boolean_variants(Config) -> }, case QueryMode of sync -> - ?assertMatch({ok, _}, send_message(Config, SentData)) + ?assertMatch({ok, _}, send_message(Config, SentData)); + async -> + ?assertMatch(ok, send_message(Config, SentData)) end, case QueryMode of + async -> ct:sleep(500); sync -> ok end, PersistedData = query_by_clientid(atom_to_binary(?FUNCTION_NAME), ClientId, Config), @@ -909,15 +927,29 @@ t_write_failure(Config) -> ), #{?snk_kind := greptimedb_connector_do_query_failure, action := nack}, 16_000 + ); + async -> + ?wait_async_action( + ?assertEqual(ok, send_message(Config, SentData)), + #{?snk_kind := handle_async_reply}, + 1_000 ) end end), - fun(Trace) -> + fun(Trace0) -> case QueryMode of sync -> ?assertMatch( [#{error := _} | _], - ?of_kind(greptimedb_connector_do_query_failure, Trace) + ?of_kind(greptimedb_connector_do_query_failure, Trace0) + ); + async -> + Trace = ?of_kind(handle_async_reply, Trace0), + ?assertMatch([#{action := nack} | _], Trace), + [#{result := Result} | _] = Trace, + ?assert( + not emqx_bridge_greptimedb_connector:is_unrecoverable_error(Result), + #{got => Result} ) end, ok @@ -1029,6 +1061,23 @@ t_authentication_error_on_send_message(Config0) -> ?assertMatch( {error, {unrecoverable_error, <<"authorization failure">>}}, send_message(Config, SentData) + ); + async -> + ?check_trace( + begin + ?wait_async_action( + ?assertEqual(ok, send_message(Config, SentData)), + #{?snk_kind := handle_async_reply}, + 1_000 + ) + end, + fun(Trace) -> + ?assertMatch( + [#{error := <<"authorization failure">>} | _], + ?of_kind(greptimedb_connector_do_query_failure, Trace) + ), + ok + end ) end, ok. From a694f3c92de7f7be7adec3c215d7d05540c7fe76 Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Mon, 4 Dec 2023 16:41:31 +0800 Subject: [PATCH 03/10] fix: tests --- apps/emqx_bridge_greptimedb/rebar.config | 2 +- .../test/emqx_bridge_greptimedb_SUITE.erl | 20 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/emqx_bridge_greptimedb/rebar.config b/apps/emqx_bridge_greptimedb/rebar.config index f9a482faf..ce147be86 100644 --- a/apps/emqx_bridge_greptimedb/rebar.config +++ b/apps/emqx_bridge_greptimedb/rebar.config @@ -6,7 +6,7 @@ {emqx_connector, {path, "../../apps/emqx_connector"}}, {emqx_resource, {path, "../../apps/emqx_resource"}}, {emqx_bridge, {path, "../../apps/emqx_bridge"}}, - {greptimedb, {git, "https://github.com/GreptimeTeam/greptimedb-client-erl", {tag, "v0.1.3"}}} + {greptimedb, {git, "https://github.com/GreptimeTeam/greptimedb-client-erl", {tag, "v0.1.4"}}} ]}. {plugins, [rebar3_path_deps]}. {project_plugins, [erlfmt]}. diff --git a/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl b/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl index a07283f16..874c647af 100644 --- a/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl +++ b/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl @@ -797,11 +797,29 @@ t_bad_timestamp(Config) -> #{?snk_kind := greptimedb_connector_send_query_error}, 10_000 ), - fun(Result, _Trace) -> + fun(Result, Trace) -> ?assertMatch({_, {ok, _}}, Result), {Return, {ok, _}} = Result, IsBatch = BatchSize > 1, case {QueryMode, IsBatch} of + {async, true} -> + ?assertEqual(ok, Return), + ?assertMatch( + [#{error := points_trans_failed}], + ?of_kind(greptimedb_connector_send_query_error, Trace) + ); + {async, false} -> + ?assertEqual(ok, Return), + ?assertMatch( + [ + #{ + error := [ + {error, {bad_timestamp, <<"bad_timestamp">>}} + ] + } + ], + ?of_kind(greptimedb_connector_send_query_error, Trace) + ); {sync, false} -> ?assertEqual( {error, [ From 2d3a15e076713c40a0ce83c4cb369a6d3c59da31 Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Mon, 4 Dec 2023 16:41:47 +0800 Subject: [PATCH 04/10] fix: forgot to update mix.es --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 567cd9e80..9821f6f82 100644 --- a/mix.exs +++ b/mix.exs @@ -236,7 +236,7 @@ defmodule EMQXUmbrella.MixProject do {:crc32cer, "0.1.8", override: true}, {:supervisor3, "1.1.12", override: true}, {:opentsdb, github: "emqx/opentsdb-client-erl", tag: "v0.5.1", override: true}, - {:greptimedb, github: "GreptimeTeam/greptimedb-client-erl", tag: "v0.1.2", override: true}, + {:greptimedb, github: "GreptimeTeam/greptimedb-client-erl", tag: "v0.1.4", override: true}, # The following two are dependencies of rabbit_common. They are needed here to # make mix not complain about conflicting versions {:thoas, github: "emqx/thoas", tag: "v1.0.0", override: true}, From 547acef01dd7c40cb425267a64e95728740699fa Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Mon, 4 Dec 2023 16:44:50 +0800 Subject: [PATCH 05/10] feat: upgrade greptimedb client to v0.1.5 --- apps/emqx_bridge_greptimedb/rebar.config | 2 +- changes/ee/feat-12072.en.md | 2 ++ mix.exs | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 changes/ee/feat-12072.en.md diff --git a/apps/emqx_bridge_greptimedb/rebar.config b/apps/emqx_bridge_greptimedb/rebar.config index ce147be86..ee207c1d2 100644 --- a/apps/emqx_bridge_greptimedb/rebar.config +++ b/apps/emqx_bridge_greptimedb/rebar.config @@ -6,7 +6,7 @@ {emqx_connector, {path, "../../apps/emqx_connector"}}, {emqx_resource, {path, "../../apps/emqx_resource"}}, {emqx_bridge, {path, "../../apps/emqx_bridge"}}, - {greptimedb, {git, "https://github.com/GreptimeTeam/greptimedb-client-erl", {tag, "v0.1.4"}}} + {greptimedb, {git, "https://github.com/GreptimeTeam/greptimedb-client-erl", {tag, "v0.1.5"}}} ]}. {plugins, [rebar3_path_deps]}. {project_plugins, [erlfmt]}. diff --git a/changes/ee/feat-12072.en.md b/changes/ee/feat-12072.en.md new file mode 100644 index 000000000..9391be539 --- /dev/null +++ b/changes/ee/feat-12072.en.md @@ -0,0 +1,2 @@ +Supports async query mode for GreptimeDB data bridge. + diff --git a/mix.exs b/mix.exs index 9821f6f82..ec6ce5830 100644 --- a/mix.exs +++ b/mix.exs @@ -236,7 +236,7 @@ defmodule EMQXUmbrella.MixProject do {:crc32cer, "0.1.8", override: true}, {:supervisor3, "1.1.12", override: true}, {:opentsdb, github: "emqx/opentsdb-client-erl", tag: "v0.5.1", override: true}, - {:greptimedb, github: "GreptimeTeam/greptimedb-client-erl", tag: "v0.1.4", override: true}, + {:greptimedb, github: "GreptimeTeam/greptimedb-client-erl", tag: "v0.1.5", override: true}, # The following two are dependencies of rabbit_common. They are needed here to # make mix not complain about conflicting versions {:thoas, github: "emqx/thoas", tag: "v1.0.0", override: true}, From fbeb56e47512ba37445825a99ecae33e91911058 Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Mon, 4 Dec 2023 18:04:04 +0800 Subject: [PATCH 06/10] fix: test case t_write_failure --- .../test/emqx_bridge_greptimedb_SUITE.erl | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl b/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl index 874c647af..497459434 100644 --- a/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl +++ b/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl @@ -938,14 +938,15 @@ t_write_failure(Config) -> emqx_common_test_helpers:with_failure(down, ProxyName, ProxyHost, ProxyPort, fun() -> case QueryMode of sync -> - ?wait_async_action( - ?assertMatch( - {error, {resource_error, #{reason := timeout}}}, - send_message(Config, SentData) - ), - #{?snk_kind := greptimedb_connector_do_query_failure, action := nack}, - 16_000 - ); + {_, {ok, _}} = + ?wait_async_action( + ?assertMatch( + {error, {resource_error, #{reason := timeout}}}, + send_message(Config, SentData) + ), + #{?snk_kind := handle_async_reply, action := nack}, + 1_000 + ); async -> ?wait_async_action( ?assertEqual(ok, send_message(Config, SentData)), @@ -957,9 +958,12 @@ t_write_failure(Config) -> fun(Trace0) -> case QueryMode of sync -> - ?assertMatch( - [#{error := _} | _], - ?of_kind(greptimedb_connector_do_query_failure, Trace0) + Trace = ?of_kind(handle_async_reply, Trace0), + ?assertMatch([_ | _], Trace), + [#{result := Result} | _] = Trace, + ?assert( + not emqx_bridge_greptimedb_connector:is_unrecoverable_error(Result), + #{got => Result} ); async -> Trace = ?of_kind(handle_async_reply, Trace0), From 97592e2e404d22aa087355c526746330cf5797a0 Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Mon, 4 Dec 2023 18:43:18 +0800 Subject: [PATCH 07/10] fix: test case t_write_failure --- .../test/emqx_bridge_greptimedb_SUITE.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl b/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl index 497459434..fdeb94294 100644 --- a/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl +++ b/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl @@ -945,13 +945,13 @@ t_write_failure(Config) -> send_message(Config, SentData) ), #{?snk_kind := handle_async_reply, action := nack}, - 1_000 + 15_000 ); async -> ?wait_async_action( ?assertEqual(ok, send_message(Config, SentData)), #{?snk_kind := handle_async_reply}, - 1_000 + 15_000 ) end end), From c128f7b2d97f0c8ebfb9e92957bd6703b017f4fc Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Mon, 4 Dec 2023 19:12:26 +0800 Subject: [PATCH 08/10] docs: update changelog --- changes/ee/feat-12072.en.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changes/ee/feat-12072.en.md b/changes/ee/feat-12072.en.md index 9391be539..0b91b5c45 100644 --- a/changes/ee/feat-12072.en.md +++ b/changes/ee/feat-12072.en.md @@ -1,2 +1,3 @@ -Supports async query mode for GreptimeDB data bridge. +Supports async query mode for GreptimeDB data bridge. It provides better performance. + From 1d6ea685ef859e2fd98c1daf14d98a9a4cb36bf5 Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Mon, 4 Dec 2023 19:36:16 +0800 Subject: [PATCH 09/10] fix: another try to fix t_write_failure --- .../test/emqx_bridge_greptimedb_SUITE.erl | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl b/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl index fdeb94294..73223892d 100644 --- a/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl +++ b/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl @@ -938,20 +938,19 @@ t_write_failure(Config) -> emqx_common_test_helpers:with_failure(down, ProxyName, ProxyHost, ProxyPort, fun() -> case QueryMode of sync -> - {_, {ok, _}} = - ?wait_async_action( - ?assertMatch( - {error, {resource_error, #{reason := timeout}}}, - send_message(Config, SentData) - ), - #{?snk_kind := handle_async_reply, action := nack}, - 15_000 - ); + ?wait_async_action( + ?assertMatch( + {error, {resource_error, #{reason := timeout}}}, + send_message(Config, SentData) + ), + #{?snk_kind := handle_async_reply, action := nack}, + 1_000 + ); async -> ?wait_async_action( ?assertEqual(ok, send_message(Config, SentData)), #{?snk_kind := handle_async_reply}, - 15_000 + 1_000 ) end end), @@ -967,7 +966,7 @@ t_write_failure(Config) -> ); async -> Trace = ?of_kind(handle_async_reply, Trace0), - ?assertMatch([#{action := nack} | _], Trace), + ?assertMatch([_ | _], Trace), [#{result := Result} | _] = Trace, ?assert( not emqx_bridge_greptimedb_connector:is_unrecoverable_error(Result), From 9920841deb2bbece35c2fb47b8ded8bf05c61cf0 Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Mon, 4 Dec 2023 20:16:51 +0800 Subject: [PATCH 10/10] chore: upgrade greptimedb client to v0.1.6 to fix the failed test --- apps/emqx_bridge_greptimedb/rebar.config | 2 +- mix.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/emqx_bridge_greptimedb/rebar.config b/apps/emqx_bridge_greptimedb/rebar.config index ee207c1d2..985299c3d 100644 --- a/apps/emqx_bridge_greptimedb/rebar.config +++ b/apps/emqx_bridge_greptimedb/rebar.config @@ -6,7 +6,7 @@ {emqx_connector, {path, "../../apps/emqx_connector"}}, {emqx_resource, {path, "../../apps/emqx_resource"}}, {emqx_bridge, {path, "../../apps/emqx_bridge"}}, - {greptimedb, {git, "https://github.com/GreptimeTeam/greptimedb-client-erl", {tag, "v0.1.5"}}} + {greptimedb, {git, "https://github.com/GreptimeTeam/greptimedb-client-erl", {tag, "v0.1.6"}}} ]}. {plugins, [rebar3_path_deps]}. {project_plugins, [erlfmt]}. diff --git a/mix.exs b/mix.exs index ec6ce5830..9c06e20af 100644 --- a/mix.exs +++ b/mix.exs @@ -236,7 +236,7 @@ defmodule EMQXUmbrella.MixProject do {:crc32cer, "0.1.8", override: true}, {:supervisor3, "1.1.12", override: true}, {:opentsdb, github: "emqx/opentsdb-client-erl", tag: "v0.5.1", override: true}, - {:greptimedb, github: "GreptimeTeam/greptimedb-client-erl", tag: "v0.1.5", override: true}, + {:greptimedb, github: "GreptimeTeam/greptimedb-client-erl", tag: "v0.1.6", override: true}, # The following two are dependencies of rabbit_common. They are needed here to # make mix not complain about conflicting versions {:thoas, github: "emqx/thoas", tag: "v1.0.0", override: true},