コード例 #1
0
async def echo_handler(session: SocketSession, msg: object):
    if not session.is_client:
        await session.send_message(msg)
        logger.info("recv msg: %s" % msg)
    else:
        logger.info("client recv msg: %s" % msg)
    pass
コード例 #2
0
async def _dispatch_actor_message_in_loop(actor: ActorBase):
    loop_id = _new_loop_id()
    context = actor.context
    assert context

    if context.loop_id != 0:
        return
    context.loop_id = loop_id
    loaded = False

    try:
        try:
            await actor.activate_async()
            loaded = True
        except Exception as e:
            logger.error(
                "Actor:%s/%s ActivateAsync Fail, Exception:%s, StackTrace:%s"
                % (actor.type_name, actor.uid, e, traceback.format_exc())
            )
            context.loop_id = 0
            return
        while True:
            # 让出CPU给其他协程, 防止某些协程等待时间过长
            await asyncio.sleep(0)
            o = cast(
                Tuple[weakref.ReferenceType[SocketSession], object],
                await context.pop_message(),
            )
            if o is None:
                logger.info(
                    "Actor:%s/%s exit message loop" % (actor.type_name, actor.uid)
                )
                break
            session, msg = o[0]() if o[0] else None, o[1]
            if isinstance(msg, RpcRequest):
                context.reentrant_id = msg.reentrant_id
                await _dispatch_actor_rpc_request(actor, session, msg)
            else:
                await actor.dispatch_message(msg)
    except Exception as e:
        logger.error(
            "_dispatch_actor_message_loop, Exception:%s, StackTrace:%s"
            % (e, traceback.format_exc())
        )
        pass

    try:
        if loaded:
            await actor.deactivate_async()
    except Exception as e:
        logger.error(
            "Actor:%s/%s DeactivateAsync Fail, Exception:%s, StaceTrace:%s"
            % (actor.type_name, actor.uid, e, traceback.format_exc())
        )

    if context.loop_id == loop_id:
        context.reentrant_id = -1
        context.loop_id = 0
    logger.info("Actor:%s/%s loop:%d finished" % (actor.type_name, actor.uid, loop_id))
コード例 #3
0
 def remove_session(self, session_id: int):
     if session_id in self._session_dict:
         session = self._session_dict[session_id]
         if session:
             session.close()
         del self._session_dict[session_id]
         logger.info("SocketSessionManager.remove_session, SessionID:%d" %
                     session_id)
コード例 #4
0
 def close(self):
     logger.info("TcpSession.close, SessionID:%d Address:%s" %
                 (self.session_id, self._address))
     self._stop = True
     try:
         self._writer.close()
     except:
         pass
コード例 #5
0
ファイル: hotfix.py プロジェクト: egmkang/koala
 async def patch_code(self, code: str) -> Tuple[str, Optional[Exception]]:
     try:
         logger.info("patch_code, %s" % code)
         exec(code)
     except Exception as e:
         logger.exception(e)
         return ("fail", e)
     return ("success", None)
コード例 #6
0
async def qps():
    last = 0
    while True:
        await asyncio.sleep(1.0)
        v = finished
        if v - last > 0:
            logger.info("QPS:%d" % (v - last))
            last = v
コード例 #7
0
ファイル: event_handler.py プロジェクト: egmkang/koala
def _process_connect_success(session: SocketSession):
    if session:
        session.heart_beat(_last_process_message_time)
        logger.info("SocketSessionManager, SessionID:%d, ConnectSuccess" %
                    session.session_id)
    else:
        logger.error("SocketSessionManager, SessionID:%d not found" %
                     session.session_id)
コード例 #8
0
 def add_session(self, session: SocketSession):
     session_id = session.session_id
     if session_id in self._session_dict:
         return
     self._session_dict[session_id] = session
     logger.info(
         "SocketSessionManager.add_session, SessionID:%d, CodecID:%d" %
         (session_id, session.codec.codec_id))
コード例 #9
0
ファイル: placement.py プロジェクト: egmkang/koala
 def _try_delete_old_server(self, node: api.HostNodeInfo) -> bool:
     if self._config.address == node.address and self.server_id() > node.server_id:
         logger.info(
             "try_delete_old_server, OldServerID:%s Address:%s"
             % (node.server_id, node.address)
         )
         asyncio.create_task(api.delete_server(node.server_id, node.address))
         return True
     return False
コード例 #10
0
async def client():
    await asyncio.sleep(2.0)
    session = await TcpSocketSession.connect("127.0.0.1", 5555, codec_id)
    count = 0
    while True:
        await asyncio.sleep(1.0)
        if session is not None:
            await session.send_message("hello world: %d" % count)
            logger.info("%d" % count)
            count += 1
    pass
