Skip to content

Commit a55787d

Browse files
committed
Changes done for v2.3.5.
1 parent b8fe2d0 commit a55787d

File tree

7 files changed

+152
-43
lines changed

7 files changed

+152
-43
lines changed

com.ibm.streamsx.sttgateway/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes
22

3+
## v2.3.5
4+
* May/16/2022
5+
* Added code and logic necessary for the VgwDataRouter application to select a speech processor for handling a new voice call in a round robin fashion. This will allow for an even distribution of the voice calls across the configured number of speech processors.
6+
37
## v2.3.4
48
* May/11/2022
59
* Added code and logic necessary to handle certain error situations where the SpeechProcessor will send much more than the required two transcriptionCompleted signals.

com.ibm.streamsx.sttgateway/info.xml

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

1515
**Note:** This toolkit requires c++11 support.
1616
</description>
17-
<version>2.3.4</version>
17+
<version>2.3.5</version>
1818
<requiredProductVersion>4.2.1.6</requiredProductVersion>
1919
</identity>
2020
<dependencies>

samples/VgwDataRouter/com.ibm.streamsx.sttgateway.sample/VgwDataRouter.spl

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
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
==============================================
1010
First created on: Nov/24/2020
11-
Last modified on: May/10/2022
11+
Last modified on: May/16/2022
1212

1313
A) 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.
13861400
public 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
}

samples/VgwDataRouter/info.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
<info:identity>
55
<info:name>VgwDataRouter</info:name>
66
<info:description>Example that shows how to route VGW speech data to different Speech processor jobs</info:description>
7-
<info:version>1.0.5</info:version>
7+
<info:version>1.0.6</info:version>
88
<info:requiredProductVersion>4.2.1.6</info:requiredProductVersion>
99
</info:identity>
1010
<info:dependencies>
1111
<info:toolkit>
1212
<common:name>com.ibm.streamsx.sttgateway</common:name>
13-
<common:version>[2.3.3,7.0.0]</common:version>
13+
<common:version>[2.3.5,7.0.0]</common:version>
1414
</info:toolkit>
1515
<info:toolkit>
1616
<common:name>com.ibm.streamsx.websocket</common:name>

