Reputation: 23
I am trying to make a UDP server and next to it a periodic task that updates a global variable every 5 minutes.
But the problem is that my UDP server and my task part blocks the rest of the code (because I use while True:
).
I was looking at this example: https://docs.python.org/3/library/asyncio-protocol.html#asyncio-udp-echo-server-protocol
import asyncio
class EchoServerProtocol:
def connection_made(self, transport):
self.transport = transport
def datagram_received(self, data, addr):
message = data.decode()
print('Received %r from %s' % (message, addr))
print('Send %r to %s' % (message, addr))
self.transport.sendto(data, addr)
async def main():
print("Starting UDP server")
# Get a reference to the event loop as we plan to use
# low-level APIs.
loop = asyncio.get_running_loop()
# One protocol instance will be created to serve all
# client requests.
transport, protocol = await loop.create_datagram_endpoint(
lambda: EchoServerProtocol(),
local_addr=('127.0.0.1', 9999))
try:
await asyncio.sleep(3600) # Serve for 1 hour.
finally:
transport.close()
asyncio.run(main())
I see in the example that they run this for an hour. But what if I wanted to run it indefinitely? I played with run_forever()
, but I don't understand how it works.
I also don't understand how to make a periodic task that doesn't use while True:
at the same time.
Is this possible?
Upvotes: 0
Views: 1022
Reputation: 6764
Instead waiting for an hour, just make an infinite loop which executes your periodic task.
Replace
await asyncio.sleep(3600)
with
while True:
print("do something every 5 minutes", datetime.datetime.now())
await asyncio.sleep(5*60)
Upvotes: 0
Reputation: 10946
Replace your asyncio.sleep(3600)
with a wait for an asyncio.Event
that never happens. That will suspend the task forever but leave the event loop running. The only way to terminate the program is with Ctrl-C or some other operating system action.
try:
await asyncio.Event().wait() # wait here until the Universe ends
finally:
transport.close()
Upvotes: 2