Twilio иногда слишком быстро отвечает на запросы ресурсов SMS или телефонных звонков - PullRequest
0 голосов
/ 12 декабря 2018

Фон

У меня есть веб-приложение без состояния, написанное на C # и работающее на Transact-SQL.В любой момент времени может быть запущено n серверов, поэтому для сохранения состояния каждого телефонного звонка / смс-сообщения мы записываем сведения о звонке в базу данных.

Проблема

В большинстве случаев это работает, поскольку база данных может записать SID Call / SMS в базу данных до того, как Twilio выполнит обратный вызов.Однако иногда мы видим, что обратные вызовы Twilio приходят до , когда данные записываются в базу данных.

Я наблюдал, как это происходит в реальном времени в моей среде отладки, поэтому яНа 100% уверен, что это то, что происходит.

Попытки решения

Таким образом, наша главная таблица, которая отслеживает каждый звонок / смс, огромна и сильно проиндексирована, как числопроцессов зависит от способности видеть быстрые ответы на запросы в этой таблице.Это имеет побочный эффект замедления скорости записи.

Итак, я создал избыточную буферную таблицу для всех текущих вызовов.Как только Twilio сделает соответствующие обратные вызовы, мы помечаем строку для удаления, и она удаляется в пакете (примерно раз в минуту).

Эта стратегия смягчила проблему, однако иногда мы видим, как Twilio выполняет обратные вызовы до того, как эта таблица также была записана.Снимаю шляпу перед Twilio за способность так быстро отвечать на запросы вызовов, но это действительно неприятность с моей стороны, так как большая часть нашего программного обеспечения зависит от успешных обратных вызовов.Если SID не записывается в базу данных к моменту поступления обратного вызова, невозможно связать вызов с записью базы данных.

Off The Table Solutions

Таблицы, оптимизированные для памяти, к сожалению, не обсуждаются, так как наш уровень Azure SQL довольно низок (мы некоммерческая организация).Я проделал еще несколько работ по оптимизации базы данных, но, опять же, даже в нашей очень маленькой буферной таблице данные записываются недостаточно быстро.

Вопрос

Итак, с учетом вышесказанного у меня есть несколько вопросов:

  • Могу ли я получить SID вызова / SMS перед началом телефонного звонка?Таким образом, я могу дождаться действия записи в базу данных перед началом вызова.
  • Могу ли я заставить Twilio повторить обратный вызов позже, когда мой сервер не сможет получить SID?

Код:

private static void MakeCall(Shift_Offer so, Callout callout, testdb2Entities5 db)
        {
            callout.status = CalloutStatus.inprogress;
            db.SaveChanges();
            try
            {
                // CallQueue is a special table for fast write access, 
                //so we can maintain relationship between call and sid before big slow ShiftOffer table has finished writing
                CallQueue callQueueItem = new CallQueue(); 
                callQueueItem.offer_id = so.shift_offer_id;
                callQueueItem.offer_finished = false;           
                var call = CallResource.Create //twilio starts the call when you call create
                            (
                                url: new Uri(TwilioCallBotController.TwilioCalloutScriptURL),
                                from: new Twilio.Types.PhoneNumber(RCHStringHelpers.formatPhoneNumber(callout.callback_number)),
                                to: new Twilio.Types.PhoneNumber(RCHStringHelpers.formatPhoneNumber(so.employee_phone_number)),
                                statusCallback: new Uri(TwilioCallBotController.StatusCallbackURL),
                                statusCallbackEvent: new List<string> { "initiated", "ringing", "answered", "completed" }
                            );
                callQueueItem.twilio_sid = call.Sid; //only after create is called do we have an Sid
                db.CallQueues.Add(callQueueItem); //write SID to buffer table
                db.SaveChanges();
                Console.WriteLine(call.Sid);
                so.offer_timestamp = DateTime.Now.ToLocalTime();               
                if (call.Status != CallResource.StatusEnum.Failed)
                {
                    Debug.WriteLine(call.Sid.ToString()
                                    + " " + call.StartTime.ToString()
                                    + " " + call.Status.ToString());
                    so.twillio_sid = call.Sid; //now we write the SID to our main call tracking table
                    so.status = call.Status.ToString();
                    db.SaveChanges();
                }
                else
                {
                    callQueueItem.offer_finished = true;
                    so.offer_status = ShiftOfferStatus.Failed;
                    so.status = call.Status.ToString();
                    callout.status = CalloutStatus.inprogressWaitingNext;
                    db.SaveChanges();
                    Debug.WriteLine(call.Status.ToString());
                }
            }
            catch (SqlException e) //if we run into any problems here, release the lock to prevent stalling
            {
                 //do exception handling stuff here, not relevant to this question
            }
}

1 Ответ

0 голосов
/ 12 декабря 2018

Это похоже на сопутствующую проблему.Поскольку вы не можете утверждать, когда будет выполнен обратный вызов из twilio (до или после записи в БД), вы можете предположить, что вызов будет до.

Следовательно, вам нужен способ уведомить метод обратного вызова, еслизапись в БД была успешной.Например:

      dbWriteFlag = false;
      db.CallQueues.Add(callQueueItem); //write SID to buffer table
      db.SaveChanges();
      dbWriteFlag = true;

и метод обратного вызова обращается к флагу, чтобы узнать, был ли он записан.

Если у вас нет доступа к этому виду флага, я могу предложить проверитьесли запись находится в БД, прежде чем что-то делать, а если нет, подождите и перепроверьте, пока она не будет записана.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...