Skip to content

Commit

Permalink
Merge branch 'master' into v2.07
Browse files Browse the repository at this point in the history
  • Loading branch information
James Aimonetti committed Jan 8, 2013
2 parents e4c2fc2 + e1cf834 commit 3f0cfc8
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 61 deletions.
2 changes: 2 additions & 0 deletions ecallmgr/src/ecallmgr_fs_nodes.erl
Expand Up @@ -789,7 +789,9 @@ maybe_ping_node(Node, Cookie, Options, #state{nodes=Nodes}=State) ->
self() ! {nodedown, Node},
{{error, failed_starting_handlers}, State};
_:Reason ->
ST = erlang:get_stacktrace(),
lager:warning("unable to start node ~s handlers: ~p", [Node, Reason]),
[lager:debug("st: ~p", [S]) || S <- ST],
self() ! {nodedown, Node},
{{error, failed_starting_handlers}, State}
end;
Expand Down
44 changes: 32 additions & 12 deletions whistle_apps/apps/acdc/src/acdc_agent_fsm.erl
Expand Up @@ -453,7 +453,7 @@ ready({pause, Timeout}, #state{acct_id=AcctId
acdc_stats:agent_paused(AcctId, AgentId, Timeout),
acdc_util:presence_update(AcctId, AgentId, ?PRESENCE_RED_FLASH),

webseq:note(self(), right, [<<"pausing for ">>, wh_util:to_binary(Timeout)]),
webseq:note(self(), right, [<<"pause: ">>, wh_util:to_binary(Timeout)]),

{next_state, paused, State#state{sync_ref=Ref}};

Expand All @@ -466,6 +466,7 @@ ready({member_connect_win, JObj}, #state{agent_proc=Srv
,endpoints=EPs
,agent_proc_id=MyId
,agent_id=AgentId
,acct_id=AcctId
}=State) ->
Call = whapps_call:from_json(wh_json:get_value(<<"Call">>, JObj)),
CallId = whapps_call:call_id(Call),
Expand All @@ -481,8 +482,10 @@ ready({member_connect_win, JObj}, #state{agent_proc=Srv
lager:debug("trying to ring agent ~s to connect to caller", [AgentId]),

acdc_agent:bridge_to_member(Srv, Call, JObj, EPs),
acdc_stats:agent_handling(AcctId, AgentId, CallId),

webseq:note(self(), right, [<<"recv win for ">>, CallId, <<", ringing">>]),
webseq:evt(self(), CallId, <<"bridge">>),
webseq:note(self(), right, <<"ringing">>),
{next_state, ringing, State#state{wrapup_timeout=WrapupTimer
,member_call=Call
,member_call_id=CallId
Expand All @@ -495,7 +498,9 @@ ready({member_connect_win, JObj}, #state{agent_proc=Srv

acdc_agent:monitor_call(Srv, Call),

webseq:note(self(), right, [<<"recv monitor for ">>, CallId, <<", ringing">>]),
webseq:evt(self(), CallId, <<"monitor">>),
webseq:note(self(), right, <<"ringing">>),

{next_state, ringing, State#state{
wrapup_timeout=WrapupTimer
,member_call_id=CallId
Expand Down Expand Up @@ -544,7 +549,7 @@ ready({route_req, Call}, #state{agent_proc=Srv
acdc_stats:agent_oncall(AcctId, AgentId, CallId),

webseq:evt(CallId, self(), <<"outbound call started">>),
webseq:note(self(), right, <<"outbound">>),
webseq:note(self(), right, [<<"outbound: ">>, CallId]),

{next_state
,outbound
Expand Down Expand Up @@ -595,6 +600,7 @@ ringing({originate_resp, ACallId}, #state{agent_proc=Srv
acdc_agent:member_connect_accepted(Srv),

webseq:evt(self(), MCallId, <<"bridged to member">>),
webseq:note(self(), right, <<"answered">>),

{next_state, answered, State#state{call_status_ref=start_call_status_timer()
,call_status_failures=0
Expand All @@ -616,6 +622,7 @@ ringing({originate_failed, _E}, #state{agent_proc=Srv
acdc_stats:agent_ready(AcctId, AgentId),

acdc_util:presence_update(AcctId, AgentId, ?PRESENCE_GREEN),
webseq:note(self(), right, <<"ready">>),
{next_state, ready, clear_call(State)};

ringing({channel_bridged, CallId}, #state{member_call_id=CallId
Expand All @@ -625,7 +632,7 @@ ringing({channel_bridged, CallId}, #state{member_call_id=CallId
acdc_agent:member_connect_accepted(Srv),

webseq:evt(self(), CallId, <<"bridged to member">>),

webseq:note(self(), right, <<"answered">>),
{next_state, answered, State#state{call_status_ref=start_call_status_timer()
,call_status_failures=0
}};
Expand All @@ -648,6 +655,7 @@ ringing({channel_hungup, CallId}, #state{agent_proc=Srv
webseq:note(self(), right, <<"failed to answer phone in time">>),

acdc_util:presence_update(AcctId, AgentId, ?PRESENCE_GREEN),
webseq:note(self(), right, <<"ready">>),
{next_state, ready, clear_call(State)};

ringing({channel_hungup, CallId}, #state{agent_proc=Srv
Expand All @@ -666,6 +674,7 @@ ringing({channel_hungup, CallId}, #state{agent_proc=Srv
webseq:note(self(), right, <<"caller hungup">>),

acdc_util:presence_update(AcctId, AgentId, ?PRESENCE_GREEN),
webseq:note(self(), right, <<"ready">>),
{next_state, ready, clear_call(State)};

ringing({dtmf_pressed, DTMF}, #state{caller_exit_key=DTMF
Expand All @@ -686,6 +695,7 @@ ringing({dtmf_pressed, DTMF}, #state{caller_exit_key=DTMF

webseq:note(self(), right, <<"member call hungup - DTMF">>),

webseq:note(self(), right, <<"ready">>),
{next_state, ready, clear_call(State)};
ringing({dtmf_pressed, DTMF}, #state{caller_exit_key=_ExitKey}=State) ->
lager:debug("caller pressed ~s, exit key is ~s", [DTMF, _ExitKey]),
Expand All @@ -700,6 +710,7 @@ ringing({channel_answered, ACallId}, #state{agent_call_id=ACallId

webseq:evt(self(), MCallId, <<"agent answered line, bridging to member">>),

webseq:note(self(), right, <<"answered">>),
{next_state, answered, State#state{call_status_ref=start_call_status_timer()
,call_status_failures=0
}};
Expand Down Expand Up @@ -756,6 +767,7 @@ answered({dialplan_error, _App}, #state{agent_proc=Srv
webseq:note(self(), right, <<"connecting to member failed">>),

acdc_util:presence_update(AcctId, AgentId, ?PRESENCE_GREEN),
webseq:note(self(), right, <<"ready">>),
{next_state, ready, clear_call(State)};

answered({channel_bridged, CallId}, #state{member_call_id=CallId
Expand All @@ -778,13 +790,15 @@ answered({channel_hungup, CallId}, #state{member_call_id=CallId}=State) ->

webseq:evt(CallId, self(), <<"member hangup">>),

webseq:note(self(), right, <<"wrapup">>),
{next_state, wrapup, State#state{wrapup_timeout=0, wrapup_ref=hangup_call(State)}};

answered({channel_hungup, CallId}, #state{agent_call_id=CallId}=State) ->
lager:debug("agent's channel has hung up"),

webseq:evt(CallId, self(), <<"agent hangup">>),

webseq:note(self(), right, <<"wrapup">>),
{next_state, wrapup, State#state{wrapup_timeout=0, wrapup_ref=hangup_call(State)}};

answered({channel_hungup, CallId}, #state{agent_proc=Srv}=State) ->
Expand All @@ -801,11 +815,13 @@ answered({sync_req, JObj}, #state{agent_proc=Srv

answered({channel_unbridged, CallId}, #state{member_call_id=CallId}=State) ->
lager:debug("caller channel unbridged"),
webseq:note(self(), right, <<"wrapup">>),
{next_state, wrapup, State#state{wrapup_timeout=0
,wrapup_ref=hangup_call(State)
}};
answered({channel_unbridged, CallId}, #state{agent_call_id=CallId}=State) ->
lager:debug("agent channel unbridged"),
webseq:note(self(), right, <<"wrapup">>),
{next_state, wrapup, State#state{wrapup_timeout=0
,wrapup_ref=hangup_call(State)
}};
Expand All @@ -814,6 +830,7 @@ answered({timeout, CRef, ?CALL_STATUS_MESSAGE}, #state{call_status_ref=CRef
,call_status_failures=Failures
}=State) when Failures > 3 ->
lager:debug("call status failed ~b times, call is probably down", [Failures]),
webseq:note(self(), right, <<"wrapup">>),
{next_state, wrapup, State#state{wrapup_timeout=0
,wrapup_ref=hangup_call(State)
}};
Expand All @@ -829,8 +846,7 @@ answered({timeout, CRef, ?CALL_STATUS_MESSAGE}, #state{call_status_ref=CRef
answered({call_status, JObj}, #state{call_status_failures=Failures}=State) ->
case wh_json:get_value(<<"Status">>, JObj) of
<<"active">> -> {next_state, answered, State#state{call_status_failures=0}};
_S ->
{next_state, answered, State#state{call_status_failures=Failures+1}}
_S -> {next_state, answered, State#state{call_status_failures=Failures+1}}
end;

answered(_Evt, State) ->
Expand Down Expand Up @@ -868,8 +884,7 @@ wrapup({timeout, Ref, ?WRAPUP_FINISHED}, #state{wrapup_ref=Ref
acdc_stats:agent_ready(AcctId, AgentId),
acdc_util:presence_update(AcctId, AgentId, ?PRESENCE_GREEN),

webseq:note(self(), right, <<"wrapup finished">>),

webseq:note(self(), right, <<"ready">>),
{next_state, ready, clear_call(State)};

wrapup({sync_req, JObj}, #state{agent_proc=Srv
Expand Down Expand Up @@ -902,7 +917,7 @@ wrapup({route_req, Call}, #state{agent_proc=Srv
acdc_stats:agent_oncall(AcctId, AgentId, CallId),

webseq:evt(CallId, self(), <<"outbound call started while wrapping up">>),

webseq:note(self(), right, <<"outbound">>),
{next_state
,outbound
,State#state{outbound_call_id=CallId
Expand Down Expand Up @@ -945,6 +960,7 @@ paused({timeout, Ref, ?PAUSE_MESSAGE}, #state{sync_ref=Ref

webseq:note(self(), right, <<"wrapup timer finished - timeout">>),

webseq:note(self(), right, <<"ready">>),
{next_state, ready, clear_call(State#state{sync_ref=undefined})};
paused({resume}, #state{acct_id=AcctId
,agent_id=AgentId
Expand All @@ -963,7 +979,7 @@ paused({resume}, #state{acct_id=AcctId
acdc_util:presence_update(AcctId, AgentId, ?PRESENCE_GREEN),

webseq:note(self(), right, <<"wrapup timer finished - resumed">>),

webseq:note(self(), right, <<"ready">>),
{next_state, ready, clear_call(State)};

paused({sync_req, JObj}, #state{agent_proc=Srv
Expand Down Expand Up @@ -996,7 +1012,7 @@ paused({route_req, Call}, #state{agent_proc=Srv
acdc_stats:agent_oncall(AcctId, AgentId, CallId),

webseq:evt(CallId, self(), <<"outbound call started while paused">>),

webseq:note(self(), right, <<"outbound">>),
{next_state
,outbound
,State#state{outbound_call_id=CallId
Expand All @@ -1023,6 +1039,7 @@ outbound({channel_hungup, CallId}, #state{agent_proc=Srv
lager:debug("outbound channel ~s hungup, ready for action", [CallId]),
acdc_agent:channel_hungup(Srv, CallId),
acdc_stats:agent_ready(AcctId, AgentId),
webseq:note(self(), right, <<"ready">>),
{next_state, ready, clear_call(State), hibernate};

outbound({leg_destroyed, CallId}, #state{agent_proc=Srv
Expand All @@ -1033,6 +1050,7 @@ outbound({leg_destroyed, CallId}, #state{agent_proc=Srv
lager:debug("outbound leg ~s destroyed", [CallId]),
acdc_agent:channel_hungup(Srv, CallId),
acdc_stats:agent_ready(AcctId, AgentId),
webseq:note(self(), right, <<"ready">>),
{next_state, ready, clear_call(State), hibernate};

outbound({member_connect_win, JObj}, #state{agent_proc=Srv}=State) ->
Expand All @@ -1047,6 +1065,7 @@ outbound({pause, Timeout}, #state{acct_id=AcctId
Ref = start_pause_timer(Timeout),
acdc_stats:agent_paused(AcctId, AgentId, Timeout),
acdc_util:presence_update(AcctId, AgentId, ?PRESENCE_RED_FLASH),
webseq:note(self(), right, <<"paused">>),
{next_state, paused, clear_call(State#state{sync_ref=Ref})};

outbound({timeout, CRef, ?CALL_STATUS_MESSAGE}, #state{call_status_ref=CRef
Expand All @@ -1056,6 +1075,7 @@ outbound({timeout, CRef, ?CALL_STATUS_MESSAGE}, #state{call_status_ref=CRef
}=State) when Failures > 3 ->
lager:debug("outbound call status failed ~b times, call is probably down", [Failures]),
acdc_stats:agent_ready(AcctId, AgentId),
webseq:note(self(), right, <<"ready">>),
{next_state, ready, clear_call(State), hibernate};
outbound({timeout, CRef, ?CALL_STATUS_MESSAGE}, #state{call_status_ref=CRef
,call_status_failures=Failures
Expand Down
3 changes: 2 additions & 1 deletion whistle_apps/apps/acdc/src/acdc_queue_manager.erl
Expand Up @@ -294,7 +294,8 @@ handle_cast({start_workers}, #state{acct_id=AcctId
], ok;
{error, _E} ->
lager:debug("failed to find agent count: ~p", [_E]),
acdc_queue_workers_sup:new_workers(WorkersSup, AcctId, QueueId, 5)
QWC = whapps_config:get_integer(<<"acdc">>, <<"queue_worker_count">>, 5),
acdc_queue_workers_sup:new_workers(WorkersSup, AcctId, QueueId, QWC)
end,
{noreply, State};

Expand Down
85 changes: 43 additions & 42 deletions whistle_apps/apps/acdc/src/acdc_stats.erl
Expand Up @@ -25,6 +25,7 @@
,agent_wrapup/3
,agent_ready/2
,agent_oncall/3
,agent_handling/3

,init_db/1
,db_name/1
Expand Down Expand Up @@ -180,6 +181,16 @@ agent_paused(AcctId, AgentId, Timeout) ->
}
}).

%% marks the agent as handling a member call
-spec agent_handling/3 :: (ne_binary(), ne_binary(), ne_binary()) -> 'ok'.
agent_handling(AcctId, AgentId, CallId) ->
gen_listener:cast(?MODULE, {store, #agent_stat{agent_id=AgentId
,acct_id=AcctId
,status='handling'
,call_id=CallId
}
}).

-spec agent_wrapup/3 :: (ne_binary(), ne_binary(), integer()) -> 'ok'.
agent_wrapup(AcctId, AgentId, Timeout) ->
gen_listener:cast(?MODULE, {store, #agent_stat{acct_id=AcctId
Expand Down Expand Up @@ -269,40 +280,31 @@ stat_to_jobj(#call_stat{acct_id=AcctId
,caller_id_name=CName
,caller_id_number=CNum
}, Prefix) ->
[wh_json:from_list(
props:filter_undefined(
[{<<"call_id">>, CallId}
,{<<"pvt_account_id">>, AcctId}
,{<<"queue_id">>, QueueId}
,{<<"agent_id">>, AgentId}
,{<<"timestamp">>, Timestamp}
,{<<"status">>, Status}
,{<<"caller_id_name">>, CName}
,{<<"caller_id_number">>, CNum}
,{<<"pvt_type">>, <<"call_partial">>}
,{<<"_id">>, doc_id(Prefix, Timestamp)}
]))
,stat_to_jobj(#agent_stat{
agent_id=AgentId
,acct_id=AcctId
,timestamp=Timestamp
,status='handling'
,call_id=CallId
}, Prefix)
];
stat_to_jobj(#call_stat{
call_id=CallId
,acct_id=AcctId
,queue_id=QueueId
,agent_id=AgentId
,timestamp=TStamp
,wait_time=WaitTime
,talk_time=TalkTime
,abandon_reason=AR
,status=Status
,caller_id_name=CName
,caller_id_number=CNum
}, Prefix) ->
wh_json:from_list(
props:filter_undefined(
[{<<"call_id">>, CallId}
,{<<"pvt_account_id">>, AcctId}
,{<<"queue_id">>, QueueId}
,{<<"agent_id">>, AgentId}
,{<<"timestamp">>, Timestamp}
,{<<"status">>, Status}
,{<<"caller_id_name">>, CName}
,{<<"caller_id_number">>, CNum}
,{<<"pvt_type">>, <<"call_partial">>}
,{<<"_id">>, doc_id(Prefix, Timestamp)}
]));
stat_to_jobj(#call_stat{call_id=CallId
,acct_id=AcctId
,queue_id=QueueId
,agent_id=AgentId
,timestamp=TStamp
,wait_time=WaitTime
,talk_time=TalkTime
,abandon_reason=AR
,status=Status
,caller_id_name=CName
,caller_id_number=CNum
}, Prefix) ->
wh_json:from_list(
props:filter_undefined(
[{<<"call_id">>, CallId}
Expand All @@ -319,14 +321,13 @@ stat_to_jobj(#call_stat{
,{<<"pvt_type">>, <<"call_partial">>}
,{<<"_id">>, doc_id(Prefix, TStamp)}
]));
stat_to_jobj(#agent_stat{
agent_id=AgentId
,acct_id=AcctId
,timestamp=TStamp
,status=Status
,wait_time=WaitTime
,call_id=CallId
}, Prefix) ->
stat_to_jobj(#agent_stat{agent_id=AgentId
,acct_id=AcctId
,timestamp=TStamp
,status=Status
,wait_time=WaitTime
,call_id=CallId
}, Prefix) ->
wh_json:from_list(
props:filter_undefined(
[{<<"pvt_account_id">>, AcctId}
Expand Down
1 change: 1 addition & 0 deletions whistle_apps/apps/acdc/src/webseq.erl
Expand Up @@ -78,6 +78,7 @@ what(IO) when is_list(IO) -> iolist_to_binary(IO).


init(_) ->
file:rename(?WEBSEQNAME, iolist_to_binary([?WEBSEQNAME, ".", wh_util:to_binary(wh_util:current_tstamp())])),
{ok, IO} = file:open(?WEBSEQNAME, [append, raw, delayed_write]),
{ok, #state{io_device=IO
,who_registry=dict:new()
Expand Down

0 comments on commit 3f0cfc8

Please sign in to comment.