Обратные вызовы в экономичных асинхронных функциях? - PullRequest
20 голосов
/ 31 марта 2010

В Комиссионный можно использовать модификатор oneway , чтобы указать вызов как асинхронный .

По-видимому, невозможно определить обратный вызов , хотя он будет выполняться после завершения выполнения функции.

Кажется, что единственная возможность, которую я имею, - это дать клиенту Thrift( PHP ) некоторые «серверные» возможности, поэтому, когда тяжелые вычисления завершаются на стороне сервера, я могу отправить ему уведомление.Это означает, что у меня должен быть новый файл .thrift с новыми определениями, новыми службами и всем остальным, и что я должен генерировать код на стороне php-сервера с помощью Thrift.

Даже если это выполнимо, он выглядит такдля меня это излишество, и мне интересно, есть ли более умный способ реализовать обратный вызов.

Ждем ваших отзывов, ребята.

Ответы [ 4 ]

19 голосов
/ 10 апреля 2010

Роберто, к сожалению, среда Thrift не имеет такой встроенной функциональности. может быть несколько альтернатив , однако, в зависимости от того, что вы хотите, чтобы ваш клиентский PHP-сеанс выполнял в то время, когда вы обычно ожидали бы ответа от вычислительно-интенсивного сервера Thrift (если бы вы не использовали oneway).

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

С самого начала вы абсолютно правы, пытаясь избежать решения, которого вы пытаетесь избежать. Ваши сеансы PHP-клиента не могут обслуживать интерфейс обратного вызова, не блокируя (если только вы не копаете дыру еще глубже, пытаясь использовать pcntl_fork или какой-либо другой PHP-поток поддержки .)

Самый простой и ИМХО лучший выход из этого - это два переключения с модели, управляемой событиями ( Я хочу получать уведомление, когда сервер завершен ) на модель опроса ( Я буду периодически запрашивать у сервера, выполняется ли это .) Существует несколько способов реализации модели опроса с несколькими вариантами реализации на сервере и на клиенте. стороны, такие как:

  1. во время фазы вызова :

    • клиентская сессия PHP выделяет уникальное значение job_id; затем сеанс выполняет асинхронный oneway вызов void compute(..., job_id) для вычислительного сервера Thrift, требующего больших вычислительных ресурсов,

    - или -

    • клиентский сеанс PHP делает синхронный вызов job_id start_compute(...) для интенсивно вычислительного сервера Thrift; сервер выделяет уникальное значение job_id, затем порождает актуальную вычислительно-интенсивную задачу в отдельном потоке / процессе, сразу возвращаясь к сеансу клиента PHP с выделенным job_id
  2. на этапе вычисления :

    • клиентский сеанс PHP продолжает периодически проверять состояние вычислительно-интенсивного задания через синхронный status get_status(job_id) вызов вычислительно-интенсивного Thrift-сервера,

    - или -

    • клиентский сеанс PHP завершается сразу же, чтобы высвободить ценные ресурсы, после передачи job_id браузеру и инструктирования браузера периодически проверять состояние вычислительно-интенсивного задания job_id (например, через META REFRESH, или через XHR (AJAX) запрос из Javascript и т. Д.); проверка браузера порождает короткий сеанс PHP-клиента, который выполняет синхронный status get_status(job_id) вызов вычислительного сервера Thrift с интенсивными вычислениями, который завершается сразу после пересылки состояния (в зависимости от того, что это может быть) в браузер
8 голосов
/ 13 апреля 2010

Я получил ответ на канале, отличном от переполнения стека. Поскольку автор дал мне разрешение опубликовать здесь свой ответ, я подумал, что он может быть полезен кому-то еще в сообществе.

Привет, Роберт,

Да, это появилось на Apache списки раньше. Там нет элегантного способа делать то, что вы просите с Бережливость. Это принципиально не предназначен для двунаправленных сообщений.

Вокруг этого есть такие хаки, как: - опрос на стороне клиента - вызывая send_method (), ожидая на стороне клиента, затем recv_method (), вместо просто method () - заставить клиента также реализовать сервер Thrift

Но, очевидно, ни один из них не является правдой двунаправленный обмен сообщениями. Мы пробовали сохранить интерфейсы Thrift как максимально простой и сфокусированный на основной вариант использования RPC, который означал оставив некоторые вещи вроде этого.

Наверное, не тот ответ, которым вы были в надежде на

Приветствия, Максли

3 голосов
/ 04 февраля 2012

Вместо того, чтобы пытаться реализовать обратные вызовы с Thrift (что, по-моему, значительно усложнило бы протокол), я использую облегченную службу обмена сообщениями (STOMP - http://stomp.github.com) для информирования клиента об асинхронных событиях.

Мой подход заключается в том, что клиент Thrift подписывается на определенный канал STOMP, и сервер Thrift будет публиковать сообщения на этом же канале всякий раз, когда происходит асинхронное событие. Затем клиент может запросить у сервера дополнительную информацию о событии.

0 голосов
/ 02 сентября 2010

Ну, в Java есть вызовы Asynchronus Message через ссылку на объект будущего. Это может быть реализовано в модели RPC с использованием Message Pack . Я не уверен, что в PHP есть что-то похожее.

...