1

I have the following code:

from discord.ext import commands

bot = commands.Bot(command_prefix= prefix)
big_var = {}

@bot.command(name='func1')
@commands.max_concurrency(1, wait = True)
async def func1(ctx):
    func1code(big_var)

bot.run(TOKEN)

I want to run a function clear_data(big_var) if the last use of big_var was X minutes ago, in order to save memory.

I tried:

from discord.ext import commands

bot = commands.Bot(command_prefix= prefix)
big_var = {}

@bot.command(name='func1')
@commands.max_concurrency(1, wait = True)
async def func1(ctx):
    func1code(big_var)
    await asyncio.sleep(600)
    clear_data(big_var)

bot.run(TOKEN)

But this prevents the function func1() from finishing and the max_concurrencydecorator will only allow 1 instance of func1() to be running at a time.

How can I resolve this issue?

EDIT: Rewrote question to make it more clear

Ricardo B.
  • 27
  • 1
  • 5
  • This seems a bit broad, and the kind of subject on which there is already information available. Can you be more specific? – AMC May 04 '20 at 01:15
  • What you are asking for is a standard use case of a cache, i.e. delete the object if time-to-live has expired. Python has a built-in `lru_cache`, but not sure if it supports TTL. – narendra-choudhary May 04 '20 at 01:22
  • 1
    [Here](https://stackoverflow.com/questions/31771286/python-in-memory-cache-with-time-to-live) and [here](https://stackoverflow.com/questions/50866911/caching-in-memory-with-a-time-limit-in-python) are some ideas for implementing such a pattern in Python. – narendra-choudhary May 04 '20 at 01:23

1 Answers1

2

threading.Timer is a function that calls the second argument after the first argument number of seconds. You might do something like:

def del_big_var():
    global big_var
    del big_var

t = threading.Timer(X * 60, del_big_var)

def command_that_need_big_var():
    global t
    t.cancel()
    t = threading.Timer(X * 60, del_big_var)

It does not block either.

import threading
import time

def foo(*args, **kwargs):
    print("TIME!")

def main():
    t = threading.Timer(3, foo)
    t.start()
    while True:
        print("going")
        time.sleep(1)

main()

The above will produce

going
going
going
TIME!
going
going
going
Traceback (most recent call last):
  File "thread_timer.py", line 15, in <module>
    main()
  File "thread_timer.py", line 13, in main
    time.sleep(1)
KeyboardInterrupt
RedKnite
  • 1,525
  • 13
  • 26
  • Upon looking into [threading.Timer](https://docs.python.org/3/library/threading.html#timer-objects) I couldn't find if it would block my function from continuing, in which case the problem maintains. – Ricardo B. May 04 '20 at 01:58