Skip to content

Commit 5e181d4

Browse files
authored
fix: handle already_started when starting instance (#111)
**Requirements** - [x] I have added test coverage for new or changed functionality - [x] I have followed the repository's [pull request submission guidelines](../blob/main/CONTRIBUTING.md#submitting-pull-requests) - [ ] I have validated my changes against all supported platform versions **Related issues** https://github.com/launchdarkly/erlang-server-sdk/blob/242986ec2dd4e42cf603ef2005de1fd96444aa42/src/ldclient_instance.erl#L61 **Describe the solution you've provided** N/A **Describe alternatives you've considered** N/A **Additional context** Add any other context about the pull request here.
1 parent 242986e commit 5e181d4

File tree

2 files changed

+78
-22
lines changed

2 files changed

+78
-22
lines changed

src/ldclient_instance.erl

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
-spec start(Tag :: atom(), SdkKey :: string(), Options :: options()) ->
5959
ok | {error, already_started, term()}.
6060
start(Tag, SdkKey, Options) ->
61-
% TODO check if Tag already exists and return already_started error
6261
% Parse options into settings
6362
Settings = ldclient_config:parse_options(SdkKey, Options),
6463
ok = ldclient_config:register(Tag, Settings),
@@ -67,14 +66,25 @@ start(Tag, SdkKey, Options) ->
6766
UpdateSupName = get_ref_from_tag(instance_stream, Tag),
6867
UpdateWorkerModule = get_update_processor(Settings),
6968
EventsSupName = get_ref_from_tag(instance_events, Tag),
70-
{ok, _} = supervisor:start_child(ldclient_sup, ldclient_instance_sup:child_spec(SupName, [SupName, UpdateSupName, UpdateWorkerModule, EventsSupName, Tag])),
71-
% Start storage backend
72-
true = ldclient_update_processor_state:create_storage_initialized_state(Tag, false),
73-
FeatureStore = maps:get(feature_store, Settings),
74-
ok = FeatureStore:init(SupName, Tag, []),
75-
% Start stream client
76-
true = ldclient_update_processor_state:create_initialized_state(Tag, false),
77-
start_updater(UpdateSupName, UpdateWorkerModule, Tag).
69+
case
70+
supervisor:start_child(
71+
ldclient_sup,
72+
ldclient_instance_sup:child_spec(SupName, [
73+
SupName, UpdateSupName, UpdateWorkerModule, EventsSupName, Tag
74+
])
75+
)
76+
of
77+
{ok, _} ->
78+
% Start storage backend
79+
true = ldclient_update_processor_state:create_storage_initialized_state(Tag, false),
80+
FeatureStore = maps:get(feature_store, Settings),
81+
ok = FeatureStore:init(SupName, Tag, []),
82+
% Start stream client
83+
true = ldclient_update_processor_state:create_initialized_state(Tag, false),
84+
start_updater(UpdateSupName, UpdateWorkerModule, Tag);
85+
{error, {already_started, Pid}} ->
86+
{error, already_started, Pid}
87+
end.
7888

7989
%% @doc Stop a client instance
8090
%%
@@ -148,22 +158,25 @@ start_updater(UpdateSupName, UpdateWorkerModule, Tag) ->
148158
%% @private
149159
%%
150160
%% @end
151-
-spec get_update_processor(Settings :: #{ stream := boolean(),
152-
offline := boolean(),
153-
use_ldd := boolean(),
154-
file_datasource := boolean(),
155-
datasource := atom(),
156-
_ => _
157-
}) -> atom().
158-
get_update_processor(#{ offline := true }) ->
161+
-spec get_update_processor(
162+
Settings :: #{
163+
stream := boolean(),
164+
offline := boolean(),
165+
use_ldd := boolean(),
166+
file_datasource := boolean(),
167+
datasource := atom(),
168+
_ => _
169+
}
170+
) -> atom().
171+
get_update_processor(#{offline := true}) ->
159172
ldclient_update_null_server;
160-
get_update_processor(#{ use_ldd := true }) ->
173+
get_update_processor(#{use_ldd := true}) ->
161174
ldclient_update_null_server;
162-
get_update_processor(#{ datasource := DataSource }) when DataSource /= undefined ->
175+
get_update_processor(#{datasource := DataSource}) when DataSource /= undefined ->
163176
list_to_atom("ldclient_update_" ++ atom_to_list(DataSource) ++ "_server");
164-
get_update_processor(#{ file_datasource := true }) ->
177+
get_update_processor(#{file_datasource := true}) ->
165178
ldclient_update_file_server;
166-
get_update_processor(#{ stream := false }) ->
179+
get_update_processor(#{stream := false}) ->
167180
ldclient_update_poll_server;
168-
get_update_processor(#{ stream := true }) ->
181+
get_update_processor(#{stream := true}) ->
169182
ldclient_update_stream_server.

test/ldclient_start_SUITE.erl

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
-module(ldclient_start_SUITE).
2+
3+
-include_lib("common_test/include/ct.hrl").
4+
5+
-compile(export_all).
6+
7+
%%====================================================================
8+
%% ct functions
9+
%%====================================================================
10+
all() ->
11+
[
12+
test_already_running_client
13+
].
14+
15+
init_per_suite(Config) ->
16+
{ok, _} = application:ensure_all_started(ldclient),
17+
Config.
18+
19+
end_per_suite(_) ->
20+
ok = application:stop(ldclient).
21+
22+
init_per_testcase(_, Config) ->
23+
Options = #{
24+
send_events => false,
25+
feature_store => ldclient_storage_map,
26+
datasource => testdata
27+
},
28+
ldclient:start_instance("", Options),
29+
Config.
30+
31+
end_per_testcase(_, _Config) ->
32+
ldclient:stop_all_instances().
33+
34+
%%====================================================================
35+
%% Tests
36+
%%====================================================================
37+
38+
test_already_running_client(_) ->
39+
{error, already_started, _} = ldclient:start_instance("", #{
40+
send_events => false,
41+
feature_store => ldclient_storage_map,
42+
datasource => testdata
43+
}).

0 commit comments

Comments
 (0)