Open In App

Periodically Execute a Function with asyncio in Tornado

Last Updated : 27 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

The primary benefit is improved performance. Asynchronous programming allows your application to efficiently handle tasks that may block the main thread, such as network operations or I/O-bound tasks. This can lead to better responsiveness and scalability. Also by controlling the frequency of periodic tasks in Tornado, you can control the frequency of periodic tasks by specifying the delay in the loop.call_later() function. The delay determines how often the coroutine will be executed. You can set the delay in seconds, and it can be a fraction of a second as well.

Concepts in Tornado & asyncio

The Tornado framework in Python supports asynchronous processing, allowing you to run tasks periodically. In this article, we will explore how we use Asyncio periodically in Tornado, and I will provide clear examples with appropriate output screenshots.

  • Tornado and Asyncio: Tornado is a Python framework known for its non-blocking network I/O. It uses the Python Asyncio library to handle asynchronous tasks. Asyncio is a standard Python library for writing asynchronous, single-threaded code.
  • Periodic execution of Asyncio: The Asyncio library includes the loop.call_later() function that allows you to schedule the process to run periodically after a specified delay
  • Coroutines in Tornado: Asynchronous functions in Tornado are defined as coroutines using the async keyword. These coroutines can be executed simultaneously, making them suitable for tasks that require the main thread to be blocked and executed periodically.

Steps for periodically executing a function with Asyncio in Tornado

  • Import Required Libraries: Begin by importing the necessary libraries, including tornado.ioloop, tornado.web, and asyncio.
  • Define Your Function: Create the function you want to execute periodically. This function should be defined as an async coroutine.
  • Create the Main Coroutine: Define a coroutine (often named main) that will orchestrate the periodic execution of your function.
  • Set Up the Event Loop: Get the current Tornado event loop using tornado.ioloop.IOLoop.current().
  • Incorporate a Loop: Within the main coroutine, set up a loop, typically a while True loop.
  • Invoke Your Function: Inside the loop, use awaits to invoke your target function asynchronously.
  • Introduce a Delay: After invoking your function, introduce a delay using await asyncio.sleep(seconds) to control the frequency of execution.
  • Application Setup: Check if the script is being run as the main module using if __name__ == “__main__”.
  • Start the Periodic Task: If it’s the main script, create a Tornado web application and listen on a specific port. Then, use asyncio.ensure_future(main()) to start the periodic execution of your function.
  • Start Tornado IOLoop: Finally, initiate the Tornado IOLoop with tornado.ioloop.IOLoop.current().start() . This keeps the application running and allows for the periodic execution of your function.

Periodically Fetching Data in Tornado

In this example, we’ll create a Tornado application that periodically fetches data from an external source. We will use asyncio to schedule the task at regular intervals.

Python3




import tornado.ioloop
import tornado.web
import asyncio
import random
 
async def fetch_data():
    # Simulate fetching data (you will replace this block with actual data fetching logic)
    data = random.randint(1, 100)
    print(f"Fetched data: {data}")
 
async def main():
    loop = tornado.ioloop.IOLoop.current()
    while True:
        await fetch_data()
        await asyncio.sleep(3# Fetch data every 3 seconds
 
if __name__ == "__main__":
    app = tornado.web.Application()
    app.listen(8888)
 
    # Start the periodic task
    asyncio.ensure_future(main())
 
    tornado.ioloop.IOLoop.current().start()


Output:

ezgifcom-optimize-(4)

In this example, the `fetch_data()` coroutine simply generates a random number as if it’s fetching data. You can replace this with your actual data-fetching logic, such as making an HTTP request or querying a database.

Periodic Database Cleanup in Tornado

In this example, we’ll create a Tornado application that periodically cleans up a database by removing outdated records. The `cleanup_database()` coroutine simulates cleaning a database by removing odd numbers from a sample database list. You should replace this logic with your actual database cleanup process.

Python3




import tornado.ioloop
import tornado.web
import asyncio
 
# Sample list to represent a database
database = [1, 2, 3, 4, 5]
 
async def cleanup_database():
    # Simulate database cleanup (you can replace this with actual database cleanup logic)
    global database
    database = [item for item in database if item % 2 == 0# Remove odd numbers
    print("Database cleaned. Updated database:", database)
 
async def main():
    while True:
        await cleanup_database()
        await asyncio.sleep(3# Clean the database every 3 sec, just for example
 
if __name__ == "__main__":
    app = tornado.web.Application()
    app.listen(8888)
 
    # Start the periodic task
    asyncio.ensure_future(main())
 
    tornado.ioloop.IOLoop.current().start()


Output

ezgifcom-optimize-(5)

Both examples demonstrate the structure and use of asyncio in Tornado for periodic tasks. Replace the sample logic with your specific data fetching or database cleanup requirements as needed.

Conclusion

Asynchronous programming with asyncio in Tornado lets you optimize tasks periodically, making it suitable for tasks like data fetching, database cleanup, etc. By using the power of coroutines and asyncio’s scheduling capabilities, you can develop high-performance applications that run intermittently Hence, they do the job with ease.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads