Tornado を使用するノンブロッキング Web アプリケーションを作成しようとしています。このアプリケーションは、ニュース サイトからデータを取得するためのスケジューラとして PeriodicCallback を使用します。
for nc_uuid in self.LIVE_NEWSCOLLECTORS.keys():
self.LIVE_NEWSCOLLECTORS[nc_uuid].agreggator,ioloop=args
period=int(self.LIVE_NEWSCOLLECTORS[nc_uuid].period)*60
if self.timer is not None: period = int(self.timer)
#self.scheduler.add_job(func=self.LIVE_NEWSCOLLECTORS[nc_uuid].getNews,args=[self.source,i],trigger='interval',seconds=10,id=nc_uuid)
task = tornado.ioloop.PeriodicCallback(lambda:self.LIVE_NEWSCOLLECTORS[nc_uuid].getNews(self.source,i),1000*10,ioloop)
task.start()
コールバックとして呼び出している「getData」には、メソッド process_responce を呼び出して分析するためにデータを解析して TCPServer に送信する非同期 http 要求があります。
@gen.coroutine
def process_response(self,*args,**kwargs):
buf = {'sentence':str('text here')}
data_string = json.dumps(buf)
s.send(data_string)
while True:
try:
data = s.recv(100000)
if not data:
print "connection closed"
s.close()
break
else:
print "Received %d bytes: '%s'" % (len(data), data)
# s.close()
break
except socket.error, e:
if e.args[0] == errno.EWOULDBLOCK:
print 'error',errno.EWOULDBLOCK
time.sleep(1) # short delay, no tight loops
else:
print e
break
i+=1
process_response 内では、ノンブロッキング ソケット操作の基本的な例を使用します。Process_response は次のように表示されます: error 10035 error 10035 Received 75 bytes: '{"mode": 1, "keyword": "\u0435\u0432\u0440\u043e", "sentence": "text here"}'
それは正常な動作に見えます。しかし、データを受信するとき、メインの IOLoop はロックされています! Web サーバーに問い合わせると、定期的なコールバック タスクが終了するまで anydata が返されません...どこが間違っていますか?