コード例 #11
0
ファイル: placement.py プロジェクト: egmkang/koala
 def remove_server(self, node: ServerNode):
     _membership_manager.remove_member(node.server_uid)
     try:
         self._on_remove_server(node)
         logger.info("PD RemoveServer, ServerID:%d, Address:%s:%s" %
                     (node.server_uid, node.host, node.port))
     except Exception as e:
         logger.error(
             "Placement.RemoveServer, ServerUID:%d, Exception:%s, StackTrace:%s"
             % (node.server_uid, e, traceback.format_exc()))
         pass
コード例 #12
0
 async def __gc_actors(cls, actors: Dict[ActorID, ActorBase]):
     current_time = time.time()
     need_remove: List[Tuple[ActorID, ActorBase]] = list()
     for actor_id, actor in actors.items():
         if (not actor.context or current_time >=
                 actor.context.last_message_time + actor.gc_time()):
             need_remove.append((actor_id, actor))
     for actor_id, actor in need_remove:
         if actor.context:
             await actor.context.push_message(None)
         logger.info("gc_actors, Actor:%s/%s" %
                     (actor.type_name, actor.uid))
         actors.pop(actor_id)
コード例 #13
0
ファイル: placement.py プロジェクト: egmkang/koala
 def add_server(self, node: ServerNode):
     server = node
     _membership_manager.add_member(server)
     try:
         self._on_add_server(server)
         logger.info(
             "PD AddServer, ServerID:%d, Address:%s:%s, Desc:%s" %
             (server.server_uid, server.host, server.port, server.desc))
     except Exception as e:
         logger.error(
             "Placement.AddServer, ServerUID:%d, Exception:%s, StackTrace:%s"
             % (node.server_uid, e, traceback.format_exc()))
         pass
コード例 #14
0
ファイル: simple.py プロジェクト: egmkang/koala
 async def _try_connect(self, node: ServerNode):
     try:
         session = await TcpSocketSession.connect(node.host, int(node.port),
                                                  CODEC_RPC)
         if session is not None:
             node.set_session(session)
             logger.info("try_connect ServerID:%d, Host:%s:%s success" %
                         (node.server_uid, node.host, node.port))
             self.session = session
     except Exception as e:
         logger.error("try_connect ServerID:%d, Host:%s:%s, Exception:%s" %
                      (node.server_uid, node.host, node.port, e))
     pass
コード例 #15
0
ファイル: koala_host.py プロジェクト: egmkang/koala
async def _try_update_load_loop():
    impl = Placement.instance()
    last = 0
    while True:
        await asyncio.sleep(10)
        try:
            v = _actor_manager.weight
            if last != v:
                logger.info("ActorWeight:%d" % v)
                last = v
            impl.set_load(last)
        except:
            pass
コード例 #16
0
    async def listen(self, port: int, codec_id: int):
        codec = _codec_manager.get_codec(codec_id)
        if codec is None:
            logger.error("listen port:%d failed, CodecID:%d not found" %
                         (port, codec_id))
            return

        async def callback(reader: asyncio.StreamReader,
                           writer: asyncio.StreamWriter):
            assert codec
            await self._handle_new_session(codec, reader, writer)

        try:
            await asyncio.start_server(callback, port=port, limit=WINDOW_SIZE)
            logger.info("listen port:%d CodecID:%d success" % (port, codec_id))
        except Exception as e:
            logger.error("listen port:%d Exception:%s" % (port, e))
コード例 #17
0
ファイル: placement.py プロジェクト: egmkang/koala
 async def find_position(self, i_type: str, uid: object) -> Optional[ServerNode]:
     node = self.find_position_in_cache(i_type, uid)
     if node is not None and node.session is not None:
         return node
     resp = await api.find_actor_position(i_type, "%s" % uid, 0)
     if resp.error_code != 0:
         raise Exception("%s" % resp.error_msg)
     node = _membership.get_member(resp.server_id)
     if node is not None:
         self._lru_cache[(i_type, uid)] = node.server_uid
         logger.info(
             "FindActorPosition:%s/%s, ServerID:%s, Address:%s:%s"
             % (i_type, uid, node.server_uid, node.host, node.port)
         )
     else:
         if (i_type, uid) in self._lru_cache:
             del self._lru_cache[(i_type, uid)]
         logger.info("FindActorPosition:%s/%s position not found" % (i_type, uid))
     return node
コード例 #18
0
ファイル: placement.py プロジェクト: egmkang/koala
 async def _try_connect(cls, node: ServerNode):
     begin = time.time()
     try:
         session = await TcpSocketSession.connect(
             node.host, int(node.port), CODEC_RPC
         )
         if session is not None:
             node.set_session(session)
             logger.info(
                 "try_connect ServerID:%d, Host:%s:%s success"
                 % (node.server_uid, node.host, node.port)
             )
     except Exception as e:
         end = time.time()
         logger.error(
             "try_connect ServerID:%d, Host:%s:%s, CostTime:%sms, Exception:%s"
             % (node.server_uid, node.host, node.port, int((end - begin) * 1000), e)
         )
     pass
