Created
August 31, 2015 12:01
-
-
Save Slach/74a59904190e6ad56b08 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Session(object): | |
@defer.inlineCallbacks | |
def load_by_sid(self): | |
# ТОРМОЗИТ РАНДОМНО любая из команд к Redis | |
player_id = yield self.redis_db.hget(SESSION_KEY, self.sid) | |
if not player_id: | |
raise error.EInternalError(error.ERROR_INVALID_SID, sid=self.sid) | |
yield self.load_by_player_id() | |
@defer.inlineCallbacks | |
def load_by_player_id(self): | |
if self.player_id is None: | |
defer.returnValue(None) | |
self.player_session_key = self.get_player_session_key(self.player_id) | |
# ТОРМОЗИТ РАНДОМНО любая из команд к Redis | |
session_data = yield self.redis_db.hgetall(self.player_session_key) | |
if not session_data: | |
raise error.EInternalError(error.ERROR_SESSION_IS_EXPIRED) | |
for k, v in session_data.iteritems(): | |
setattr(self, k, v) | |
# ТОРМОЗИТ РАНДОМНО любая из команд к Redis | |
yield self.redis_db.expire(self.player_session_key, const.SESSION_TTL) | |
# ТОРМОЗИТ ВОТ ЭТОТ КОД | |
@defer.inlineCallbacks | |
def get_session_by_sid(sid): | |
session = Session(sid=sid) | |
yield session.load_by_sid() | |
defer.returnValue(session) | |
class SetProfileHandler(CustomErrorPageMixin, CustomPynbaMonitoringMixin, cyclone.web.RequestHandler): | |
@defer.inlineCallbacks | |
def post(self): | |
with self.pynba.timer(state='parse_request'): | |
parsed_request = service.unpack_request(self.request) | |
# ВОТ ЭТОТ КОД работает больше 2 секунд при 150 rps ;( | |
№ redis при этом показывает что команды выполняется не более чем за 0.04 сек (40000 microsec) | |
with self.pynba.timer(state='get_session_by_sid'): | |
session = yield session_model.get_session_by_sid(parsed_request['sid']) | |
# этот код РАБОТАЕТ менее 0.1с | |
with self.pynba.timer(state='get_player_by_session'): | |
profile = profile_model.PlayerProfile(player_id=session.player_id) | |
yield profile.load(field_list=('changed_from_external',)) | |
if profile.changed_from_external: | |
raise error.EInternalError(error.ERROR_PROFILE_CHANGED_FROM_EXTERNAL) | |
profile_data = parsed_request["profile"] | |
# этот код ТАКЖЕ работает менее 0.1с | |
with self.pynba.timer(state='save_profile_data'): | |
yield profile.save(profile_data) | |
# этот код ТАКЖЕ работает менее 0.1с | |
with self.pynba.timer(state='write_response'): | |
resp = sign.sign_response(resp, parsed_request, session.sid, session.device_uuid, session.user_uuid) | |
resp_string = service.pack(resp) | |
resp_string = sign.sign_response_data(resp, resp_string) | |
self.write(resp_string) | |
WEB_HANDLERS = [ | |
(r"/game/\d+/set_profile/", SetProfileHandler), | |
] | |
#инициализация сервиса | |
@defer.inlineCallbacks | |
def main(): | |
# skip parse args | |
args = parser.parse_args() | |
path_to_config = args.path_to_config[0] | |
application = cyclone.web.Application(WEB_HANDLERS, | |
error_handler=CustomErrorHandler) | |
# это просто синглтон | |
service.name = TEST_SERVICE | |
service.config = config | |
service.service_id = 1 | |
try: | |
yield service.initialize() | |
except: | |
logging.critical(traceback.format_exc()) | |
reactor.callLater(0, reactor.stop) | |
raise | |
# правильно ли я инициализирую listenTCP ???? | |
reactor.listenTCP( | |
port=config["service"]["port"], | |
factory=application, | |
interface=config["service"]["host"], | |
backlog=config["service"]["backlog"] | |
) | |
if __name__ == "__main__": | |
reactor.callWhenRunning(main) | |
reactor.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment