diff options
Diffstat (limited to 'aergia')
| -rwxr-xr-x | aergia/aergia.py | 39 |
1 files changed, 17 insertions, 22 deletions
diff --git a/aergia/aergia.py b/aergia/aergia.py index b7b4f35..ad283e0 100755 --- a/aergia/aergia.py +++ b/aergia/aergia.py @@ -175,35 +175,30 @@ class Aergia(object): @staticmethod def get_event_loops(): - '''Obtains each thread's event loop by relying on the fact that - if an event loop is active, it's own `run_once' and `run_forever' - will appear in the callstack.''' + '''Obtains each thread's event loop.''' loops = [] for t in threading.enumerate(): frame = sys._current_frames().get(t.ident) - if not frame: - continue - loops.extend(Aergia.walk_back_until_loops(frame)) + if frame: + loop = Aergia.walk_back_until_loop(frame) + if loop and loop not in loops: + loops.append(loop) return loops @staticmethod - def walk_back_until_loops(frame): - '''Walks back the callstack until all event loops are found.''' - loops = [] + def walk_back_until_loop(frame): + '''Walks back the callstack until we are in a method named '_run_once'. + If this is ever true, we assume we are in an Asyncio event loop method, + and check to see if the 'self' variable is indeed and instance of + AbstractEventLoop. Return this variable if true.''' while frame: - loop = Aergia.find_loop_in_locals(frame.f_locals) - if loop and loop not in loops: # Avoid duplicates - loops.append(loop) - frame = frame.f_back - return loops - - @staticmethod - def find_loop_in_locals(locals_dict): - '''Given a dictionary of local variables for a stack frame, - retrieves the asyncio loop object, if there is one.''' - for val in locals_dict.values(): - if isinstance(val, asyncio.AbstractEventLoop): - return val + if frame.f_code.co_name == '_run_once' and 'self' in frame.f_locals: + loop = frame.f_locals['self'] + if isinstance(loop, asyncio.AbstractEventLoop): + return loop + else: + # print(frame.f_code.co_name) + frame = frame.f_back return None @staticmethod |
