def ping_send(remotename, interval = 100): ''' 向给自己发消息 params tuple remotename (groupname, servicename) int interval 每隔多久发一次消息 ''' try : global MONITOR_RBT_WRITE global MBC global reply_info while True: MBC._end_event.wait(interval) if MBC._end_event.isSet(): break try: data = { "0003":{"0005":0x00000001}, "0004":{}, } data = JsonUtil.write( data ) MONITOR_RBT_WRITE.send(remotename, data) if True == reply_info['is_reply']: reply_info['is_reply'] = False reply_info['ping_time'] = time.time() logging.info('send [ping] to myself through rabbitmq') except: logging.warning('from ping_send %s',traceback.format_exc()) except Exception,ex: logging.error( "Error: %s" % ex ) logging.error( traceback.format_exc() )
def _connect_rbt_server(self): ''' connnect to rabbitmq server params string server_url amqp的url return 1表示成功 ''' server_url = self.rbt_server_list[self.current_node_index] try: self.client = puka.Client(server_url) promise = self.client.connect() res = self.client.wait(promise) if res and res.has_key('server_properties'): logging.info('connect to rabbitmq-server [%s] success',server_url) else: logging.error('fail to connect or init rabbitmq-server ,amqp url is [%s] error is [%s]',server_url, traceback.format_exc()) return -1 if not self.declare_my_exchange(): #declare exchange return -4 if not self.declare_my_queue(self.my_q_name): #declare myself queue error return -2 if not self.declare_group_queue(self.my_grp_qname): #declare my group queue error return -3 if self.type == 'read': self.get_consume_promise( [self.my_q_name, self.my_grp_qname]) logging.info('success init to rabbitmq-server [%s] success',server_url) return 1 except: logging.error('fail to connect or init rabbitmq-server ,amqp url is [%s] error is [%s]',server_url, traceback.format_exc()) time.sleep(0.3) return -1
def init(self, myname, myaddr, mdaddr, type): ''' params tuple myname (groupname,servicename) groupname为组的名字 servicename为自己的名字 mydaddr 目前无用 string mdaddr rabbitmq-server的地址 需要是amqp的url格式 amqp://192.168.0.252:5673/ 或者 amqp://192.168.0.252:5673/;amqp://192.168.0.252:5674/ string type 'read' 或者 'write' return -1 表示 连接rabbit-server 失败 -2 表示 声明自己的queue失败 -3 表示 声明组的queue失败 ''' if type not in ['read','write']: logging.error('from init type error') return -4 self.type = type self.rbt_server_list = [ ] amqp_url_list = mdaddr.split(';') for i in amqp_url_list: if i: self.rbt_server_list.append(i) random.shuffle(self.rbt_server_list) #当前使用节点列表中的哪个index self.current_node_index = 0 #我的组名字 self.my_grp_qname = myname[0] #我的service名字 self.my_q_name = myname[1] self.mdaddr = mdaddr #当前使用节点列表中的哪个index return self.connect_rbt_server()
def invokeAutoMatchArgs(fun, inargs): funinfo=inspect.getargspec(fun) _name=funinfo[0] # 参数列表 if len(_name) == 0: # 这是一个不需要入参的函数 return fun() _defval=list(funinfo[-1] or ()) # 默认值列表 _args=[] # 填充默认值列表,没有默认值的以 NO_DEFAULT_DATA 值填充 _defval = [__NO_DEFAULT_DATA__ for i in range(len(_name)-len(_defval))]+_defval # 组织参数列表 for idx, argname in enumerate(_name): # 参数传入 if 'self' == argname : continue if inargs.has_key(argname): _args.append(inargs[argname]) elif _defval[idx] != __NO_DEFAULT_DATA__: # 参数没有传入,检查有没有默认值 _args.append(_defval[idx]) else: # 参数错误 logging.error( "缺少参数%s"%argname ) return False return fun(*_args)
def _send(self, remotename, data, timeout=None): ''' params tuple remotename 远程服务名 (group, name) (group或name 超过8个字符会报错) data 数据 "hello world" timeout 超时时间 单位 秒 为0则表示阻塞发送 return True or False timeout秒钟之内 发送成功或者失败 ''' try: if timeout == 0: timeout = None data = self.join_send_info(remotename,data) promise = self.client.basic_publish(exchange = 'poker', routing_key = remotename[1], body = data, ) #return True ress = self.client.wait(promise, None) if ress == {} : return True else: return False except: logging.error( 'from send %s',traceback.format_exc() ) return False
def generate_game_list( self, table_num_create, target_gameaddr = None, sort = 'NO', type = 'NO' ): ''' 功能:根据要创建的牌桌个数,生成游戏服务列表 入参:sort : 牌桌大类 CASH/MATCH type : 牌桌子类 RAKEPOINT/GOLD TOURNEY/SITANDGO 出参:glist ''' logging.info('table_num = %s, target_gameaddr = %s, sort = %s, type = %s' %(table_num_create, target_gameaddr, sort, type)) glist = [] # 1.如果有指定的Game服务,则直接把桌子全部创到这个服务上去 if target_gameaddr in self.game_list: for i in range( table_num_create ): game_name = target_gameaddr remote_addr = (Config.GAME_GROUP_NAME, game_name) glist.append( remote_addr ) self.inc_table_count( game_name, table_num_create ) return glist #记录一下错误信息 if target_gameaddr != None: logging.error('generate_game_list: not exist gameaddr [%s] '%target_gameaddr) gameaddr_list = self.get_target_gameaddr(table_num_create, sort, type) if len( gameaddr_list ) <= 0: logging.error( 'there is not single game address!' ) return self # 2.只有一个地址的情况下,很好处理 if len( gameaddr_list ) == 1: for i in range( table_num_create ): game_name = gameaddr_list.keys()[0] remote_addr = (Config.GAME_GROUP_NAME, game_name) glist.append( remote_addr ) self.inc_table_count( game_name, table_num_create ) return glist # 3.其他情况:取最多、最少牌桌的游戏 # 算法的基本思路是: # 取最小牌桌数量的Game服务 for i in range( table_num_create ): max_name, min_name = get_max_and_min_table_game( gameaddr_list ) # 取到一个游戏地址 game_name = min_name remote_addr = (Config.GAME_GROUP_NAME, game_name) # 登记到缓存 glist.append( remote_addr ) self.inc_table_count( game_name ) gameaddr_list[ game_name ] += 1 return glist
def remove_gameaddr( self, server_name ): '''''' if self.game_list.has_key( server_name ): if self.game_list[server_name] != 0: logging.error('can not remove gameaddr[%s], table_num != 0'%server_name) return False del self.game_list[server_name] else: logging.error('from remove_gameaddr : no exist server_name[%s]'%server_name)
def ping_reply(*arglist,**arglists): ''' 接收到ping消息以后的回复 需要接收消息的服务程序指定命令字对应 ''' global MBC try: MBC.inform() except: logging.error( traceback.format_exc() )
def check_match_canrun(match_list): '''检查 can_run标志''' for match_id in match_list: pause_match = get_pause_match(match_id) if not pause_match: logging.error('from check_match_canrun: not exist match_id[%s]' % match_id) continue pause_match.check_all_flag()
def endSignalHandler(signum, frame): matchs = Match.get_all_match() for match_id, match in matchs.items(): sq_regroup_table = match.sq_regroup_table if not Label.unset(sq_regroup_table): logging.error('regrouping, try later [ match : %s ]' % match_id) #return False # ²âÊÔµÄʱºò×¢Ïúµô END_EVENT.set() return True
def stop(): ''' 向监控中心解除注销''' try: global MBC res = MBC.unregister() if res['code'] != 301: logging.warning('monitor unregister %s',res) except Exception,ex: logging.error( "Error: %s" % ex ) logging.error( traceback.format_exc() )
def run(): '''主运行程序''' while not Object.END_EVENT.isSet(): try: _DATA_EVENT_.wait(INTERVAL) _data = OM.get_all_match() _store(_data) _DATA_EVENT_.clear() except: logging.error('error in StoreMatch.run: %s', traceback.format_exc())
def del_pause_match(match_id): '''del''' global _PAUSE_MATCH_DICT_ if _PAUSE_MATCH_DICT_.has_key(match_id): del _PAUSE_MATCH_DICT_[match_id] logging.info('del pause_match[%s] from _PAUSE_MATCH_DICT_' % match_id) return True else: logging.error( 'from del_pause_match: no pause_match[%s] in _PAUSE_MATCH_DICT_' % match_id) return False
def record(self, commond_id, msg): ''' ¼Ç¼Æ÷ ''' try: msg = Version.deformator(msg) commond_id = Version.R_CMD.get(commond_id, commond_id) self.content.append([commond_id, msg]) if commond_id == 'PRIZE_MSG': msg = json.write([self.table_id, self.hand_id, self.content]) send(msg) except: logging.error(traceback.format_exc())
def _loop_inform(self, data, interval): """自动循环通知 """ while True: self._end_event.wait(interval) if self._end_event.isSet(): break try: self.inform(data) except: logging.error('monitoring inform failed: [%s] %s', self.app_id, traceback.format_exc())
def ping_reply(*arglist,**arglists): ''' 接收到ping消息以后的回复 需要接收消息的服务程序指定命令字对应 ''' try: global MBC global reply_info reply_info['is_reply'] = True MBC.inform() except Exception,ex: logging.error( "Error: %s" % ex ) logging.error( traceback.format_exc() )
def unregister(self): """unregister """ self._end_event.set() try: ret = self._call2('unregister', None) if ret['code'] < 0: raise Exception(ret) except: logging.error('monitoring unregister failed: [%s] %s', self.app_id, traceback.format_exc()) return return ret
def need_hbh(match): ''' hands-by-hands 1. 当前人数 == final-talbe人数 + 1 2. 钱圈人数 +1 == 当前人数 ''' try: # 如果本场比赛已经有牌桌进入了hands-by-hands状态,那么后续的所有牌桌都 # 应该进入该状态,然后统一解除状态 pause_match = get_pause_match(match.match_id) if pause_match and pause_match.hbh_flag: return True alive_num = match.get_alive_player() # 第一种情况:final-table if alive_num == match.conf.seat_num + 1: logging.debug("match[%s] final-table hands-by-hands!" % match.match_id) return True # 第二种情况:钱圈人数 inthemoney_num = match.conf.inthemoney_ratio / 100.0 * len( match.user_list) if inthemoney_num == 0 or inthemoney_num <= match.conf.seat_num: return False # total_table_num = len(match.table_list) - match.destroying_table_num # 找到能容纳钱圈人数的最小桌子数 # for i in range(1, alive_num): # if i*match.conf.seat_num >= inthemoney_num: # break # usable_seat_num = i*match.conf.seat_num # if inthemoney_num < alive_num and alive_num <= usable_seat_num and total_table_num > 1: # logging.debug("match[%s] QianQuan hands-by-hands! inthemoney_num=%s, alive_num=%s, usable_seat_num=%s" # %( match.match_id, inthemoney_num, alive_num, usable_seat_num)) # return True if math.floor(inthemoney_num) + 1 == alive_num: logging.debug( "match[%s] QianQuan hands-by-hands! inthemoney_num=%s, alive_num=%s, inthemoney_ratio=%s" % (match.match_id, inthemoney_num, alive_num, match.conf.inthemoney_ratio)) return True return False except: logging.error("some error in need_hbh: %s" % (traceback.format_exc())) return False
def alert(shortmsg, longmsg, charset='gbk'): ''' 告警接口 ''' global SWITCH global MBC try: shortmsg = str( MBC.app_id ) + ':' + shortmsg longmsg = str( MBC.app_id ) + ':' + longmsg if SWITCH == 'OFF': logging.error('SWITCH=OFF shortmsg[%s],longmsg[%s]',shortmsg,longmsg) return MBC.alert(shortmsg, longmsg, charset) except: logging.error( traceback.format_exc() )
def add_player(self, seat_num, player_id, user_id, user_name, ante, user_rake, putin_chips, get_chips, chips): i = int(seat_num) if i < 0 or i > 8: logging.error( "add player_group error! wrong seat_num %s"%i ) return False self.player_list[i].player_id = player_id self.player_list[i].user_id = user_id self.player_list[i].user_name = user_name self.player_list[i].ante = ante self.player_list[i].user_rake = user_rake self.player_list[i].putin_chips = putin_chips self.player_list[i].get_chips = get_chips self.player_list[i].chips = chips
def check_real_addon(self): '''检查该场比赛是否可以正式addon了''' match = MatchObject.get(self.match_id) if match == None: logging.error('not existmatch_id[%s]' % (match_id)) return total_table_num = len(match.table_list) - match.destroying_table_num logging.info('check_real_addon match[%s] total_table_num = %s' % (self.match_id, total_table_num)) if self.addon_table_num >= total_table_num: return True else: return False
def inc_table_count(self, game_name, count = 1): ''' 增加game服务下挂载的牌桌数量 ''' try: self.rlock.acquire() #申请锁 if game_name not in self.game_list: logging.error('from inc_table_count : game_name [%s] not in game_list'%game_name) return False self.game_list[game_name] += count logging.info('%s table_num + %s'%(game_name, count)) finally: self.rlock.release() #释放锁
def load_config( self ): ''' 加载服务分配配置方案 ''' try: self.config_cash_server = Config.GAMEADDR_CASH.split( ',' ) #加载现金桌配置 self.config_match_server = Config.GAMEADDR_MATCH.split( ',' ) #加载比赛配置 self.config_gold_server = Config.GAMEADDR_GOLD.split( ',' ) #加载金币场配置 self.config_rakepoint_server = Config.GAMEADDR_RAKEPOINT.split( ',' ) #加载积分场配置 self.config_tourney = Config.GAMEADDR_TOURNEY.split( ',' ) #加载锦标赛配置 self.config_sitandgo = Config.GAMEADDR_SITANDGO.split( ',' ) #加载坐满即玩配置 except: logging.error('Game router load config failed!') return False
def start(q_name, my_app_name, mq_addr): ''' params tuple q_name string my_app_name 同一台机器 不可有两个相同进程的my_app_name相同 string mq_addr rabbitmq的amqp格式的字符串 ''' try : init(q_name, my_app_name) global MONITOR_RBT_WRITE MONITOR_RBT_WRITE = dispatcher.Dispatcher() MONITOR_RBT_WRITE.init( q_name, '', mq_addr, 'write') except Exception,ex: logging.error( "Error: %s" % ex ) logging.error( traceback.format_exc() )
def update_pause_starttime(self): ''' 更新各牌桌的暂停起始时间,以便统一盲注 ''' tid_list = self.table_dict.keys() #取所有的牌桌id for id in tid_list: table = TableObject.get(id) if not table: logging.error( 'from update_pause_starttime: not exist table[%s]' % table_id) continue table.pause_time = self.addon_start_time #统一暂停开始时间
def get_gain_conf(match_id, user_rank): '''检查用户是否有获取奖励''' match = omatch.get(match_id) if not match: logging.error('model Match.Match.check_add_blind can"t found match:%s', match_id) return None mc = match.conf if user_rank > mc.gain_conf[-1][0][1]: #比最大的钱圈名次还大 return None for i in mc.gain_conf: if user_rank >= i[0][0] and user_rank <= i[0][1] : return i[1] return None
def get_user_ladder_point(user_id): ''' 获取玩家天梯积分 ''' sql = '''select f_rank ladder_point from t_user_exp_rank where f_uid = %s''' args = (user_id, ) ret = Db.Mysql.connect('esun_texas').query(sql, args) if not ret: return 0 else: try: return int( ret[0]['ladder_point'] ) except: logging.error('%s'%traceback.format_exc()) return 0
def get_user_vip_level(user_id): ''' 获取玩家vip等级 ''' sql = '''select f_level vip_level from t_user_vip where f_uid = %s ''' args = (user_id, ) ret = Db.Mysql.connect('esun_texas').query(sql, args) if not ret: return 0 else: try: return int( ret[0]['vip_level'] ) except: logging.error('%s'%traceback.format_exc()) return 0
def _send(self, remotename, data, timeout=None): ''' params tuple remotename 远程服务名 (group, name) (group或name 超过8个字符会报错) data 数据 "hello world" timeout 超时时间 单位 秒 为0则表示阻塞发送 return True or False timeout秒钟之内 发送成功或者失败 ''' try: if timeout == 0: timeout = None data = self.join_send_info(remotename,data) self.cabbit_server.send(remotename[1], data) return True except: logging.error( 'from send %s',traceback.format_exc() ) return False
def is_time_to_pause(): ''' 判断当前时间是否为休息时间段 默认休息时间段:55分--00(整点) ''' try: current_minute = time.strftime("%M", time.localtime()) #取当前时间的分钟数 如15:30:42 分钟数为30 current_minute = int(current_minute) if current_minute >= 55: #if (current_minute % 10) >= 8: return True else: return False except: logging.error('Some error: is_time_to_pause------>%s' % (traceback.format_exc()))