checkGames.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. require_once realpath(dirname(__FILE__)) . '/../common.php';
  3. $index = (int) $argv[1];
  4. if (!singleProcess(getCurrentCommand(), ROOT_PATH . "/bin/run/checkGames_{$index}.pid")) {
  5. exit("Sorry, this script file has already been running ...\n");
  6. }
  7. // $index = 1;
  8. $objOffer = new Offer();
  9. $listKey = 'globals:baccarat:game_list';
  10. $revealPreKey = 'globals:baccarat:game_reveal:';
  11. $objRedis = dwRedis::init(Eos::REDIS_SERV);
  12. $objGame = new Game();
  13. if ($index === 0) {
  14. // 获取正在进行中的游戏
  15. for ($i = 0; $i < 1000; $i++) {
  16. // 获取当前有几个房间,是否可以要开奖
  17. $keyWord = [
  18. '_sortKey' => 'update_time_int ASC',
  19. '_field' => 'id, ttl, create_time, update_time_int'
  20. ];
  21. $games = $objGame->objTable->getAll(['game_state' => Game::STATUS_PLAYING], $keyWord);
  22. $ids = [];
  23. foreach ($games as $game) {
  24. $timeout = strtotime($game['create_time']) + $game['ttl'];
  25. $timeout = $timeout - time();
  26. if ($timeout <= 0) {
  27. $ids[] = $game['id'];
  28. // 设置开始时间
  29. $objRedis->setex($revealPreKey . $game['id'], 120, time());
  30. }
  31. }
  32. if ($ids) {
  33. $data = $ids;
  34. // 批量更新数据库
  35. $newData = ['game_state' => Game::STATUS_OPENING];
  36. $where = ['id' => $ids];
  37. $objGame->objTable->updateObject($newData, $where);
  38. Eos::log("lPush:" . join(',', $ids));
  39. // 批量插入redis
  40. array_unshift($data, $listKey);
  41. call_user_func_array([$objRedis, 'lPush'], $data);
  42. } else {
  43. Tool::sleep(1);
  44. }
  45. // 检查正在开奖中的游戏,是否正常
  46. $game_ids = $games = $objGame->objTable->getCol(['game_state' => Game::STATUS_OPENING], ['_field' => 'id']);
  47. $error_ids = [];
  48. foreach ($game_ids as $game_id) {
  49. $time = $objRedis->get($revealPreKey . $game_id);
  50. $span = time() - $time;
  51. // 处理事件超过了30秒,则认为是异常的游戏
  52. if ($span > 30) {
  53. $msg = "百家乐游戏超时:{$game_id}, span:{$span},设置game_state=0";
  54. Eos::log($msg);
  55. $error_ids[] = $game_id;
  56. }
  57. }
  58. if ($error_ids) {
  59. $newData = ['game_state' => 0];
  60. $where = ['game_state' => 1, 'id' => $error_ids];
  61. $objGame->objTable->updateObject($newData, $where);
  62. }
  63. }
  64. } else {
  65. $objSyncOffer = new Sync_Offer();
  66. $objEos = new Eos();
  67. for ($i = 0; $i < 1000; $i++) {
  68. // 获取要开奖的游戏
  69. $game_id = $objRedis->rPop($listKey);
  70. if (!$game_id) {
  71. Tool::sleep(1);
  72. continue;
  73. }
  74. Eos::log("rPop: {$game_id}");
  75. // 设置开始处理时间
  76. $objRedis->setex($revealPreKey . $game_id, 120, time());
  77. $game = $objGame->objTable->getRow(['id' => $game_id]);
  78. if ($game['game_state'] != Game::STATUS_OPENING) {
  79. Eos::log("skig, game_state: {$game['game_state']}");
  80. continue;
  81. }
  82. $timeout = strtotime($game['create_time']) + $game['ttl'];
  83. $timeout = $timeout - time();
  84. try {
  85. if ($timeout <= 0) {
  86. // 开奖并充值
  87. Eos::log("revealCreate gameid: {$game['id']}");
  88. $newGameId = $objEos->revealCreate($game, $objGame);
  89. $json = Eos::$last_json;
  90. if ($newGameId) {
  91. // 同步订单状态
  92. $objSyncOffer->pubSubscribe(false);
  93. // 开奖后,同步游戏数据
  94. $objSyncGame = new Sync_Game();
  95. $objSyncGame->pubSubscribe(false);
  96. } else {
  97. // 交易太长的告警跳过
  98. if (strpos($json, 'Transaction took too long') === false || $timeout <= -10) {
  99. $msg = "游戏id:{$game_id} 开奖异常,timeout:{$timeout}, 重新放入队列. json:{$json}";
  100. errorGame($game_id, $msg);
  101. } else {
  102. resetGame($game_id);
  103. }
  104. sleep(1);
  105. }
  106. CallLog::logSelfCall(CODE_SUCCESS, "checkGames_{$index}, times:{$i}, timeout:{$timeout}");
  107. global $startTime;
  108. $startTime = microtime(true);
  109. } else {
  110. $msg = "游戏id:{$game_id} 还没到开奖时间,重新放入队列.";
  111. errorGame($game_id, $msg);
  112. }
  113. } catch (Exception $ex) {
  114. $msg = "游戏id:{$game_id} 未知异常,重新放入队列. 异常:" . $ex->getMessage();
  115. errorGame($game_id, $msg);
  116. }
  117. }
  118. }
  119. function resetGame($game_id) {
  120. global $objGame;
  121. // 异常情况
  122. $newData = ['game_state' => Game::STATUS_PLAYING];
  123. $where = ['id' => $game_id, 'game_state' => Game::STATUS_OPENING];
  124. $objGame->objTable->updateObject($newData, $where);
  125. }
  126. function errorGame($game_id, $msg) {
  127. resetGame($game_id);
  128. // $msg = "游戏id:{$game_id} 还没到开奖时间,重新放入队列.";
  129. alermErrorMsg($msg);
  130. Eos::log($msg);
  131. }