Python 扭曲,reactor.callLater() 不推迟
Python twisted, reactor.callLater() not defering
以下代码片段来自 python 扑克牌服务器。该程序有效,除非在使用 reactor.callLater 时试图延迟锦标赛的开始。
变量 "wait" 从设置为“60”的 xml 文件中获取其整数。然而,延迟从未实施,比赛总是立即开始。我对 python 不是很熟悉,或者只是试图破解它为我工作而扭曲。然而,从我的角度来看,有一件事似乎它不应该工作,因为我看不到变量 "old_state" 如何或在何处获取其值以便代码正确确定服务器的状态。但也许我错了。
希望熟悉python和twisted的人能看出问题所在,并愿意就这个问题开导我。
elif old_state == TOURNAMENT_STATE_REGISTERING and new_state == TOURNAMENT_STATE_RUNNING:
self.databaseEvent(event = PacketPokerMonitorEvent.TOURNEY_START, param1 = tourney.serial)
reactor.callLater(0.01, self.tourneyBroadcastStart, tourney.serial)
# Only obey extra_wait_tourney_start if we had been registering and are now running,
# since we only want this behavior before the first deal.
wait = int(self.delays.get('extra_wait_tourney_start', 0))
if wait > 0:
reactor.callLater(wait, self.tourneyDeal, tourney)
else:
self.tourneyDeal(tourney)
作为参考,我放置了与问题相关的大部分代码。
def spawnTourneyInCore(self, tourney_map, tourney_serial, schedule_serial, currency_serial, prize_currency):
tourney_map['start_time'] = int(tourney_map['start_time'])
if tourney_map['sit_n_go'] == 'y':
tourney_map['register_time'] = int(seconds()) - 1
else:
tourney_map['register_time'] = int(tourney_map.get('register_time', 0))
tourney = PokerTournament(dirs = self.dirs, **tourney_map)
tourney.serial = tourney_serial
tourney.verbose = self.verbose
tourney.schedule_serial = schedule_serial
tourney.currency_serial = currency_serial
tourney.prize_currency = prize_currency
tourney.bailor_serial = tourney_map['bailor_serial']
tourney.player_timeout = int(tourney_map['player_timeout'])
tourney.via_satellite = int(tourney_map['via_satellite'])
tourney.satellite_of = int(tourney_map['satellite_of'])
tourney.satellite_of, reason = self.tourneySatelliteLookup(tourney)
tourney.satellite_player_count = int(tourney_map['satellite_player_count'])
tourney.satellite_registrations = []
tourney.callback_new_state = self.tourneyNewState
tourney.callback_create_game = self.tourneyCreateTable
tourney.callback_game_filled = self.tourneyGameFilled
tourney.callback_destroy_game = self.tourneyDestroyGame
tourney.callback_move_player = self.tourneyMovePlayer
tourney.callback_remove_player = self.tourneyRemovePlayer
tourney.callback_cancel = self.tourneyCancel
if not self.schedule2tourneys.has_key(schedule_serial):
self.schedule2tourneys[schedule_serial] = []
self.schedule2tourneys[schedule_serial].append(tourney)
self.tourneys[tourney.serial] = tourney
return tourney
def deleteTourney(self, tourney):
if self.verbose > 2:
self.message("deleteTourney: %d" % tourney.serial)
self.schedule2tourneys[tourney.schedule_serial].remove(tourney)
if len(self.schedule2tourneys[tourney.schedule_serial]) <= 0:
del self.schedule2tourneys[tourney.schedule_serial]
del self.tourneys[tourney.serial]
def tourneyResumeAndDeal(self, tourney):
self.tourneyBreakResume(tourney)
self.tourneyDeal(tourney)
def tourneyNewState(self, tourney, old_state, new_state):
cursor = self.db.cursor()
updates = [ "state = '" + new_state + "'" ]
if old_state != TOURNAMENT_STATE_BREAK and new_state == TOURNAMENT_STATE_RUNNING:
updates.append("start_time = %d" % tourney.start_time)
sql = "update tourneys set " + ", ".join(updates) + " where serial = " + str(tourney.serial)
if self.verbose > 2:
self.message("tourneyNewState: " + sql)
cursor.execute(sql)
if cursor.rowcount != 1:
self.error("modified %d rows (expected 1): %s " % ( cursor.rowcount, sql ))
cursor.close()
if new_state == TOURNAMENT_STATE_BREAK:
# When we are entering BREAK state for the first time, which
# should only occur here in the state change operation, we
# send the PacketPokerTableTourneyBreakBegin. Note that this
# code is here and not in tourneyBreakCheck() because that
# function is called over and over again, until the break
# finishes. Note that tourneyBreakCheck() also sends a
# PacketPokerGameMessage() with the time remaining, too.
secsLeft = tourney.remainingBreakSeconds()
if secsLeft == None:
# eek, should I really be digging down into tourney's
# member variables in this next assignment?
secsLeft = tourney.breaks_duration
resumeTime = seconds() + secsLeft
for gameId in map(lambda game: game.id, tourney.games):
table = self.getTable(gameId)
table.broadcast(PacketPokerTableTourneyBreakBegin(game_id = gameId, resume_time = resumeTime))
self.tourneyBreakCheck(tourney)
elif old_state == TOURNAMENT_STATE_BREAK and new_state == TOURNAMENT_STATE_RUNNING:
wait = int(self.delays.get('extra_wait_tourney_break', 0))
if wait > 0:
reactor.callLater(wait, self.tourneyResumeAndDeal, tourney)
else:
self.tourneyResumeAndDeal(tourney)
elif old_state == TOURNAMENT_STATE_REGISTERING and new_state == TOURNAMENT_STATE_RUNNING:
self.databaseEvent(event = PacketPokerMonitorEvent.TOURNEY_START, param1 = tourney.serial)
reactor.callLater(0.01, self.tourneyBroadcastStart, tourney.serial)
# Only obey extra_wait_tourney_start if we had been registering and are now running,
# since we only want this behavior before the first deal.
wait = int(self.delays.get('extra_wait_tourney_start', 0))
if wait > 0:
reactor.callLater(wait, self.tourneyDeal, tourney)
else:
self.tourneyDeal(tourney)
elif new_state == TOURNAMENT_STATE_RUNNING:
self.tourneyDeal(tourney)
elif new_state == TOURNAMENT_STATE_BREAK_WAIT:
self.tourneyBreakWait(tourney)
我发现这段代码有几个导入的文件,它们位于我没有检查的另一个目录中。我还错误地假设了这个代码块的目的。我希望该功能是任意的,并将每次锦标赛延迟 n 秒,但实际上它仅在玩家忘记游戏并且没有出现时才实施延迟。一旦我检查了正确的文件,这些事实就很清楚了。学过的知识。看看所有的进口!
以下代码片段来自 python 扑克牌服务器。该程序有效,除非在使用 reactor.callLater 时试图延迟锦标赛的开始。
变量 "wait" 从设置为“60”的 xml 文件中获取其整数。然而,延迟从未实施,比赛总是立即开始。我对 python 不是很熟悉,或者只是试图破解它为我工作而扭曲。然而,从我的角度来看,有一件事似乎它不应该工作,因为我看不到变量 "old_state" 如何或在何处获取其值以便代码正确确定服务器的状态。但也许我错了。
希望熟悉python和twisted的人能看出问题所在,并愿意就这个问题开导我。
elif old_state == TOURNAMENT_STATE_REGISTERING and new_state == TOURNAMENT_STATE_RUNNING:
self.databaseEvent(event = PacketPokerMonitorEvent.TOURNEY_START, param1 = tourney.serial)
reactor.callLater(0.01, self.tourneyBroadcastStart, tourney.serial)
# Only obey extra_wait_tourney_start if we had been registering and are now running,
# since we only want this behavior before the first deal.
wait = int(self.delays.get('extra_wait_tourney_start', 0))
if wait > 0:
reactor.callLater(wait, self.tourneyDeal, tourney)
else:
self.tourneyDeal(tourney)
作为参考,我放置了与问题相关的大部分代码。
def spawnTourneyInCore(self, tourney_map, tourney_serial, schedule_serial, currency_serial, prize_currency):
tourney_map['start_time'] = int(tourney_map['start_time'])
if tourney_map['sit_n_go'] == 'y':
tourney_map['register_time'] = int(seconds()) - 1
else:
tourney_map['register_time'] = int(tourney_map.get('register_time', 0))
tourney = PokerTournament(dirs = self.dirs, **tourney_map)
tourney.serial = tourney_serial
tourney.verbose = self.verbose
tourney.schedule_serial = schedule_serial
tourney.currency_serial = currency_serial
tourney.prize_currency = prize_currency
tourney.bailor_serial = tourney_map['bailor_serial']
tourney.player_timeout = int(tourney_map['player_timeout'])
tourney.via_satellite = int(tourney_map['via_satellite'])
tourney.satellite_of = int(tourney_map['satellite_of'])
tourney.satellite_of, reason = self.tourneySatelliteLookup(tourney)
tourney.satellite_player_count = int(tourney_map['satellite_player_count'])
tourney.satellite_registrations = []
tourney.callback_new_state = self.tourneyNewState
tourney.callback_create_game = self.tourneyCreateTable
tourney.callback_game_filled = self.tourneyGameFilled
tourney.callback_destroy_game = self.tourneyDestroyGame
tourney.callback_move_player = self.tourneyMovePlayer
tourney.callback_remove_player = self.tourneyRemovePlayer
tourney.callback_cancel = self.tourneyCancel
if not self.schedule2tourneys.has_key(schedule_serial):
self.schedule2tourneys[schedule_serial] = []
self.schedule2tourneys[schedule_serial].append(tourney)
self.tourneys[tourney.serial] = tourney
return tourney
def deleteTourney(self, tourney):
if self.verbose > 2:
self.message("deleteTourney: %d" % tourney.serial)
self.schedule2tourneys[tourney.schedule_serial].remove(tourney)
if len(self.schedule2tourneys[tourney.schedule_serial]) <= 0:
del self.schedule2tourneys[tourney.schedule_serial]
del self.tourneys[tourney.serial]
def tourneyResumeAndDeal(self, tourney):
self.tourneyBreakResume(tourney)
self.tourneyDeal(tourney)
def tourneyNewState(self, tourney, old_state, new_state):
cursor = self.db.cursor()
updates = [ "state = '" + new_state + "'" ]
if old_state != TOURNAMENT_STATE_BREAK and new_state == TOURNAMENT_STATE_RUNNING:
updates.append("start_time = %d" % tourney.start_time)
sql = "update tourneys set " + ", ".join(updates) + " where serial = " + str(tourney.serial)
if self.verbose > 2:
self.message("tourneyNewState: " + sql)
cursor.execute(sql)
if cursor.rowcount != 1:
self.error("modified %d rows (expected 1): %s " % ( cursor.rowcount, sql ))
cursor.close()
if new_state == TOURNAMENT_STATE_BREAK:
# When we are entering BREAK state for the first time, which
# should only occur here in the state change operation, we
# send the PacketPokerTableTourneyBreakBegin. Note that this
# code is here and not in tourneyBreakCheck() because that
# function is called over and over again, until the break
# finishes. Note that tourneyBreakCheck() also sends a
# PacketPokerGameMessage() with the time remaining, too.
secsLeft = tourney.remainingBreakSeconds()
if secsLeft == None:
# eek, should I really be digging down into tourney's
# member variables in this next assignment?
secsLeft = tourney.breaks_duration
resumeTime = seconds() + secsLeft
for gameId in map(lambda game: game.id, tourney.games):
table = self.getTable(gameId)
table.broadcast(PacketPokerTableTourneyBreakBegin(game_id = gameId, resume_time = resumeTime))
self.tourneyBreakCheck(tourney)
elif old_state == TOURNAMENT_STATE_BREAK and new_state == TOURNAMENT_STATE_RUNNING:
wait = int(self.delays.get('extra_wait_tourney_break', 0))
if wait > 0:
reactor.callLater(wait, self.tourneyResumeAndDeal, tourney)
else:
self.tourneyResumeAndDeal(tourney)
elif old_state == TOURNAMENT_STATE_REGISTERING and new_state == TOURNAMENT_STATE_RUNNING:
self.databaseEvent(event = PacketPokerMonitorEvent.TOURNEY_START, param1 = tourney.serial)
reactor.callLater(0.01, self.tourneyBroadcastStart, tourney.serial)
# Only obey extra_wait_tourney_start if we had been registering and are now running,
# since we only want this behavior before the first deal.
wait = int(self.delays.get('extra_wait_tourney_start', 0))
if wait > 0:
reactor.callLater(wait, self.tourneyDeal, tourney)
else:
self.tourneyDeal(tourney)
elif new_state == TOURNAMENT_STATE_RUNNING:
self.tourneyDeal(tourney)
elif new_state == TOURNAMENT_STATE_BREAK_WAIT:
self.tourneyBreakWait(tourney)
我发现这段代码有几个导入的文件,它们位于我没有检查的另一个目录中。我还错误地假设了这个代码块的目的。我希望该功能是任意的,并将每次锦标赛延迟 n 秒,但实际上它仅在玩家忘记游戏并且没有出现时才实施延迟。一旦我检查了正确的文件,这些事实就很清楚了。学过的知识。看看所有的进口!