Salesforce / PHP - Массовое исходящее сообщение (SOAP), проблема с тайм-аутом - Смотрите обновление # 2

StackOverflow https://stackoverflow.com/questions/2472746

Вопрос

Система Salesforce может отправлять до 100 запросов в одном сообщении SOAP.При отправке этого типа массового запроса на отправку сообщений мой PHP-скрипт завершает выполнение, но SF не может принять ACK, используемый для очистки очереди сообщений на стороне Salesforce.Просматривая журнал исходящих сообщений (мониторинг) Я вижу все сообщения в состоянии ожидания с причиной сбоя доставки "java.net.SocketTimeoutException:Время чтения истекло".Если мой скрипт завершил выполнение, почему я получаю эту ошибку?

Я пробовал эти методы, чтобы увеличить время выполнения на моем сервере, поскольку у меня нет доступа на стороне Salesforce:

  • set_time_limit(0) установить временный_лимит_(0);// в сценарии
  • максимальное время выполнения = 360 ;Максимальное время выполнения каждого скрипта, в секундах
  • max_input_time = 360 ;Максимальное количество времени, которое каждый скрипт может потратить на анализ данных запроса
  • memory_limit = 32M ;Максимальный объем памяти, который может потреблять скрипт

Я использовал высокие настройки только для тестирования.

Есть какие-нибудь мысли относительно того, почему из-за этого не удается вернуть подтверждение в Salesforce?

Вот часть кода:Вот как я принимаю и отправляю файл подтверждения для входящего запроса SOAP

$data = 'php://input';
$content = file_get_contents($data);

if($content) {
    respond('true');
} else {
    respond('false');
}

Функция ответа

function respond($tf) {
    $ACK = <<<ACK
<?xml version = "1.0" encoding = "utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <notifications xmlns="http://soap.sforce.com/2005/09/outbound">
            <Ack>$tf</Ack>
        </notifications>
    </soapenv:Body>
</soapenv:Envelope>
ACK;

    print trim($ACK); 
}

Они находятся в общем сценарии, который я включаю в сценарий, использующий данные для определенного рабочего процесса.Я могу обработать около 25 запросов (которые находятся в 1 ответе SOAP), но как только я перехожу к этому, я получаю ошибку тайм-аута в очереди Salesforce.на 50 запросов обычно моему PHP-скрипту требуется 86,77 секунды.

Может быть, это Apache?PHP?

Я также протестировал простое принятие ответа SOAP на 100 запросов и простое принятие и отправку подтверждения, после чего очередь очищается, так что я знаю, что это на моей стороне.

Я не показываю ошибок в журнале apache, скрипт работает нормально.

Я нашел кое-какую информацию на сайте Salesforce, но по-прежнему безуспешно.Вот связь.

Также я использую PHP Toolkit 11 (от Salesforce).

Другой форум с хорошей справкой по SF

Спасибо за любое понимание этого, --Phill

Обновить:

Если я получу входящее сообщение и распечатаю ответ, должно ли это произойти первым, независимо от того, сделаю ли я что-нибудь еще после?Или он ждет завершения моего процесса, а затем печатает ответ?

ОБНОВЛЕНИЕ №2:

ладно, я думаю, у меня проблема:PHP использует однопоточный подход к обработке и не будет отправлять обратно файл ACK до тех пор, пока поток не завершит его обработку.Есть ли способ сделать это многопоточным процессом?Поток # 1 - примите входящий запрос SOAP и отправьте обратно подтверждение Поток # 2 - Обработайте запрос SOAP

Я знаю, что мог бы разбить его на что-то вроде таблицы базы данных или плоского файла, но есть ли способ добиться этого, не делая этого?

Я собираюсь попытаться закрыть сокет после отправки подтверждения и продолжить обработку, скрестив пальцы, это сработает.

Это было полезно?

Решение 5

Итак, что я сделал, это:

  1. Принимайте все входящие OBM, преобразуйте их в базу данных
  2. Когда это будет сделано, запускайте процесс, который выполняется в фоновом режиме (на самом деле я отправляю его в фоновый режим, чтобы скрипт мог завершиться)
  3. Отправить файл подтверждения обратно

Просто принимая необработанные данные, разбор на поля и вставка их в базу данных выполняется довольно быстро.Затем я запускаю команду командной строки Linux, которая также отправляет скрипт обработки для запуска в фоновом режиме.Затем я отправляю файл подтверждения в SF, и скрипт завершается в течение отведенного времени.Разбивать процесс написания сценария на два отдельных этапа громоздко, но это работает.

Другие советы

Похоже, что время ожидания исходящего сообщения истекло.Другие пользователи сообщали о таймаутах всего в 10 секунд (см. Ссылку на форум ниже).У экземпляра песочницы, который я использую (cs1), истекает время ожидания примерно через 1 минуту после моего тестирования.Возможно, что время ожидания является параметром уровня организации или экземпляра, которым управляет Salesforce.

Две вещи, которые вы могли бы попробовать:

  1. Откройте запрос в службу поддержки Salesforce, чтобы узнать, могут ли они увеличить время ожидания для исходящих сообщений.Исходя из моего опыта, существует множество настроек, которые они могут изменять на уровне организации - это может быть одна из них.

  2. Разгрузите обработку ваших данных, чтобы подтверждение было немедленно отправлено обратно в Salesforce.Тогда фактическая обработка ваших данных будет происходить асинхронно.т.е.Сообщение очередь, отдельный поток и т.д.

Некоторые другие ресурсы, которые могли бы быть полезны:

обсуждение на форуме Salesforce по теме

Документация по исходящим сообщениям

Я думаю, что они приостанавливают работу, ожидая завершения Вашего сценария.

Есть способ, которым вы могли бы попытаться это исправить.

Выведите конверт с сообщением ack в начале, а затем сбросьте его, чтобы их сервер получил его до того, как вы завершите обработку.Никакой многопоточности, просто переосмысление приоритетов :)

прочтите это для получения наилучшей информации о содержимом для промывки

Вы на 100% уверены, что Salesforce будет ждать столько времени, сколько потребуется для запуска ваших скриптов?80 секунд мне тоже кажутся долгим сроком.

Если все запросы завершились неудачей, я бы предположил, что Salesforce ожидает, что вы установите Content-Type заголовок соответствующий, но, похоже, это не тот случай.

Я не знаю насчет Salesforce, но если вы хотите использовать многопоточность с помощью PHP, вам следует взглянуть на этот пример кода а точнее , к pcntl_fork().

N.B:pcntl - это нет включен по умолчанию и не будет работать на платформах Windows.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top