samples/VgwDataRouterMini/com.ibm.streamsx.sttgateway.sample/VgwDataRouter.spl

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/*
99
==============================================
1010
First created on: Nov/24/2020
11-
Last modified on: May/10/2022
11+
Last modified on: May/16/2022
1212

1313
A) What does this example application do?
1414
--------------------------------------
@@ -496,6 +496,13 @@ public composite VgwDataRouter {
496496
// given time by all the given speech processors that are configured to run.
497497
mutable list<int32> _speechProcessorStatusList =
498498
prepareIdleSpeechProcessorsList($totalNumberOfSpeechProcessorJobs);
499+
// This variable tells us the speech processor id that was
500+
// chosen to process a most recently arrived new voice call.
501+
// This will help us in choosing the speech processors in a
502+
// round robin fashion to evenly distribute the voice calls across
503+
// all the speech processors thereby avoiding the overcrowding of
504+
// just a few speech processors most of the time.
505+
mutable int32 _recentlyChosenSpeechProcessorId = -1;
499506
// This map tells us which speech processor is processing a given vgwSessionId.
500507
// Key=vgwSessionId, Value=Speech Processor Id.
501508
mutable map<rstring, int32> _vgwSessionIdToSpeechProcessorMap = {};
@@ -541,7 +548,9 @@ public composite VgwDataRouter {
541548
speechProcessorId =
542549
getSpeechProcessorIdForNewCallProcessing(
543550
_numberOfConcurrentCallsAllowedPerSpeechProcessor,
544-
_speechProcessorStatusList);
551+
_speechProcessorStatusList,
552+
$totalNumberOfSpeechProcessorJobs,
553+
_recentlyChosenSpeechProcessorId);
545554

546555
if(speechProcessorId == -1) {
547556
// This condition should not happen as long as there are enough
@@ -556,13 +565,17 @@ public composite VgwDataRouter {
556565
" next time to handle your maximum expected concurrent calls.");
557566
return;
558567
}
559-
568+
560569
// Let us store the speech processor id of this call for
561570
// future use as the speech data keeps coming.
562571
insertM(_vgwSessionIdToSpeechProcessorMap, BSD.vgwSessionId, speechProcessorId);
563572
appTrc(Trace.error, "A new call with vgwSessionId=" + BSD.vgwSessionId +
564573
" is being assigned to speech processor id " + (rstring)speechProcessorId);
565-
574+
575+
// Let us store the currently chosen speech processor id in a
576+
// state variable so that next time when a new call arrives we can
577+
// choose the next speech processor to go in a round robin fashion.
578+
_recentlyChosenSpeechProcessorId = speechProcessorId;
566579
} else {
567580
// This incoming tuple carries speech data belonging to a
568581
// voice call that we have already started processing.
@@ -928,33 +941,72 @@ public list<int32> prepareIdleSpeechProcessorsList(int32 speechProcessorsCount)
928941
// If all the speech processors are busy at this time, it will return -1.
929942
public int32 getSpeechProcessorIdForNewCallProcessing(
930943
int32 numberOfConcurrentCallsAllowedPerSpeechProcessor,
931-
mutable list<int32> speechProcessorStatusList) {
944+
mutable list<int32> speechProcessorStatusList,
945+
int32 speechProcessorsCount,
946+
int32 recentlyChosenSpeechProcessorId) {
947+
// We can't do much with an empty list.
932948
if (size(speechProcessorStatusList) <= 0) {
933949
return(-1);
934950
}
935951

936-
mutable int32 idx = -1;
952+
// We are given a speech processor id that was earlier chosen for a most recently
953+
// arrived new voice call. Instead of choosing the same speech processor id
954+
// immediately for a newly arriving call right now, let us choose the next available
955+
// speech processor. With this round robin approach, we can give a fair chance to
956+
// every speech processor to process voice calls as they arrive. This will also
957+
// help in spreading the voice call processing somewhat evenly across all the
958+
// available speech processors thereby not overcrowding a few
959+
// speech processors most of the time.
960+
//
961+
// Speech processor ids range from 1 to N. However, the SPL list passed to us above
962+
// ranges from 0 to N-1. That means, the next speech processor status list index that
963+
// we want to check is already being pointed to by the recently chosen
964+
// speech processor id passed above as it is 1 based.
965+
//
937966
mutable boolean speechProcessorAvailable = false;
967+
mutable int32 speechProcessorIdToBeChecked = recentlyChosenSpeechProcessorId;
968+
mutable int32 loopCnt = 1;
938969

939-
for(int32 x in speechProcessorStatusList) {
940-
idx++;
941-
942-
if(x < numberOfConcurrentCallsAllowedPerSpeechProcessor) {
970+
// If the recently chosen speech processor id is the very last one,
971+
// let us start from the beginning of the list. We will do the same if this is the
972+
// very first time this function is getting called with the recently
973+
// chosen speech processor id set to -1.
974+
if(recentlyChosenSpeechProcessorId == -1 ||
975+
recentlyChosenSpeechProcessorId == speechProcessorsCount) {
976+
speechProcessorIdToBeChecked = 0;
977+
}
978+
979+
// We can try to get one out of the configured number of speech processors as long as
980+
// there exists a speech processor that is not fully booked at this time.
981+
while(loopCnt++ <= speechProcessorsCount) {
982+
// Can we choose this speech processor if it has
983+
// any available slots to take a new voice call for processing?
984+
if(speechProcessorStatusList[speechProcessorIdToBeChecked] <
985+
numberOfConcurrentCallsAllowedPerSpeechProcessor) {
943986
// This speech processor is not handling its max allowed concurrent calls.
987+
// This speech processor id is available.
944988
speechProcessorAvailable = true;
945989
break;
946990
}
947-
} // End of for loop.
991+
992+
// If we are at the end of the list, let us wrap around to
993+
// the beginning of the list now.
994+
if(++speechProcessorIdToBeChecked >= speechProcessorsCount) {
995+
speechProcessorIdToBeChecked = 0;
996+
}
997+
} // End of while loop.
948998

949999
if(speechProcessorAvailable == false) {
9501000
// All the speech processors are busy at this time.
9511001
// This is not good news for a newly arrived voice call.
9521002
return(-1);
953-
}
954-
955-
// A newly arrived call's processing will be assigned to this speech processor.
956-
// Let us increment the given speech processor's current call handling count.
957-
speechProcessorStatusList[idx] = speechProcessorStatusList[idx] + 1;
958-
// Since it is a zero based index array, we will return a value by adding 1 to it.
959-
return(idx + 1);
1003+
} else {
1004+
// A newly arrived call's processing will be assigned to this speech processor.
1005+
// Let us increment the given speech processor's current call handling count.
1006+
speechProcessorStatusList[speechProcessorIdToBeChecked] =
1007+
speechProcessorStatusList[speechProcessorIdToBeChecked] + 1;
1008+
// Since it is a zero based index array, we will return a value by adding 1 to it.
1009+
// As we already mentioned above, we refer to the speech processor ids from 1 to N.
1010+
return(speechProcessorIdToBeChecked + 1);
1011+
}
9601012
}

samples/VgwDataRouterMini/info.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
<info:identity>
55
<info:name>VgwDataRouterMini</info:name>
66
<info:description>Example that shows how to route VGW speech data to different Speech processor jobs</info:description>
7-
<info:version>1.0.5</info:version>
7+
<info:version>1.0.6</info:version>
88
<info:requiredProductVersion>4.2.1.6</info:requiredProductVersion>
99
</info:identity>
1010
<info:dependencies>
1111
<info:toolkit>
1212
<common:name>com.ibm.streamsx.sttgateway</common:name>
13-
<common:version>[2.3.3,7.0.0]</common:version>
13+
<common:version>[2.3.5,7.0.0]</common:version>
1414
</info:toolkit>
1515
<info:toolkit>
1616
<common:name>com.ibm.streamsx.websocket</common:name>

sttgateway-tech-brief.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
============================================================
22
First created on: July/01/2018
3-
Last modified on: May/11/2022
3+
Last modified on: May/16/2022
44

55
Purpose of this toolkit
66
-----------------------

0 commit comments

Comments
 (0)