Лучший способ объединения каналов в Google App Engine

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

Я занимался мозговым штурмом (местами) для реализации пула каналов, но каждый метод, о котором я думаю, имеет некоторые довольно серьезные недостатки.

Статическая память сервлета. Хорошо, но при открытии нового экземпляра виртуальной машины и/или передачи клиента с одной виртуальной машины на другую будет выпадать довольно много открытых каналов.

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

Backend Instance. Вероятно, это лучший вариант с точки зрения надежности, но теперь затраты на запуск бэкэнда будут в первую очередь поглощать все преимущества внедрения пула!

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

Ответы

Ответ 1

Вот что я буду делать (я действительно подумываю о написании этой библиотеки после просмотра вашего вопроса, мне тоже нужно):

Создайте модуль taskpool со следующим API.

client_id, token = taskpool.get()

# Setup a heartbeat in the client JS, maybe every minute. 
# Also call this every time the client indicates presence
taskpool.ping(client_id)

taskpool.release(client_id)

Реализация:

  • Сохраните client_id и token в сущности со статусом, указывающим, будет ли он использоваться, время последнего пинга и время создания. Пусть ключ client_id. Также рассмотрите возможность использования NDB. Бесплатная memcaching.

get() проверяет наличие неиспользуемых токенов и возвращает один, если он находит его. В противном случае создайте новый, сохраните и верните его.

ping() обновляет время последнего пинга для этого токена. Вместо опроса пусть клиент посылает пингу каждый [биение сердца].

release() отмечает токен как неиспользуемый.

Запустите задачу /cron каждые [сердцебиение] секунд, чтобы найти маркеры, которые не получили пинг через некоторое время, и установите их как неиспользуемые.

Когда клиенты сообщают о закрытом токене, выполните get().

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

Я обновлю этот ответ, если и когда я напишу это как библиотеку.