Я пытаюсь подписаться на фид pubsubhubbub (pshb) на superfeedr. Путь протокол PSHB работы являетсяHTTP-запрос при создании ActiveRecord
- вы Отправить POST к концентратору с просьбой подписаться на канал и обеспечить обратный вызов
- хаб отправляет GET для обратного вызова для проверки вашего намерения подписаться
- вы ответить говоря да, я хочу подписаться
- ступицу отвечает подписной проверки
Я бегу сервер локально на мой Dev машине. У меня есть код, который может успешно подписаться на фид, я тестирую его, выполнив его непосредственно в консоли rails. Теперь я создал модель Feed ActiveRecord и хочу автоматически подписываться каждый раз, когда создается новая запись Feed. Я добавил функцию обратного вызова ActiveRecord в модели фидера в качестве такого
after_create :subscribe_feed
Теперь, когда я создаю активной записи я вижу правильный запрос HTTP выйти, то есть длинный повесить (около 5 секунд, где ничего не происходит в журналов), тогда ответ от сервера pshb приходит к выводу, что мой обратный вызов не может быть достигнут.
Здесь находится бревна (число добавленного мною для опорных точек)
(1) (0.1ms) begin transaction
(2) SQL (4.4ms) INSERT INTO "feeds" ("created_at", "updated_at", "url") VALUES (?, ?, ?) [["created_at", Fri, 15 Nov 2013 23:08:39 UTC +00:00], ["updated_at", Fri, 15 Nov 2013 23:08:39 UTC +00:00], ["url", "http://push-pub.appspot.com/feed"]]
(3) pshb subscribe parameters: {:headers=>{"Accept"=>"application/json"}, :body=>{"hub.mode"=>"subscribe", "hub.verify"=>"sync", "hub.callback"=>"http://...myserver.../pub_sub/callback", "hub.topic"=>"http://push-pub.appspot.com/feed", "hub.verify_token"=>"superfeedtest", "format"=>"json"}}
(4) # ABOUT 5 SECOND WAIT
(5) Subscribe Response: #<HTTParty::Response:0x7fd2180cd978 parsed_response="Your callback couldn't be reached.\n", @response=#<Net::HTTPUnprocessableEntity 422 Unprocessable Entity readbody=true>, @headers={"server"=>["nginx/0.8.52"], "date"=>["Fri, 15 Nov 2013 23:08:44 GMT"], "content-type"=>["text/plain; charset=utf-8"], "connection"=>["close"], "status"=>["422 Unprocessable Entity"], "x-runtime"=>["10057"], "content-length"=>["35"], "set-cookie"=>["_superfeedr_session=BAh7BzoMdXNlcl9pZGkC%2BIY6D3Nlc3Npb25faWQiJTBiMDExZGYzNzU4Mjk0MTMxNjc4NmE0OTg3MDhlMjJk--85d29756ae4b5ae9464630741372af7656f3894b; path=/; HttpOnly"], "cache-control"=>["no-cache"], "pubsubhubbub-version"=>["0.3"]}>
(6) (7.2ms) commit transaction
Redirected to http://67.180.177.165/feeds/28
Completed 302 Found in 10695ms (ActiveRecord: 11.6ms)
(7) Started GET "/pub_sub/callback?hub.challenge=437c4b3b47aa1dbf4072a2d8abb5c39a&hub.lease_seconds=315360000&hub.mode=subscribe&hub.topic=http%3A%2F%2Fpush-pub.appspot.com%2Ffeed&hub.verify_token=superfeedtest" for 173.255.193.75 at 2013-11-15 15:08:50 -0800
Вы можете видеть, что после ответа фиксацию транзакции происходит (6), а затем получить от сервера PHSB спрашивать (7). Таким образом, концентратор может достичь моего обратного вызова, но по какой-то причине я не получаю GET от хаба до тех пор, пока не истечет время ожидания?
Я новичок в рельсах, поэтому не уверен, как все работает, но я предполагаю, что что-то происходит с параллелизмом запросов в середине создания ActiveRecord. Подписка работает сама по себе, но не во время создания ActiveRecord, поскольку я установил ее в after_create.
Каков правильный способ обработки HTTP-запроса сторонним серверам, если вы хотите сделать это, когда создается запись ActiveRecord?
УКАЗАНИЕ ** в superfeedr api вы можете указать намерение проверки асинхронно. Когда я укажу, что это async, я получаю ответ об успешном ответе, но подписка по-прежнему, похоже, не разбивается на концентратор суперфильтра. Я напрямую свяжусь с superfeedr об этой проблеме, но в целом я хочу знать, как обрабатывать эту ситуацию для API, у которых нет опции async.
Я не стал бы связывать процесс ActiveRecord из-за запроса GET. Если ваш запрос занимает слишком много времени, ваш код зависает, что будет плохо для вашего сервера и всех ваших пользователей. Люди могут даже использовать DOS, поставляя фиктивные записи, которые, как они знают, займут некоторое время. Вместо этого напишите URL-адрес в своей базе данных, а затем запустите поток, который обрабатывает только этот процесс подписки, а затем завершает работу. Или посмотрите на что-то вроде AMQP/RabbitMQ и напишите узел, который обрабатывает задание для вас; Он не повесит ваш сервер Rails, он будет автоматически вставлен в очередь и будет достаточно легким. –