kytos-ng / kytos

Kytos SDN Platform. Kytos is designed to be easy to install, use, develop and share Network Apps (NApps).
https://kytos-ng.github.io/
MIT License
2 stars 7 forks source link

feat: augmented listen_to pool kwargs to support 'dynamic_single' #399

Closed viniarck closed 11 months ago

viniarck commented 11 months ago

Closes #397

Summary

With this feature we can revert (part of) certain specific fixes that had to fix on NApps, for instance:

Side node

For future developers readers, if you can afford and don't have blocking dependencies, you can also achieve a similar result with alisten_to decorator for async functions since you have explicit control when the task yields, so you can also try to leverage alisten_to if you don't have threading.Lock, since a threading.Lock wasn't designed to be used with coroutines (unlike asyncio.Lock). This is what we've done on of_core on_raw_in handler

Local Tests

    @listen_to("kytos.topology.updated", pool="dynamic_single")
    def on_topology_updated(self, event):
        """on_topology_updated."""
        t = random.randint(1, 5)
        log.info(f"handling topo_update ts: {event.timestamp}, it'll sleep for {t} secs")
        time.sleep(t)
        log.info(f"handling topo_update ts: {event.timestamp} done")

This example is forcing a random time sleep for 1-5 secs, if you check the logs you can see that handling topo_update ts: respects the FIFO order

2023-07-19 15:30:40,991 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:40.987721+00:00, it'll sleep 
for 1 secs
2023-07-19 15:30:41,993 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:40.987721+00:00 done
2023-07-19 15:30:41,993 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:40.993571+00:00, it'll sleep 
for 4 secs
2023-07-19 15:30:45,998 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:40.993571+00:00 done
2023-07-19 15:30:45,999 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:40.994863+00:00, it'll sleep 
for 1 secs
2023-07-19 15:30:47,000 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:40.994863+00:00 done
2023-07-19 15:30:47,001 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:40.995381+00:00, it'll sleep 
for 3 secs
2023-07-19 15:30:50,003 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:40.995381+00:00 done
2023-07-19 15:30:50,004 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.208848+00:00, it'll sleep 
for 5 secs
2023-07-19 15:30:55,007 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.208848+00:00 done
2023-07-19 15:30:55,007 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.211174+00:00, it'll sleep 
for 1 secs
2023-07-19 15:30:56,008 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.211174+00:00 done
2023-07-19 15:30:56,009 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.212471+00:00, it'll sleep 
for 2 secs
2023-07-19 15:30:58,011 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.212471+00:00 done
2023-07-19 15:30:58,012 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.217225+00:00, it'll sleep 
for 2 secs
2023-07-19 15:31:00,014 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.217225+00:00 done
2023-07-19 15:31:00,015 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.306234+00:00, it'll sleep 
for 1 secs
2023-07-19 15:31:01,017 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.306234+00:00 done
2023-07-19 15:31:01,017 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.306557+00:00, it'll sleep 
for 4 secs
2023-07-19 15:31:05,020 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.306557+00:00 done
2023-07-19 15:31:05,021 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.306819+00:00, it'll sleep 
for 5 secs
2023-07-19 15:31:10,026 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.306819+00:00 done
2023-07-19 15:31:10,027 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.307170+00:00, it'll sleep 
for 2 secs
2023-07-19 15:31:12,030 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.307170+00:00 done
2023-07-19 15:31:12,031 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.307951+00:00, it'll sleep 
for 3 secs
2023-07-19 15:31:15,034 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.307951+00:00 done
2023-07-19 15:31:15,035 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.308313+00:00, it'll sleep 
for 3 secs
2023-07-19 15:31:18,037 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.308313+00:00 done
2023-07-19 15:31:18,037 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.308811+00:00, it'll sleep 
for 4 secs
2023-07-19 15:31:22,040 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.308811+00:00 done
2023-07-19 15:31:22,041 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.309109+00:00, it'll sleep 
for 5 secs
2023-07-19 15:31:27,046 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.309109+00:00 done
2023-07-19 15:31:27,047 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.309276+00:00, it'll sleep 
for 5 secs
2023-07-19 15:31:32,052 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.309276+00:00 done
2023-07-19 15:31:32,053 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.309447+00:00, it'll sleep 
for 2 secs
2023-07-19 15:31:34,056 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.309447+00:00 done
2023-07-19 15:31:34,056 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.312398+00:00, it'll sleep 
for 5 secs
2023-07-19 15:31:39,059 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.312398+00:00 done
2023-07-19 15:31:39,060 - INFO [kytos.napps.amlight/noviflow] [main.py:117:on_topology_updated] (dynamic_single_0) handling topo_update ts: 2023-07-19 18:30:42.313410+00:00, it'll sleep 
    @listen_to("kytos.topology.updated")
    def on_topology_updated(self, event):
        """on_topology_updated."""
        t = random.randint(1, 5)
        log.info(f"handling topo_update ts: {event.timestamp}, it'll sleep for {t} secs")
        time.sleep(t)
        log.info(f"handling topo_update ts: {event.timestamp} done")

This is the case where out of order events can happen, since the time.sleep here is forcning a simulation of a thread being suspended and then resumed (and this has been a source of potential out of order event issues that we've been dealing with):

2023-07-19 15:33:50,727 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (thread_pool_app_88) handling topo_update ts: 2023-07-19 18:33:48.724754+00:00 done
2023-07-19 15:33:50,730 - INFO [kytos.napps.amlight/noviflow] [main.py:119:on_topology_updated] (thread_pool_app_14) handling topo_update ts: 2023-07-19 18:33:47.728401+00:00 done

End-to-End Tests

I'll run e2e tests with a related test on pathfinder, I'll post the results here.