Python を使用して Google-App-Engine に Web サイトをデプロイしました。
GAE は「キープアライブ」を保証しないため、ステートレス サーバーを実装しました。
内部変数が変更されるたびに、それらはすぐに GQL データベースに保存されます。
プロセスが開始されるたびに、すべての内部変数が GQL データベースからロードされます。
めったに例外をスローしないシナリオがあり、それを追跡できませんでした。
クライアントが同期 AJAX POST 要求を送信します。
サーバーはセッションを作成し、応答で一意のセッション ID を送信します。
クライアントは、セッション ID を引数として同期 AJAX GET 要求を送信します。
サーバーは応答でテキスト メッセージを送信します。
クライアントのリクエストは同期的であるため、シーケンス全体も同期的です。
私のサーバー内の関連するマッピングは次のとおりです。
from webapp2 import WSGIApplication
from Handler import MyRequestHandler
app = WSGIApplication([
('/request1' ,MyRequestHandler), # post request
('/request2(.*)',MyRequestHandler), # get request
])
私のサーバー内の関連するリクエスト処理は次のとおりです。
from webapp2 import RequestHandler
from Server import MyServer
myServer = MyServer()
class MyRequestHandler(RequestHandler):
def post(self):
try:
if self.request.path.startswith('/request1'):
sessionId = myServer.GetNewSessionId()
self.SendContent('text/plain',sessionId)
except Exception,error:
self.SendError(error)
def get(self,sessionId):
try:
if self.request.path.startswith('/request2'):
textMessage = myServer.GetMsg(sessionId)
self.SendContent('text/plain',textMessage)
except Exception,error:
self.SendError(error)
def SendContent(self,contentType,contentData):
self.response.set_status(200)
self.response.headers['content-type'] = contentType
self.response.headers['cache-control'] = 'no-cache'
self.response.write(contentData)
def SendError(self,error):
self.response.set_status(500)
self.response.write(error.message)
私のサーバーの内部実装は次のとおりです。
class MyServer():
def __init__(self):
self.sessions = SessionsTable.ReadSessions()
def GetNewSessionId(self):
while True:
sessionId = ... # a 16-digit random number
if SessionsTable.ReserveSession(sessionId):
self.sessions[sessionId] = ... # a text message
SessionsTable.WriteSession(self.sessions,sessionId)
return sessionId
def GetMsg(self,sessionId):
return self.sessions[sessionId]
最後に、サーバー内のデータベースのメンテナンスは次のとおりです。
from google.appengine.ext import db
class SessionsTable(db.Model):
message = db.TextProperty()
@staticmethod
def ReadSessions():
sessions = {}
for session in SessionsTable.all():
sessions[session.key().name()] = session.message
return sessions
@staticmethod
@db.transactional
def ReserveSession(sessionId):
if not SessionsTable.get_by_key_name(sessionId):
SessionsTable(key_name=sessionId,message='').put()
return True
return False
@staticmethod
def WriteSession(sessions,sessionId):
SessionsTable(key_name=sessionId,message=sessions[sessionId]).put()
@staticmethod
def EraseSession(sessionId):
SessionsTable.get_by_key_name(sessionId).delete()
例外自体はsessions
、キーを使用したディクショナリへの不正なアクセスを示していsessionId
ます。私の観察によると、この質問の冒頭で説明したクライアント/サーバー シーケンスが、サーバーが比較的長い期間 (数日程度) 「スリープ状態」になった後に開始された場合にのみ発生します。私にはわかりませんが、この問題の原因を突き止める手掛かりが得られるかもしれません。
私の質問:
私のデザインに目に見える問題はありますか?
GAEで同様の問題を経験した人はいますか?
この問題を理解するのに役立つ明らかな解決策やデバッグ方法を誰かが見ていますか?
ありがとう