Skip to content

Commit cd49225

Browse files
authored
PISTON-221: only record in ACDc once per call (#6736)
- prevent multiple overlapping recordings if caller re-enters a queue
1 parent c1a8734 commit cd49225

File tree

4 files changed

+128
-5
lines changed

4 files changed

+128
-5
lines changed

applications/acdc/src/acdc_agent_listener.erl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,10 +1188,10 @@ maybe_start_recording(Call, 'true', Url) ->
11881188
,{<<"url">>, Url}
11891189
]),
11901190
lager:debug("starting recording listener for ~s", [Url]),
1191-
case acdc_recordings_sup:new(Call, RecordingJObj) of
1192-
{'ok', _P} ->
1193-
lager:debug("recording tracked in ~p", [_P]);
1194-
_E -> lager:debug("failed to start recording: ~p", [_E])
1191+
try acdc_recordings_map_srv:register(Call, RecordingJObj) of
1192+
_P -> lager:debug("recording tracked in ~p", [_P])
1193+
catch
1194+
'exit':_E -> lager:debug("failed to start recording: ~p", [_E])
11951195
end.
11961196

11971197
recording_format() ->
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
%%%-----------------------------------------------------------------------------
2+
%%% @copyright (C) 2016-2021, 2600Hz
3+
%%% @doc
4+
%%% @author Daniel Finke
5+
%%% @end
6+
%%%-----------------------------------------------------------------------------
7+
-module(acdc_recordings_map_srv).
8+
9+
-behaviour(gen_server).
10+
11+
%% API
12+
-export([start_link/0]).
13+
-export([register/2]).
14+
15+
%% gen_server callbacks
16+
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
17+
terminate/2, code_change/3]).
18+
19+
-include("acdc.hrl").
20+
21+
-define(SERVER, ?MODULE).
22+
23+
-record(state, {table_id :: ets:tid()}).
24+
-type state() :: #state{}.
25+
26+
%%%=============================================================================
27+
%%% API
28+
%%%=============================================================================
29+
30+
%%------------------------------------------------------------------------------
31+
%% @doc Starts the server
32+
%%
33+
%% @end
34+
%%------------------------------------------------------------------------------
35+
-spec start_link() -> kz_types:startlink_ret().
36+
start_link() ->
37+
gen_server:start_link({'local', ?SERVER}, ?MODULE, [], []).
38+
39+
-spec register(kapps_call:call(), kz_json:object()) -> pid().
40+
register(Call, RecordingJObj) ->
41+
gen_server:call(?SERVER, {'register', Call, RecordingJObj}).
42+
43+
%%%=============================================================================
44+
%%% gen_server callbacks
45+
%%%=============================================================================
46+
47+
%%------------------------------------------------------------------------------
48+
%% @doc Initializes the server
49+
%%
50+
%% @end
51+
%%------------------------------------------------------------------------------
52+
-spec init([]) -> {'ok', state()}.
53+
init([]) ->
54+
process_flag('trap_exit', 'true'),
55+
TabId = ets:new('map', []),
56+
{'ok', #state{table_id=TabId}}.
57+
58+
%%------------------------------------------------------------------------------
59+
%% @doc Handling call messages
60+
%%
61+
%% @end
62+
%%------------------------------------------------------------------------------
63+
-spec handle_call(any(), kz_term:pid_ref(), state()) -> kz_types:handle_call_ret_state(state()).
64+
handle_call({'register', Call, RecordingJObj}, _From, #state{table_id=TabId}=State) ->
65+
case ets:lookup(TabId, kapps_call:call_id(Call)) of
66+
[] ->
67+
{'ok', Pid} = acdc_recordings_sup:new(Call, RecordingJObj),
68+
link(Pid),
69+
ets:insert(TabId, {kapps_call:call_id(Call), Pid}),
70+
Pid;
71+
[{_, Pid}] -> Pid
72+
end,
73+
{'reply', Pid, State};
74+
handle_call(_Request, _From, State) ->
75+
Reply = 'ok',
76+
{'reply', Reply, State}.
77+
78+
%%------------------------------------------------------------------------------
79+
%% @doc Handling cast messages
80+
%%
81+
%% @end
82+
%%------------------------------------------------------------------------------
83+
-spec handle_cast(any(), state()) -> kz_types:handle_cast_ret_state(state()).
84+
handle_cast(_Msg, State) ->
85+
{'noreply', State}.
86+
87+
%%------------------------------------------------------------------------------
88+
%% @doc Handling all non call/cast messages
89+
%%
90+
%% @end
91+
%%------------------------------------------------------------------------------
92+
-spec handle_info(any(), state()) -> kz_types:handle_info_ret_state(state()).
93+
handle_info({'EXIT', Pid, _Reason}, #state{table_id=TabId}=State) ->
94+
ets:match_delete(TabId, {'$1', Pid}),
95+
{'noreply', State};
96+
handle_info(_Info, State) ->
97+
{'noreply', State}.
98+
99+
%%------------------------------------------------------------------------------
100+
%% @doc This function is called by a gen_server when it is about to
101+
%% terminate. It should be the opposite of Module:init/1 and do any
102+
%% necessary cleaning up. When it returns, the gen_server terminates
103+
%% with Reason. The return value is ignored.
104+
%%
105+
%% @end
106+
%%------------------------------------------------------------------------------
107+
-spec terminate(any(), state()) -> 'ok'.
108+
terminate(_Reason, _State) ->
109+
'ok'.
110+
111+
%%------------------------------------------------------------------------------
112+
%% @doc Convert process state when code is changed
113+
%%
114+
%% @end
115+
%%------------------------------------------------------------------------------
116+
-spec code_change(any(), state(), any()) -> {'ok', state()}.
117+
code_change(_OldVsn, State, _Extra) ->
118+
{'ok', State}.
119+
120+
%%%=============================================================================
121+
%%% Internal functions
122+
%%%=============================================================================

applications/acdc/src/acdc_recordings_sup.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
-define(SERVER, ?MODULE).
2222

23-
-define(CHILDREN, [?WORKER_TYPE('kz_media_recording', 'transient')]).
23+
-define(CHILDREN, [?WORKER_TYPE('kzc_recording', 'transient')]).
2424

2525
%%%=============================================================================
2626
%%% API functions

applications/acdc/src/acdc_sup.erl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
,?WORKER('acdc_agent_manager')
2929
,?WORKER('acdc_init')
3030
,?WORKER('acdc_listener')
31+
,?WORKER('acdc_recordings_map_srv')
3132
]).
3233

3334
%%==============================================================================

0 commit comments

Comments
 (0)