What I’m trying to do:
I am trying to understand the lifespan of an alert. I have a form which is opened in an alert and dismissed. Yet the alert form is still “alive” after the alert has been closed.
What I’ve tried and what’s not working:
I noticed this because I was using the publish/subscribe utility in the anvil_extras package. In the alert, I subscribe to a channel and publish to that channel elsewhere. This worked great, but when I no longer am in that form, this published message still raises the handler method and causes an error.
I was able to resolve this fairly easy by unsubscribing in the alert before it is dismissed, but it brought me to the question; when is the alert out of scope? Does it live in the background for the entire session?
Here is a simple demo.
You see the alert is still interactive by doing the following:
- click the alert button
- dismiss the alert by clicking off of it
- click the publish message button
This will generate a message in the terminal. If you generate multiple alerts, all will receive the message.
Thanks for any insight!
Clone link:
https://anvil.works/build#clone:LHTRAYBZB555BSVY=JJKURMG2DPRNVTHUKZ4EBVFK
General observations (I haven’t looked at your clone).
This is likely less about scope, and more about lifetime.
In Python, names have scope. Scope is about which names are visible, and where they’ve visible. This is independent of object lifetime.
Objects have a lifetime. In general, an object will continue to exist as long as some object, somewhere in your running program, has a reference to it.
For example, a publish-subscribe mechanism will keep just such a reference.
You may create an object in one scope (e.g., a function body), pass it (return it) to another scope, where it may be known by a different name entirely. Multiple objects may end up referring to it.
It’s fairly easy to end up with circular references: object 1 refers to object 2, which refers to object 1. The interpreter has to work to discover such isolated loops, in its “garbage collector”, so such objects will hang around longer, i.e., until the garbage collector finds them.
For an excellent description of object lifetime, see
2 Likes
I have not cloned the app, but my guess is that your alert shows a form and you are dealing with the scope of that form, not the scope of the alert itself.
For example:
f = MyForm()
alert(f)
# After the alert is closed, the alert doesn't exist
# anymore, but f is still alive and kicking
#
# f will be out of scope when this function exits
but:
self.f = MyForm()
alert(self.f)
# Here self.f will be out of scope only after the
# form is destroyed... unless the form is cached, for
# example if you use routing from Anvil Extras
1 Like
From the subscribe docs:
"You can unsubscribe from a channel using the publisher’s unsubscribe method.
You can also remove an entire channel using the publisher’s close_channel method.
Be sure to do one of these if you remove instances of a form as the publisher will hold references to those instances and the handlers will continue to be called."
https://anvil-extras.readthedocs.io/en/latest/guides/modules/messaging.html#subscribe-to-a-channel
2 Likes
Thank you for the clarification! I had a hunch “scope” wasn’t the right termonolgy. I will definitely give the link a read!
Not sure if this is interpreted differently than the first example you gave, but it is like this
alert(MyForm())
I put it in the same line as an attempt to have its lifespan end when the alert was dismissed.
Looks like I was one line away from reading what was holding my reference!