11/*
22==============================================
33# Licensed Materials - Property of IBM
4- # Copyright IBM Corp. 2018, 2021
4+ # Copyright IBM Corp. 2018, 2022
55==============================================
66*/
77
88/*
99==============================================
1010First created on: Nov/24/2020
11- Last modified on: May/10 /2022
11+ Last modified on: May/16 /2022
1212
1313A) What does this example application do?
1414 --------------------------------------
@@ -547,6 +547,13 @@ public composite VgwDataRouter {
547547 // given time by all the given speech processors that are configured to run.
548548 mutable list<int32> _speechProcessorStatusList =
549549 prepareIdleSpeechProcessorsList($totalNumberOfSpeechProcessorJobs);
550+ // This variable tells us the speech processor id that was
551+ // chosen to process a most recently arrived new voice call.
552+ // This will help us in choosing the speech processors in a
553+ // round robin fashion to evenly distribute the voice calls across
554+ // all the speech processors thereby avoiding the overcrowding of
555+ // just a few speech processors most of the time.
556+ mutable int32 _recentlyChosenSpeechProcessorId = -1;
550557 // This map tells us which speech processor is processing a given vgwSessionId.
551558 // Key=vgwSessionId, Value=Speech Processor Id.
552559 mutable map<rstring, int32> _vgwSessionIdToSpeechProcessorMap = {};
@@ -591,10 +598,12 @@ public composite VgwDataRouter {
591598 // send the speech data belonging to this call.
592599 // Store this VGW session id to change the status of this
593600 // voice call from "brand new" to "ongoing".
594- int32 speechProcessorId =
601+ speechProcessorId =
595602 getSpeechProcessorIdForNewCallProcessing(
596603 _numberOfConcurrentCallsAllowedPerSpeechProcessor,
597- _speechProcessorStatusList);
604+ _speechProcessorStatusList,
605+ $totalNumberOfSpeechProcessorJobs,
606+ _recentlyChosenSpeechProcessorId);
598607
599608 if(speechProcessorId == -1) {
600609 // This condition should not happen as long as there are enough
@@ -616,7 +625,12 @@ public composite VgwDataRouter {
616625 // future use as the speech data keeps coming.
617626 insertM(_vgwSessionIdToSpeechProcessorMap, BSD.vgwSessionId, speechProcessorId);
618627 appTrc(Trace.error, "A new call with vgwSessionId=" + BSD.vgwSessionId +
619- " is being assigned to speech processor id " + (rstring)speechProcessorId);
628+ " is being assigned to speech processor id " + (rstring)speechProcessorId);
629+
630+ // Let us store the currently chosen speech processor id in a
631+ // state variable so that next time when a new call arrives we can
632+ // choose the next speech processor to go in a round robin fashion.
633+ _recentlyChosenSpeechProcessorId = speechProcessorId;
620634 }
621635
622636 // We can prepare this speech data to be sent to the chosen speech processor id.
@@ -1385,33 +1399,72 @@ public list<int32> prepareIdleSpeechProcessorsList(int32 speechProcessorsCount)
13851399// If all the speech processors are busy at this time, it will return -1.
13861400public int32 getSpeechProcessorIdForNewCallProcessing(
13871401 int32 numberOfConcurrentCallsAllowedPerSpeechProcessor,
1388- mutable list<int32> speechProcessorStatusList) {
1402+ mutable list<int32> speechProcessorStatusList,
1403+ int32 speechProcessorsCount,
1404+ int32 recentlyChosenSpeechProcessorId) {
1405+ // We can't do much with an empty list.
13891406 if (size(speechProcessorStatusList) <= 0) {
13901407 return(-1);
13911408 }
13921409
1393- mutable int32 idx = -1;
1410+ // We are given a speech processor id that was earlier chosen for a most recently
1411+ // arrived new voice call. Instead of choosing the same speech processor id
1412+ // immediately for a newly arriving call right now, let us choose the next available
1413+ // speech processor. With this round robin approach, we can give a fair chance to
1414+ // every speech processor to process voice calls as they arrive. This will also
1415+ // help in spreading the voice call processing somewhat evenly across all the
1416+ // available speech processors thereby not overcrowding a few
1417+ // speech processors most of the time.
1418+ //
1419+ // Speech processor ids range from 1 to N. However, the SPL list passed to us above
1420+ // ranges from 0 to N-1. That means, the next speech processor status list index that
1421+ // we want to check is already being pointed to by the recently chosen
1422+ // speech processor id passed above as it is 1 based.
1423+ //
13941424 mutable boolean speechProcessorAvailable = false;
1425+ mutable int32 speechProcessorIdToBeChecked = recentlyChosenSpeechProcessorId;
1426+ mutable int32 loopCnt = 1;
13951427
1396- for(int32 x in speechProcessorStatusList) {
1397- idx++;
1398-
1399- if(x < numberOfConcurrentCallsAllowedPerSpeechProcessor) {
1428+ // If the recently chosen speech processor id is the very last one,
1429+ // let us start from the beginning of the list. We will do the same if this is the
1430+ // very first time this function is getting called with the recently
1431+ // chosen speech processor id set to -1.
1432+ if(recentlyChosenSpeechProcessorId == -1 ||
1433+ recentlyChosenSpeechProcessorId == speechProcessorsCount) {
1434+ speechProcessorIdToBeChecked = 0;
1435+ }
1436+
1437+ // We can try to get one out of the configured number of speech processors as long as
1438+ // there exists a speech processor that is not fully booked at this time.
1439+ while(loopCnt++ <= speechProcessorsCount) {
1440+ // Can we choose this speech processor if it has
1441+ // any available slots to take a new voice call for processing?
1442+ if(speechProcessorStatusList[speechProcessorIdToBeChecked] <
1443+ numberOfConcurrentCallsAllowedPerSpeechProcessor) {
14001444 // This speech processor is not handling its max allowed concurrent calls.
1445+ // This speech processor id is available.
14011446 speechProcessorAvailable = true;
14021447 break;
14031448 }
1404- } // End of for loop.
1449+
1450+ // If we are at the end of the list, let us wrap around to
1451+ // the beginning of the list now.
1452+ if(++speechProcessorIdToBeChecked >= speechProcessorsCount) {
1453+ speechProcessorIdToBeChecked = 0;
1454+ }
1455+ } // End of while loop.
14051456
14061457 if(speechProcessorAvailable == false) {
14071458 // All the speech processors are busy at this time.
14081459 // This is not good news for a newly arrived voice call.
14091460 return(-1);
1410- }
1411-
1412- // A newly arrived call's processing will be assigned to this speech processor.
1413- // Let us increment the given speech processor's current call handling count.
1414- speechProcessorStatusList[idx] = speechProcessorStatusList[idx] + 1;
1415- // Since it is a zero based index array, we will return a value by adding 1 to it.
1416- return(idx + 1);
1461+ } else {
1462+ // A newly arrived call's processing will be assigned to this speech processor.
1463+ // Let us increment the given speech processor's current call handling count.
1464+ speechProcessorStatusList[speechProcessorIdToBeChecked] =
1465+ speechProcessorStatusList[speechProcessorIdToBeChecked] + 1;
1466+ // Since it is a zero based index array, we will return a value by adding 1 to it.
1467+ // As we already mentioned above, we refer to the speech processor ids from 1 to N.
1468+ return(speechProcessorIdToBeChecked + 1);
1469+ }
14171470}
0 commit comments