pyscript icon indicating copy to clipboard operation
pyscript copied to clipboard

Triggers are not cleaned up in modules

Open dlashua opened this issue 4 years ago • 4 comments

After more investigation on #277 I've found this.

modules/trig_from_mod.py

def make_simple_trigger(note):
    @time_trigger("period(now, 1sec, now + 30sec)")
    def be_noisy():
        log.info(f'{note}')

    return be_noisy

scripts/quick_test.py

import trig_from_mod as tfm
ITER = 'd'

rt = []
@time_trigger('startup')
def startup():
    rett = tfm.make_simple_trigger(f'{ITER}')
    rt.append(rett)

To reproduce, save file and see logging start. Change ITER and save file again. Notice both sets of logging still occurring.

Moving make_simple_trigger into quick_test.py causes the expected behavior (the logging stops on reload of quick_test.py).

dlashua avatar Nov 28 '21 12:11 dlashua

I have managed to work around this with some ugly code...

Every time a script uses a module function that creates a trigger function, that module function also takes a registration parameter. I am passing this in as name from the calling script. Instead of returning the trigger function it instead registers it within the module by calling register_trigger(reg, func):

nt = {}

def register_trigger(reg, trig):
    log.info(f'Registering {reg} {trig}')
    if reg not in nt:
        nt[reg] = []

    nt[reg].append(trig)

def unregister_triggers(reg):
    log.info(f'Unregistering {reg}')
    if reg in nt:
        del nt[reg]

Then, each script must also call modulename.unregister_triggers(__name__) in a shutdown function.

This leads me to believe that the core of the issue has something to do with the context the trigger is associated with. I could be way off, though, as I was unable to pinpoint where this happens in the pyscript code.

There were some other interesting behaviors as well. For instance, even if I never stored the trigger function in a global variables (in the script or in the module) it would still react to events/state changes. However, without storing it, the only way to remove the trigger function was to reload the module.

dlashua avatar Mar 01 '22 12:03 dlashua

Is this still an issue? It seems like this may've been caused by #457, so it could be fixed now.

j-steve avatar Jul 18 '23 17:07 j-steve

Is this still an issue? It seems like this may've been caused by #457, so it could be fixed now.

I can confirm that this issue still exists with 1.4.0, so no, it is not fixed.

@dlashua could you elaborate what you mean by

each script must also call modulename.unregister_triggers(name) in a shutdown function. ?

I have the problem that while developing my pyscript module, I tend to modify&safe it a lot. This seems to lead to a number of identical trigger functions existing in parallel and triggering simultaneously. Since this is caused by just simply saving the file repeatedly, I do not think that I can create a function that will prevent it.

orbelico avatar Aug 17 '23 22:08 orbelico