title: How can you reset or cancel asyncio.sleep events?
body: <p>I am trying to set up a bot in discord that works on timers. One of them will work if one person types in the '!challenge' command, in which the bot will wait for 60 seconds to see if anyone types the '!accept' command in response. If it does not, it states 'Challenge was ignored. Resetting.' Or something along those lines.</p>
  
  <p>Another timer actually runs during the game itself, and is an hour long. However, the hour resets after a command has been put in. If the games is idle for an hour (One player DCs or quits) the bot resets the game itself.</p>
  
  <p>I had this working with threading:</p>
  
  <pre class="lang-py prettyprint-override"><code>        # Initiate a challenge to the room. Opponent is whoever uses the !accept command. This command should be
          # unavailable for use the moment someone !accepts, to ensure no one trolls during a fight.
          if message[:10] == "!challenge":
              msg, opponent, pOneInfo, new_game, bTimer, playerOne = message_10_challenge(channel, charFolder, message, unspoiledArena, character,                   self.game)
              if opponent is not "":
                  self.opponent = opponent
              if pOneInfo is not None:
                  self.pOneInfo = pOneInfo
                  self.pOneTotalHP = self.pOneInfo['thp']
                  self.pOneCurrentHP = self.pOneInfo['thp']
                  self.pOneLevel = self.pOneInfo['level']
              if new_game != 0:
                  self.game = new_game
              if bTimer is True:
                  timeout = 60
                  self.timer = Timer(timeout, self.challengeTimeOut)
                  self.timer.start()
              if playerOne is not "":
                  self.playerOne = playerOne
              super().MSG(channel, msg)
  </code></pre>
  
  <p>and:</p>
  
  <pre class="lang-py prettyprint-override"><code>        # Response to use to accept a challenge.
  
         if message == "!accept":
              msg, pTwoInfo, new_game, playerTwo, bTimer, bGameTimer, new_oppenent, token = message_accept(channel, charFolder, unspoiledArena,                                character, self.game, self.opponent, self.pOneInfo)
              if not charFile.is_file():
                  super().MSG(channel, "You don't even have a character made to fight.")
              else:
                  if new_game is not None:
                      self.game = new_game
                  if pTwoInfo is not None:
                      self.pTwoInfo = pTwoInfo
                      self.pTwoTotalHP = self.pTwoInfo['thp']
                      self.pTwoCurrentHP = self.pTwoInfo['thp']
                      self.pTwoLevel = self.pTwoInfo['level']
                  if bTimer:
                      self.timer.cancel()
                  if bGameTimer:
                      gametimeout = 3600
                      self.gameTimer = Timer(gametimeout, self.combatTimeOut)
                      self.gameTimer.start()
                  if new_oppenent is not None:
                      self.opponent = new_oppenent
                  if playerTwo is not None:
                      self.playerTwo = playerTwo
                  if token is not None:
                      self.token = token
                  for msg_item in msg:
                      super().MSG(channel, msg_item)
  </code></pre>
  
  <p>with functions:</p>
  
  <pre class="lang-py prettyprint-override"><code>    def challengeTimeOut(self):
          super().MSG(unspoiledArena, "Challenge was not accepted. Challenge reset.")
          self.game = 0
  
      def combatTimeOut(self):
          super().PRI('Unspoiled Desire', "!reset")
  </code></pre>
  
  <p>The above is an example of the same game, but on a different chat platform, with threading to handle the timers. But threading and discord.py aren't friends I guess. So I am trying to get the above code to work with discord.py, which seems to use asyncio. </p>
  
  <p>The thought was to use <code>asyncio.sleep()</code> in the</p>
  
  <pre class="lang-py prettyprint-override"><code>if bTimer is true:
       await asyncio.sleep(60)
       self.game = 0
       await ctx.send("Challenge was not accepted. Challenge reset.")
  </code></pre>
  
  <p>And this works...but it doesn't stop the timer, so even if someone <code>!accepts</code>, thus changing <code>bTimer</code> to <code>False</code>, which would cancel the timer:</p>
  
  <pre class="lang-py prettyprint-override"><code>if bTimer:
       self.timer.cancel()
  </code></pre>
  
  <p>it's still going to say "Challenge was not accepted. Challenge reset."</p>
  
  <p>The same problem will occure with <code>bGameTimer</code> if I try:</p>
  
  <pre class="lang-py prettyprint-override"><code>if bGameTimer:
       await asyncio.sleep(3600)
       await ctx.send("!reset")
  </code></pre>
  
  <p>the game will be hardwired to reset after 1 hours time, no matter if the game is done or not. Rather than resetting the 1 hour timer after every turn, and ONLY resetting if a full hour has passed in which no commands are made.</p>
  
  <p>Is there a way to easily cancel or reset sleep cycles?</p>