Skip to content

Commit 8999854

Browse files
authored
Merge pull request #338 from Resgrid/develop
Fix Twilio IncomingMessage timeouts
2 parents b32d621 + 5a61660 commit 8999854

2 files changed

Lines changed: 37 additions & 21 deletions

File tree

Core/Resgrid.Services/SubscriptionsService.cs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,26 +56,34 @@ public SubscriptionsService(IPlansRepository plansRepository, IPaymentRepository
5656

5757
if (!String.IsNullOrWhiteSpace(Config.SystemBehaviorConfig.BillingApiBaseUrl) && !String.IsNullOrWhiteSpace(Config.ApiConfig.BackendInternalApikey))
5858
{
59-
var options = new RestClientOptions(Config.SystemBehaviorConfig.BillingApiBaseUrl)
59+
try
6060
{
61-
MaxTimeout = 200000 // ms
62-
};
61+
var options = new RestClientOptions(Config.SystemBehaviorConfig.BillingApiBaseUrl)
62+
{
63+
MaxTimeout = 5000 // ms — fail fast so callers (e.g. Twilio webhooks) don't exceed their own timeouts
64+
};
6365

64-
var client = new RestClient(options, configureSerialization: s => s.UseNewtonsoftJson());
65-
var request = new RestRequest($"/api/Billing/GetCurrentPlanForDepartment", Method.Get);
66-
request.AddHeader("X-API-Key", Config.ApiConfig.BackendInternalApikey);
67-
request.AddHeader("Content-Type", "application/json");
68-
request.AddParameter("departmentId", departmentId, ParameterType.QueryString);
66+
var client = new RestClient(options, configureSerialization: s => s.UseNewtonsoftJson());
67+
var request = new RestRequest($"/api/Billing/GetCurrentPlanForDepartment", Method.Get);
68+
request.AddHeader("X-API-Key", Config.ApiConfig.BackendInternalApikey);
69+
request.AddHeader("Content-Type", "application/json");
70+
request.AddParameter("departmentId", departmentId, ParameterType.QueryString);
6971

70-
var response = await client.ExecuteAsync<GetCurrentPlanForDepartmentResult>(request);
72+
var response = await client.ExecuteAsync<GetCurrentPlanForDepartmentResult>(request);
7173

72-
if (response.StatusCode == HttpStatusCode.NotFound)
73-
return freePlan;
74+
if (response.StatusCode == HttpStatusCode.NotFound)
75+
return freePlan;
7476

75-
if (response.Data == null)
76-
return freePlan;
77+
if (response.Data == null)
78+
return freePlan;
7779

78-
return response.Data.Data;
80+
return response.Data.Data;
81+
}
82+
catch (Exception ex)
83+
{
84+
Framework.Logging.LogException(ex);
85+
return freePlan;
86+
}
7987
}
8088

8189
return freePlan;

Web/Resgrid.Web.Services/Controllers/TwilioController.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,18 @@ public async Task<ActionResult> IncomingMessage([FromQuery] TwilioMessage reques
143143

144144
if (departmentId.HasValue)
145145
{
146-
var department = await _departmentsService.GetDepartmentByIdAsync(departmentId.Value);
147-
//var textToCallEnabled = await _departmentSettingsService.GetDepartmentIsTextCallImportEnabledAsync(departmentId.Value);
148-
//var textCommandEnabled = await _departmentSettingsService.GetDepartmentIsTextCommandEnabledAsync(departmentId.Value);
149-
var dispatchNumbers = await _departmentSettingsService.GetTextToCallSourceNumbersForDepartmentAsync(departmentId.Value);
150-
var authroized = await _limitsService.CanDepartmentProvisionNumberAsync(departmentId.Value);
151-
var customStates = await _customStateService.GetAllActiveCustomStatesForDepartmentAsync(departmentId.Value);
146+
// Run all department-level lookups in parallel — they are independent of each other.
147+
var departmentTask = _departmentsService.GetDepartmentByIdAsync(departmentId.Value);
148+
var dispatchNumbersTask = _departmentSettingsService.GetTextToCallSourceNumbersForDepartmentAsync(departmentId.Value);
149+
var authorizedTask = _limitsService.CanDepartmentProvisionNumberAsync(departmentId.Value);
150+
var customStatesTask = _customStateService.GetAllActiveCustomStatesForDepartmentAsync(departmentId.Value);
151+
152+
await System.Threading.Tasks.Task.WhenAll(departmentTask, dispatchNumbersTask, authorizedTask, customStatesTask);
153+
154+
var department = departmentTask.Result;
155+
var dispatchNumbers = dispatchNumbersTask.Result;
156+
var authroized = authorizedTask.Result;
157+
var customStates = customStatesTask.Result;
152158

153159
messageEvent.CustomerId = departmentId.Value.ToString();
154160

@@ -196,7 +202,9 @@ public async Task<ActionResult> IncomingMessage([FromQuery] TwilioMessage reques
196202

197203
if (!isDispatchSource)
198204
{
199-
var profile = await _userProfileService.GetProfileByMobileNumberAsync(textMessage.Msisdn);
205+
// Reuse the profile fetched above when the department was resolved via mobile number;
206+
// only hit the DB again if the department came from the phone-number lookup path.
207+
var profile = userProfile ?? await _userProfileService.GetProfileByMobileNumberAsync(textMessage.Msisdn);
200208

201209
if (profile != null)
202210
{

0 commit comments

Comments
 (0)