-
Notifications
You must be signed in to change notification settings - Fork 215
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conference timeout and termination API - Restcomm 1171 #2617
Conversation
@@ -58,12 +68,21 @@ private CustomHttpClientBuilder() { | |||
} | |||
|
|||
private static CloseableHttpClient defaultClient = null; | |||
private static CloseableHttpAsyncClient closeableHttpAsyncClient = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure putting sync and async factory in same class is meaningful (maybe a separated async factory would have work better). Lets keep it like this by now, since we are reuding the lifecycle, and final closing during app shutdown...
if (sender != null && !sender.isTerminated()) { | ||
sender.tell(response, self()); | ||
} else { | ||
if (logger.isInfoEnabled()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens if we send msg to terminated actor? checking actor state from the outside is not guaranteed,as in the next instruction the state may have changed. So, there will be chances where we send the response,and the actor is terminated. Not sure is worth to make the distinction here, or maybe send response blindly to actor, and let Akka figure out what to do (deadletter box..)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree with letting akka handle the delivery dynamics
if (contentType != null) { | ||
builder.setContentType(contentType.getValue()); | ||
} | ||
builder.setContent(StringUtils.toString(stream)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i dont like how response is stringified here, i think it should be original "sender" responsability to do this if appropiate. I can see the existing HttpResponseDescriptor already expectsa String content, but i think its a bit dangerous in terms of encoding(this is assuming body is JVM charset encoded/UTF8...) and performance(we loss any streaming chance, and we create an String in memory with potentially big body with no control on actual length)
not sure worth the refactoring, but very worrying...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we refactor this as part of this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it will impact Downloader as well,so I guess we can do that later...
if(logger.isDebugEnabled()) | ||
logger.debug(String.format("Conference cdr is null for sid: %s", sid)); | ||
}else{ | ||
return DateTime.now().getMillis()-cdr.getDateCreated().getMillis(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we assume all JVM/OS nodes in the cluster are clock synced? are the nodes configured to sync system clock from a central server regularly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaimecasero Network Time Protocol (NTP) is configured by default on Amazon Linux instances and for cloud service is up and running to make it synchronised to NTP server.
|
||
String conferenceSid = getConferenceSid(confRoom1); | ||
assertEquals(2, getParticipantsSize(conferenceSid)); | ||
int liveCalls = MonitoringServiceTool.getInstance().getStatistics(deploymentUrl.toString(), adminAccountSid, adminAuthToken); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it worthit to depend test result on monitorignService? i expect monitoring service to collect on some collection frequency, will the test be stable if we include this assertion here?.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo monitoring service is a nice way to check live calls in memory, not sure why test would be unstable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I though monitoringService was getting stats from other components from time to time. Apparently components push data into monitoring service in real time instead. So i guess its safe to use the MonService during test... nevermind my comment
} | ||
|
||
private int getActiveConferencesSize() { | ||
JsonObject conferences = RestcommConferenceTool.getInstance().getConferences(deploymentUrl.toString(),adminAccountSid, adminAuthToken); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this may reuse my new countByFilter metthod :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaimecasero can you explain how can i use a dao method at this level, is there an api available on top of that ?
bobCall.listenForDisconnect(); | ||
georgeCall.listenForDisconnect(); | ||
|
||
assertTrue(bobCall.waitForDisconnect(80 * 1000)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i guess this depends on conf timeout, where is the conf timeout configured here? i guess the default 4hours is not good for testing. is this configured at rcml level for this tetscase?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaimecasero its not 4 hours for testing, its 60 seconds for testing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where are those 60 seconds configured?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in restcomm-conference.xml
aka restcomm.xml
for this specific test class
// Bob is a simple SIP Client. Will not register with Restcomm | ||
private SipStack bobSipStack; | ||
private SipPhone bobPhone; | ||
private String bobContact = "sip:bob@127.0.0.1:5090"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we make this test follow paralle testing approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
letme change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -331,6 +331,9 @@ private AuthOutcome secureLevelControl(Account operatedAccount, String resourceA | |||
String operatedAccountSid = null; | |||
if (operatedAccount != null) | |||
operatedAccountSid = operatedAccount.getSid().toString(); | |||
if (isSuperAdmin()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will this affect to other existing operations? Seems like a big change.... Of course this means is the superAdmin anyway, but just wanted to check if this will change anything for other existing RESTAPI operations...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this change would mean that superadmin account would have control over restcomm APIs (number, clients, call, conference etc) regardless of the fact that resource being owned by another account in the system
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq but there is already a method for this org.restcomm.connect.http.SecuredEndpoint#isSuperAdmin
and can be used from any endpoint its needed.
I think if we go with this patch then we mess the SecuredEndpoints and the rules to follow and it will be harder to debug later.
I think we should remove this and instead check with isSuperAdmin
method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gvagenas good point, i added this check for superadmin in conference and call endpoints intead
logger.info(String.format("updateConference accountsid: %s conferenceSid: %s", accountSid, sid)); | ||
Account account = daoManager.getAccountsDao().getAccount(accountSid); | ||
try { | ||
secure(account, "RestComm:Read:Conferences"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this the correct literal "RestComm:Read:Conferences"? i dont know the convention, but this is not a ReadOnly operation, here we are modifying the conference, shouldnt be somethign like "Restcomm:Write:Conferences"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice catch, updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let me know your opinion on comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq I provided my comments and one of the most important is that the CallApiClient actor is a top-level actor and as far as I can see this actors will never get destroyed unless the Akka system stops.
Also, using LCM from Restcomm to Restcomm inside the cluster is very bad and restrictive design to my point of view, but this is not related to the patch here but rather to the old design decisions that were taken.
final String status = data.getFirst("Status"); | ||
|
||
if(status != null){ | ||
if(status.equalsIgnoreCase("completed")){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq I think we need to provide a default response in the case where the provided status DOESN NOT match the completed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
private void kickoutAllActiveParticipants(ConferenceDetailRecord conferenceDetailRecord){ | ||
List<CallDetailRecord> callDetailRecords = daoManager.getCallDetailRecordsDao().getRunningCallDetailRecordsByConferenceSid(conferenceDetailRecord.getSid()); | ||
|
||
if(callDetailRecords == null || callDetailRecords.isEmpty()){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq also here I think we need a response to tell user that there were no participants
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gvagenas I dont think it need other than a suceesful response, user will get conference resource in response.
this case here is just to make sure in a race case when participants leave themselves before system kick them out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
main issue with any single response is that this would require to wait for result on async actions started from here, and which may take time (LVM remote invocation). The response should be succesful if the action of terminating the conf may be initiated.
I think any client can check the RESTAPI later to see how many participants are left at any moment...
return new CallApiClient(sid, daoManager); | ||
} | ||
}); | ||
return system.actorOf(props); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq here you create a top-level actor with a parent the system itself.
Nowhere in the patch, you destroy this actor, thus this actor and its child actors HttpAsycClientHelper
will stay in memory for as long as the akka system is up and running.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq I believe better design would be to use ASK pattern, delegate the task to CallManager which create CallApiClient , use to kill the calls and then destroy the actor.
On top, we can use ASK pattern without blocking, just fire the request and return, since we don't need the response.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq also delegating the task to CallManager, we can save some LCM (http) requests.
CallManager can check which of the CDRs are local calls or not and either use update call method or LCM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq I see the local calls are removed by the Conferences endpoint (Evicting private class) but still I think the task to remove remote calls actors should be delegated to CallManager that will create CallApiClient actors and then destroy them
logger.info("Call api response succeeded " + response.succeeded()); | ||
logger.info("Call api response: " + response); | ||
} | ||
requestee.tell(message, self); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq with the current implementation the requestee
will always be null.
Shouldn't we protect the code for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please chek comments below
} | ||
|
||
protected void onHangup(Hangup message, ActorRef self, ActorRef sender) throws URISyntaxException, ParseException { | ||
requestee = sender; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq What is the reason behind this? Any plans to use the CallApiClient in other places where we will need to return back the response, because currently there is no use of that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i have changed both CallApiClient and ConferenceApiClient to be disposable (used for one time request), they will clean them selves after sending back DownloaderResponse
} | ||
|
||
@Override | ||
public void postStop () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq as far as I can see, CallApiClient will never be destroyed and thus this method will never be called, see my comments on ConferencesEndpoint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i have changed both CallApiClient and ConferenceApiClient to be disposable (used for one time request), they will clean them selves after sending back DownloaderResponse
} | ||
} | ||
|
||
private String getSuperAdminAuthenticationHeader(){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq since the ConferencesEndpoint.updateConference() can be used by any account with RestComm:Modify:Conferences
permision, why we create LCM using super admin credentials?
I think we should use the credentials of the account that requested the update initially
} | ||
} | ||
|
||
private String getSuperAdminAuthenticationHeader(){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq I think we should use the credentials of the account that requested the stop conference initially and not the super admin.
+ "At the postStop() method."); | ||
} | ||
if(conferenceApiClient != null && !conferenceApiClient.isTerminated()) | ||
getContext().stop(conferenceApiClient); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq instead of waiting for the Conference actor to get destroyed in order to destroy the conferenceApiClient, we can make use of the fact the ConferenceApiClient will send the DownloaderResponse to the Confernece actor and kill the actor at this point
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gvagenas i have changed both CallApiClient
and ConferenceApiClient
to be disposable (used for one time request), they will clean them selves after sending back DownloaderResponse
@@ -331,6 +331,9 @@ private AuthOutcome secureLevelControl(Account operatedAccount, String resourceA | |||
String operatedAccountSid = null; | |||
if (operatedAccount != null) | |||
operatedAccountSid = operatedAccount.getSid().toString(); | |||
if (isSuperAdmin()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq but there is already a method for this org.restcomm.connect.http.SecuredEndpoint#isSuperAdmin
and can be used from any endpoint its needed.
I think if we go with this patch then we mess the SecuredEndpoints and the rules to follow and it will be harder to debug later.
I think we should remove this and instead check with isSuperAdmin
method
* master: fixed counter increase created notice in doc to alert about SMPP regex disable added test for new RegexRemover restore previous number selection,and disable regexes for smpp allow usage for nonSIP scenarios use organizationutil to match incomingphonenumber. make test more stable by preventing conunt of data from previous testcase Fixed #2625: Update Quick Start documentation for Android BETA7 removed listPhones from dao attributes, DAO needs to be stateless. fixed toString method to show fields fixed sip and tomcat as test dependencies in parent.defined proper dependencies at child level. Patch to fix Record race condition. Also provides enhancements for MockMediaGateway. This close #RESTCOMM-1219 This close #RESTCOMM-1229 This close #RESTCOMM-1230 This close #RESTCOMM-1231 Work in progress This refer to #RESTCOMM-1219 Patch for MockMediaGateway to create recording file on RQNT ES (sg=pr) request This refer to #RESTCOMM-1219 Work in progress This refer to #RESTCOMM-1219 Patch for MockMediaGateway to create recording file on RQNT ES (sg=pr) request This refer to #RESTCOMM-1219 Patch for MockMediaGateway to create recording file on RQNT ES (sg=pr) request This refer to #RESTCOMM-1219 Work in progress This refer to #RESTCOMM-1219 Work in progress This refer to #RESTCOMM-1219 Work in progress This refer to #RESTCOMM-1219
…est) and get destroyed after that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq please check my comments, I think there few things to improve.
There are some comments related to the local and remote call actors, that I am not sure are correct, lets discuss about them
@@ -309,8 +326,10 @@ public void execute(Object message) throws Exception { | |||
final Leave leave = new Leave(); | |||
call.tell(leave, super.source); | |||
} | |||
//tell conference api client to call conference api to terminate conference and kick all calls | |||
conferenceApiClient = conferenceApiClient(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq Is there a way to tell if a conference has remote participants or not? This would be a great improvement in order to save resources by not creating and executing the ConferenceApiClient
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can check by DB but that is like alternative to me not an optimisation, in most cases it would be an overhead query
if(message.getCallDetailRecord().getInstanceId().equals(RestcommConfiguration.getInstance().getMain().getInstanceId())){ | ||
ActorRef callTobeHangup = lookup(new GetCall(message.getCallDetailRecord().getCallPath())); | ||
if (callTobeHangup != null){ | ||
callTobeHangup.tell(message, self); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq at the Conference.onStopConference() method, the Conference actor will ask all local call actors to leave.
The call actor at this point will send BYE to the sip client.
So there is no need to send Hangup to the local call actors.
Important! I think there is a bug in the call actor where after Leave message is received, the call actor will never get destroyed.
As far as I can see, when the call actor receives Leave
message:
- Will send bye
- Will tell MmsCallController to leave (destroy media resources)
Possible BUG -> 3. The Call.onMediaServerControllerStateChanged doesn't take care of the MmsCallController response while state isLeaving
We need to investigate this one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gvagenas do you think this is part of the scop of this PR? this bug is there regardless if we merge this patch or not no? can we handle that seperatly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq do you think this is part of the scop of this PR?
the bug is not in the scope of this PR but I believe CallManager shouldn't try to Hangup local calls.
if (logger.isInfoEnabled()) { | ||
logger.info("Conference Received Timeout, will stop conference now."); | ||
} | ||
onStopConference(new StopConference(SUPER_ADMIN_ACCOUNT_SID), self, sender); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq Maybe we should differentiate the StopConference initiated by SuperAdmin and the one initiated by the timer. This is just an idea, not sure about the implementation but I think if it sounds feasible to you we should investigate it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can provide a reason
field in StopConference
as well in API, in case of timeout its will be conference time limit reached
this field will later be passed as reason header in corresponding BYE to sip clients
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq sounds good
logger.warning(String.format("could not retrive any conference record for this conference accountSid %s name: %s", accountSid, name)); | ||
return null; | ||
}else{ | ||
return conferenceDetailRecords.get(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq isn't this dangerous since we pick the first available Conference in the DB? I believe we should stop and fail the request when conferenceSid is null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conferenceSid
is not always available at local conference we care about accountSid:name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq but still picking up the first on the list its dangerous since this one might not be the conference we are looking for
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gvagenas as per our conference design/state, there is only one conference in DB in running state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq ??? Only one conference in running state? I am missing something here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There will be only 1 RUNNING Conference for AccountSid and given Name
Conference ID is unique because AccountSid+ConferenceName is unique
} else { | ||
try { | ||
URI uri = new URI("/restcomm"+conferenceDetailRecord.getUri()); | ||
uri = UriUtils.resolve(uri); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq here we rely on the fact that the cluster has a common public IP address (the LB public IP). Nothing bad in the current phase but maybe the conferenceDetailRecord.getUri()
should contain the remote IP Address (when/if the conference is remote).
This would help later to have conferences between instances that don't belong to the same "cluster".
This is just an idea for discussion.
Account account = daoManager.getAccountsDao().getAccount(accountSid); | ||
Account effectiveAccount = userIdentityContext.getEffectiveAccount(); | ||
try { | ||
secure(account, "RestComm:Modify:Conferences"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq Since later we use isSuperAdmin()
I don't think we need to check permissions here.
The updateConference()
method could be protected with just the isSuperAdmin()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conference termination request can be initiated by owner of the conference as well hence we need to make sure that resource is being accessed by proper account
//allow super admin to perform update on any conference - https://telestax.atlassian.net/browse/RESTCOMM-1171 | ||
if (!isSuperAdmin()) { | ||
try { | ||
secure(account, cdr.getAccountSid(), SecuredType.SECURED_STANDARD); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq can you elaborate on that? Why we use secure again here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conference termination request can be initiated by owner of the conference as well hence we need to make sure that resource is being accessed by proper account
final String status = data.getFirst("Status"); | ||
|
||
if(status != null){ | ||
if (status.equalsIgnoreCase("completed")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq you can combine status != null
AND status.equalsIgnoreCase("completed")
in the same if
statement so we don't need duplicate else
clause that does exactly the same thing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, changed
while(iterator.hasNext()){ | ||
final CallDetailRecord CallDR = iterator.next(); | ||
if (callManager == null) | ||
callManager = (ActorRef) context.getAttribute("org.restcomm.connect.telephony.CallManager"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq why don't you retrieve the CallManager
actor outside the while
statement so you do it just once and not for every CDR in the list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point
final CallDetailRecord CallDR = iterator.next(); | ||
if (callManager == null) | ||
callManager = (ActorRef) context.getAttribute("org.restcomm.connect.telephony.CallManager"); | ||
callManager.tell(new Hangup("Conference Terminated", effectiveAccount.getSid(), CallDR), null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq Does it worth to create a new message instead of use Hangup that is used by VoiceInterpreter to ask the Call actor to terminate the call?
Not important, just wondering if it would be a better approach to have a new message here
@maria-farooq I am not comfortable with the current implementation because I can see redundant functionality and not a clear separation of concerns in the actors/endpoints involved. Let me elaborate:
Currently, your patch implements the following:
My comments on the above implementation:
|
* master: Updated quick start for beta.5. added unstable beased on latest test results from CI LiveCallModificationTest modified to test LiveCall and Mgcp metrics This refer to #RESTCOMM-1238 fixes subsequent regex removal includign category to exclude unstable tests
…incharge of removing local and remote participants
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq see my comments for a minor issue that I think should be fixed.
Other than that looks good
@@ -95,6 +108,8 @@ | |||
private Sid sid; | |||
private final List<ActorRef> calls; | |||
private final List<ActorRef> observers; | |||
//list of callApiClients created by Conference | |||
private List<ActorRef> callApiClients; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq There is no need to keep a list of CallApiClients, this is redundant and will consume memory for no reason. See my comment later for the onDownloaderResponse
method
private void onDownloaderResponse(DownloaderResponse message, ActorRef self, ActorRef sender) { | ||
//make sure we only remove sender that is callApiClient and was created by this conference actor | ||
//so we don't kill a sender that has accidently broadcast a DownloaderResponse to this conference. | ||
if(callApiClients.contains(sender)){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maria-farooq as said earlier no need to keep a list of CallApiClient
and then check if sender is on the list.
I believe we should stop sender straight away UNLESS if there is a chance to receive DownloaderResponse from other actors, which I cannot think of such a case.
Even if that's the case (other actors sends DownloaderResponse to Conference) maybe its better to create another wrapper message for the responses of CallApiClient
@gvagenas created a new wrapper for callapiresponse instead of reusing downloader response. |
related issues:
https://telestax.atlassian.net/browse/RESTCOMM-1171
https://telestax.atlassian.net/browse/RESTCOMM-758