diff --git a/src/cets.erl b/src/cets.erl index ad5c7ea..466ad0e 100644 --- a/src/cets.erl +++ b/src/cets.erl @@ -28,6 +28,7 @@ -behaviour(gen_server). -export([ + start_link/2, start/2, stop/1, insert/2, @@ -70,6 +71,7 @@ ]). -ignore_xref([ + start_link/2, start/2, stop/1, insert/2, @@ -249,6 +251,17 @@ %% API functions +%% @doc Starts a linked process serving an ETS table. +%% @see start/2 +-spec start_link(table_name(), start_opts()) -> gen_server:start_ret(). +start_link(Tab, Opts) when is_atom(Tab) -> + case check_opts(Opts) of + [] -> + gen_server:start_link({local, Tab}, ?MODULE, {Tab, Opts}, []); + Errors -> + {error, Errors} + end. + %% @doc Starts a process serving an ETS table. %% %% The process would be registered under `table_name()' name. diff --git a/test/cets_SUITE.erl b/test/cets_SUITE.erl index 06c87d1..9235526 100644 --- a/test/cets_SUITE.erl +++ b/test/cets_SUITE.erl @@ -39,6 +39,7 @@ groups() -> cases() -> [ + start_link_inits_and_accepts_records, inserted_records_could_be_read_back, insert_many_with_one_record, insert_many_with_two_records, @@ -52,6 +53,7 @@ cases() -> join_works_with_existing_data_with_conflicts_and_defined_conflict_handler_and_more_keys, join_works_with_existing_data_with_conflicts_and_defined_conflict_handler_and_keypos2, bag_with_conflict_handler_not_allowed, + bag_with_conflict_handler_not_allowed_for_start_link, insert_new_works, insert_new_works_with_table_name, insert_new_works_when_leader_is_back, @@ -274,6 +276,12 @@ end_per_testcase(_, _Config) -> log_modules() -> [cets, cets_call, cets_long, cets_join, cets_discovery]. +start_link_inits_and_accepts_records(Config) -> + Tab = make_name(Config), + start_link_local(Tab), + cets:insert(Tab, {alice, 32}), + [{alice, 32}] = ets:lookup(Tab, alice). + inserted_records_could_be_read_back(Config) -> Tab = make_name(Config), start_local(Tab), @@ -747,6 +755,10 @@ bag_with_conflict_handler_not_allowed(Config) -> {error, [bag_with_conflict_handler]} = cets:start(make_name(Config), #{handle_conflict => fun resolve_highest/2, type => bag}). +bag_with_conflict_handler_not_allowed_for_start_link(Config) -> + {error, [bag_with_conflict_handler]} = + cets:start_link(make_name(Config), #{handle_conflict => fun resolve_highest/2, type => bag}). + join_with_the_same_pid(Config) -> Tab = make_name(Config), {ok, Pid} = start_local(Tab), @@ -2917,6 +2929,16 @@ still_works(Pid) -> ok = cets:insert(Pid, {1}), {ok, [{1}]} = cets:remote_dump(Pid). +start_link_local(Name) -> + start_link_local(Name, #{}). + +start_link_local(Name, Opts) -> + catch cets:stop(Name), + wait_for_name_to_be_free(node(), Name), + {ok, Pid} = cets:start_link(Name, Opts), + schedule_cleanup(Pid), + {ok, Pid}. + start_local(Name) -> start_local(Name, #{}).