Closed kjellwinblad closed 1 year ago
I added a commit that also makes the mongo_api
work with MongoDB 5.1+ when the setting use_legacy_protocol
is set to true
.
@thalesmg @zmstone . Thanks for the reviews and comments. I will try to make appropriate fixes. FYI, I just added a new commit that makes detection of the appropriate protocol type automatic. I would appreciate reviews for that commit as well. Thank you!
Rebased after latest changes on master
I have tried to do hot-upgrade of this library from the commit before this PR to the last commit of the PR together with EMQX. When doing operations on a connection after the upgrade it fails with the following error:
> mongo_api:insert(Conn, <<"upgrade2">>, [#{<<"hej">> => 2}]).
2022-12-25T17:00:03.456390+01:00 [error] Generic server <0.2900.0> terminating. Reason: {{badfun,#Fun<mc_worker.0.130118026>},[{mc_worker,process_read_request,3,[{file,"mc_worker.erl"},{line,197}]},{gen_server,try_handle_call,4,[{file,"gen_server.erl"},{line,721}]},{gen_server,handle_msg,6,[{file,"gen_server.erl"},{line,750}]},{proc_lib,wake_up,3,[{file,"proc_lib.erl"},{line,236}]}]}. Last message: {query,<<"$cmd">>,false,false,false,false,false,0,-1,{<<"insert">>,<<"upgrade2">>,<<"documents">>,[#{<<"_id">> => {<<99,168,115,131,144,170,99,247,84,0,0,2>>},<<"hej">> => 2}],<<"writeConcern">>,{<<"w">>,1}},#{}}. State: {state,#Port<0.24>,#{},<<>>,{conn_state,unsafe,master,<<"test_db">>,<<"admin">>},undefined,#Fun<mc_worker.0.130118026>,gen_tcp}. Client <0.2831.0> stacktrace: [{gen,do_call,4,[{file,"gen.erl"},{line,214}]},{gen_server,call,3,[{file,"gen_server.erl"},{line,243}]},{mc_connection_man,request_worker,2,[{file,"mc_connection_man.erl"},{line,89}]},{mc_connection_man,read_one,2,[{file,"mc_connection_man.erl"},{line,45}]}].
2022-12-25T17:00:03.457056+01:00 [error] crasher: initial call: mc_worker:init/1, pid: <0.2900.0>, registered_name: [], error: {{badfun,#Fun<mc_worker.0.130118026>},[{mc_worker,process_read_request,3,[{file,"mc_worker.erl"},{line,197}]},{gen_server,try_handle_call,4,[{file,"gen_server.erl"},{line,721}]},{gen_server,handle_msg,6,[{file,"gen_server.erl"},{line,750}]},{proc_lib,wake_up,3,[{file,"proc_lib.erl"},{line,236}]}]}, ancestors: [<0.2899.0>,<0.2898.0>,<0.2880.0>,<0.2876.0>,<0.2831.0>], message_queue_len: 0, messages: [], links: [<0.2899.0>,<0.2898.0>], dictionary: [], trap_exit: false, status: running, heap_size: 6772, stack_size: 29, reductions: 16303; neighbours:
2022-12-25T17:00:03.457555+01:00 [error] Supervisor: {<0.2899.0>,poolboy_sup}. Context: child_terminated. Reason: {{badfun,#Fun<mc_worker.0.130118026>},[{mc_worker,process_read_request,3,[{file,"mc_worker.erl"},{line,197}]},{gen_server,try_handle_call,4,[{file,"gen_server.erl"},{line,721}]},{gen_server,handle_msg,6,[{file,"gen_server.erl"},{line,750}]},{proc_lib,wake_up,3,[{file,"proc_lib.erl"},{line,236}]}]}. Offender: id=mc_worker,pid=<0.2900.0>.
{error,{{{badfun,#Fun<mc_worker.0.130118026>},
[{mc_worker,process_read_request,3,
[{file,"mc_worker.erl"},{line,197}]},
{gen_server,try_handle_call,4,
[{file,"gen_server.erl"},{line,721}]},
{gen_server,handle_msg,6,
[{file,"gen_server.erl"},{line,750}]},
{proc_lib,wake_up,3,[{file,"proc_lib.erl"},{line,236}]}]},
{gen_server,call,
[<0.2900.0>,
{query,<<"$cmd">>,false,false,false,false,false,0,-1,
{<<"insert">>,<<"upgrade2">>,<<"documents">>,
[#{<<"_id">> => {<<"c¨s"...>>},<<"hej">> => 2}],
<<"writeConcern">>,
{<<"w">>,1}},
#{}},
infinity]}}}
(emqx@127.0.0.1)4> 2022-12-25T17:00:03.654410+01:00 [error] [ecpool_worker_sup] wait_connect_complete timeout
2022-12-25T17:00:34.656559+01:00 [error] [ecpool_worker_sup] wait_connect_complete timeout
2022-12-25T17:00:34.657120+01:00 [error] Supervisor: {<0.2899.0>,poolboy_sup}. Context: shutdown_error. Reason: killed. Offender: id=mc_worker,nb_children=1.
2022-12-25T17:00:34.657425+01:00 [error] Generic server <0.2899.0> terminating. Reason: killed. Last message: {'EXIT',<0.2898.0>,killed}. State: {state,{<0.2899.0>,poolboy_sup},simple_one_for_one,{[mc_worker],#{mc_worker => {child,undefined,mc_worker,{mc_worker,start_link,[[{host,"localhost"},{port,27017},{database,<<"test_db">>}]]},temporary,false,5000,worker,[mc_worker]}}},{mapsets,#{<0.3128.0> => []}},0,1,[],0,never,poolboy_sup,{mc_worker,[{host,"localhost"},{port,27017},{database,<<"test_db">>}]}}.
2022-12-25T17:00:34.657776+01:00 [error] crasher: initial call: supervisor:poolboy_sup/1, pid: <0.2899.0>, registered_name: [], exit: {killed,[{gen_server,decode_msg,9,[{file,"gen_server.erl"},{line,481}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,226}]}]}, ancestors: [<0.2898.0>,<0.2880.0>,<0.2876.0>,<0.2831.0>], message_queue_len: 0, messages: [], links: [], dictionary: [], trap_exit: true, status: running, heap_size: 6772, stack_size: 29, reductions: 23135; neighbours:
(emqx@127.0.0.1)4> 2022-12-25T17:01:05.658398+01:00 [error] [ecpool_worker_sup] wait_connect_complete timeout
(emqx@127.0.0.1)4> 2022-12-25T17:01:36.660417+01:00 [error] [ecpool_worker_sup] wait_connect_complete timeout
2022-12-25T17:02:07.662466+01:00 [error] [ecpool_worker_sup] wait_connect_complete timeout
2022-12-25T17:02:38.664530+01:00 [error] [ecpool_worker_sup] wait_connect_complete timeout
2022-12-25T17:03:09.666399+01:00 [error] [ecpool_worker_sup] wait_connect_complete timeout
2022-12-25T17:03:40.668396+01:00 [error] [ecpool_worker_sup] wait_connect_complete timeout
2022-12-25T17:04:11.670474+01:00 [error] [ecpool_worker_sup] wait_connect_complete timeout
(emqx@127.0.0.1)4> 2022-12-25T17:04:42.672517+01:00 [error] [ecpool_worker_sup] wait_connect_complete timeout
(emqx@127.0.0.1)4>
This seems to be because a fun referring the old mc_worker module is stored in the mc_worker state (see https://github.com/emqx/mongodb-erlang/blob/89f7cc8566bef15c507b05bf354d2408477a1f0b/src/connection/mc_worker.erl#L200). This problem existed even before this PR so I conclude that hot-upgrade seems to have been broken for a very long time. Therefore I do not think it is worth fixing it (if a broken hot-upgrade for this driver hasn't been a problem until now it is probably not a problem now as well).
The MongoDB protocol has evolved and the only protocol that this driver supported before this commit has been removed in MongoDB 5.1. This commit makes it possible to use the module
mc_worker_api
(that handles a connection to a single MongoDB server) with MongoDB 5.1+ by configuring the driver withapplication:set_env(mongodb, use_legacy_protocol, false)
. This functionality can be tested by running./test/test_without_legacy_protocol.sh
. Themongo_api
module still needs to be fixed before it can be used with MongoDB 5.1+.The commit also includes some fixes to Dialyzer warnings that existed even before the commit (there are still a few warnings left).