コード例 #19
0
ファイル: account.py プロジェクト: egmkang/koala
async def process_gateway_account_login(session: SocketSession, msg: object):
    global _config
    if not _config:
        _config = koala_config.get_config()

    request = cast(RpcMessage, msg)
    req = cast(RequestAccountLogin, request.meta)
    body = request.body
    body_message, check_sum = utils.message_check_sum(
        body, private_key=_config.private_key)
    logger.info(
        "process_gateway_account_login, SessionID:%s, OpenID:%s, ServerUD:%s , CheckSum:%s, %s"
        %
        (req.session_id, req.open_id, req.server_id, check_sum, body_message))

    resp = ResponseAccountLogin()
    resp.session_id = req.session_id
    resp.actor_type = body_message.get("actor_type", "IPlayer")
    resp.actor_id = body_message.get("actor_id", "1")
    await session.send_message(RpcMessage(meta=resp))
コード例 #20
0
ファイル: placement.py プロジェクト: egmkang/koala
 async def register_server(self):
     resp = await api.new_server_id()
     if resp.error_code == 0:
         self._server_id = resp.id
         logger.info("PD Register Server Success, ServerID:%d" % self._server_id)
     else:
         logger.error(
             "PD Register Server Fail, ExitCode:%d" % ERROR_PD_NEW_SERVER.code
         )
         exit(ERROR_PD_NEW_SERVER.code)
         return
     resp = await api.register_server(
         self._server_id,
         self._config.start_time,
         self._config.ttl,
         self._config.address,
         self._config.services,
         self._config.desc if self._config.desc else "host_%s" % self.server_id(),
     )
     if resp.error_code == 0:
         self._lease_id = resp.lease_id
         logger.info("ServerID:%d, LeaseID:%d" % (self._server_id, self._lease_id))
         service_list = [
             "%s => %s" % (k, self._config.services[k])
             for k in self._config.services
         ]
         logger.info("Host Services:%s" % (", ".join(service_list)))
         asyncio.create_task(self._heart_beat_loop())
     else:
         logger.error(
             "%d, %s" % (ERROR_PD_NEW_SERVER.code, ERROR_PD_NEW_SERVER.message)
         )
         exit(ERROR_PD_REGISTER_SERVER.code)
     pass
コード例 #21
0
ファイル: self_rpc.py プロジェクト: egmkang/koala
async def patch_code():
    await asyncio.sleep(3.0)
    placement = Placement.instance()
    servers = placement.get_all_servers()
    for server in servers:
        proxy = rpc_proxy.get_rpc_proxy(hotfix.IHotFix,
                                        "1",
                                        server_node=server,
                                        check_postion=False)
        await proxy.patch_code("print(112233)")


PORT = 15555

placement = SelfHostedPlacement(PORT)
Placement.set_instance(placement)
logger.info(Placement.instance())

koala_host.init_server(globals())
koala_host.listen_rpc(PORT)
koala_host.create_task(service_1())

for item in range(16):
    i = item
    koala_host.create_task(bench(i))

koala_host.create_task(patch_code())
koala_host.create_task(run_timer(1))
koala_host.create_task(qps())
koala_host.run_server()
コード例 #22
0
ファイル: placement.py プロジェクト: egmkang/koala
 def set_instance(cls, impl: "Placement"):
     cls.__placement_impl = impl
     logger.info("init placement impl %s" % cls.__placement_impl)
コード例 #23
0
ファイル: self_rpc.py プロジェクト: egmkang/koala
 async def say_hello(self, hello: str) -> str:
     service_2 = self.get_proxy(IService2, "2")
     logger.info(
         "service 2 return %s" %
         await service_2.hello(self.uid, random.randrange(0, 10000)))
     return "my name is %s, and yours is %s" % (self.uid, hello)
コード例 #24
0
 async def on_session_aborted(self, msg: NotifyActorSessionAborted):
     _ = msg
     logger.info("Actor:%s/%s SessionID:%s aborted" %
                 (self.type_name, self.uid, self.session_id))
     self.set_session_id(0)
コード例 #25
0
 async def on_new_session(self, msg: NotifyNewActorSession, body: bytes):
     _ = body
     logger.info("Actor:%s/%s NewSessionID:%s" %
                 (self.type_name, self.uid, msg.session_id))
     self.set_session_id(msg.session_id)
     pass
コード例 #26
0
ファイル: self_rpc.py プロジェクト: egmkang/koala
async def service_1():
    await asyncio.sleep(3.0)
    proxy = rpc_proxy.get_rpc_proxy(IService1, "1")
    logger.info(await proxy.say_hello("2"))
    pass
コード例 #27
0
 def on_session_changed(self, old_session_id: int):
     logger.info(
         "Actor:%s/%s, OldSessionID:%s, NewSessionID:%s" %
         (self.type_name, self.uid, old_session_id, self.session_id))
コード例 #28
0
ファイル: self_rpc.py プロジェクト: egmkang/koala
 def f(timer: ActorTimer):
     logger.info("timer, tick:%s" % timer.tick_count)
     if timer.tick_count >= count:
         a: BenchImpl = cast(BenchImpl, weak_actor())
         a.unregister_timer(timer.timer_id)