This seems to work fine (on python 3.3) -- just have lru_cache store the Futures instead of the internal results:
from tornado import gen
from tornado.ioloop import IOLoop
import functools
import time
@functools.lru_cache()
@gen.coroutine
def do_something_slow(arg1, arg2):
print("doing something slow with %s and %s" % (arg1, arg2))
yield gen.Task(IOLoop.current().add_timeout, time.time() + 1)
print("finished")
return arg1 + arg2
@gen.coroutine
def main():
print("starting main")
result = yield do_something_slow(2, 2)
print("got result %s" % result)
result = yield do_something_slow(3, 4)
print("got result %s" % result)
result = yield do_something_slow(2, 2)
print("got result %s" % result)
IOLoop.current().run_sync(main)