I am integrating GoESL (https://www.php.cn/link/d9b64cee05c46d31b10b9869a3198a6d) with Temporal to automate via FreeSWITCH dial. This setup allows 1,000 concurrent channels and 50 calls per second (CPS). Each dialing attempt starts a temporary workflow that initiates the call through an activity.
After 96 successfully initiated calls (a variable number), FreeSWITCH handles no more calls. There are no logs in the CLI and no events in the event socket layer to indicate further attempts. However, if I stop the Temporal Worker, the previously "stuck" calls appear in the FreeSWITCH CLI indicating that they have been queued by the GoESL client. I can confirm that the worker is not stuck as it continues to launch the main workflow.
The following are relevant code snippets:
Lead processing loop:
for _, lead := range leadResult.Leads { // [omitted setup and checks] // Checking for channel availability and sleeping to respect CPS limits workflow.Await(ctx, func() bool { return dialerQueryResponse.AvailableChannels > 0 }) timeToSleep := time.Second / time.Duration(dialerQueryResponse.CallsPerSecondLimit) workflow.Sleep(ctx, timeToSleep) // Dialing the lead fmt.Printf("dialing lead %s\n", lead) dialLead(lead, selectedDialer.Id, callTimeout) fmt.Print("lead dialed\n\n") }
Dial-up guidance logic:
dialLead := func(lead string, selectedDialerId, dialerCallTimeout int) { // Setup child workflow context with unique ID cwo.WorkflowID = fmt.Sprintf("Campaign_Call_%s", lead) childCtx := workflow.WithChildOptions(ctx, cwo) // Struct to pass input to the child workflow input := domain.CallWorkflowInput{ Lead: lead, DialerId: selectedDialerId, CampaignName: cds.CampaignName, DialplanExtension: cc.Survey.DialplanExtension, CallTimeout: dialerCallTimeout, } // Executing the child workflow and handling its future future := workflow.ExecuteChildWorkflow(childCtx, CallWorkflow, input) var dialerId int selector.AddFuture(future, func(f workflow.Future) { err := f.Get(ctx, &dialerId) // Error handling and updating concurrency state // ... }) }
Call workflow function:
func CallWorkflow(ctx workflow.Context, input domain.CallWorkflowInput) (int, error) { // [omitted setup] // Executing the originate call activity var dialLeadResult domain.DialLeadResponse if err := workflow.ExecuteActivity(ctx, activity.Dialer.OriginateCallActivity, dialInput).Get(ctx, &dialLeadResult); err != nil { // Error handling } // [omitted post-call handling] }
Execute the call initiating activities in sequence:
func (a *DialerActivities) OriginateCallActivity(ctx context.Context, input domain.DialLeadRequest) (domain.DialLeadResponse, error) { // [omitted client selection] // Command to originate the call cmd := fmt.Sprintf("originate {%s}%s/%s/%s 704 XML default test %s 10", variables, protocol, gateway, input.DestinationNumber, input.OriginatingNumber) err := selectedClient.BgApi(cmd) if err != nil { // Error handling } // [omitted response preparation] }}, nil }
Has anyone encountered a similar issue using GoESL or Temporal, where calls seem to be queued and not executed past a certain point? Any suggestions on how to debug this situation or why killing the temporary worker thread might trigger the handling of queued calls?
What I tried:
workflow.Sleep
duration from a few milliseconds to 5 - 10 seconds to ensure it is not network latency causing the problem. Decided to change the GoESL software package (https://www.php.cn/link/d9b64cee05c46d31b10b9869a3198a6d) to use Different GoESL packages (https://www.php.cn/link/8c8566b78ac2b99c542bef8c37cac179) and the problem has been solved. Seems to be a fundamental issue in the initial GoESL package.
I've opened an issue on the Github repository here (https://github.com/0x19/goesl/issues/40) in case anyone encounters the same problem in the future.
The above is the detailed content of GoESL vs. Temporal: The call does not originate from a certain point in FreeSWITCH. For more information, please follow other related articles on the PHP Chinese website!