# How to use pn.state.on\_session\_destroyed

**URL:** <https://discourse.holoviz.org/t/how-to-use-pn-state-on-session-destroyed/5121>\
**Category:** Panel\
**Tags:** panel\
**Created:** [March 21, 2023, 11:10pm UTC](https://discourse.holoviz.org/t/how-to-use-pn-state-on-session-destroyed/5121 "2023-03-21T23:10:51Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![CongTang](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/congtang/32/3055_2.png) [@CongTang](https://discourse.holoviz.org/u/CongTang)\
**Post date:** [March 21, 2023, 11:10pm UTC](https://discourse.holoviz.org/t/how-to-use-pn-state-on-session-destroyed/5121/1 "2023-03-21T23:10:51Z")

</div>

Hi

I am trying to use pn.state.on\_session\_destroyed to clean up. And i received an error of “RuntimeError: Could not add session destroyed callback since no document to attach it to could be found.”

Do we have any example about how to the on\_session\_destroyed?

Any help will be gratefully

Kind regards  
Victor

---

<div class="post-metadata">

**Author:** ![Marc](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/marc/32/24_2.png) [@Marc](https://discourse.holoviz.org/u/Marc)\
**Post date:** [March 22, 2023, 5:02am UTC](https://discourse.holoviz.org/t/how-to-use-pn-state-on-session-destroyed/5121/2 "2023-03-22T05:02:59Z")

</div>

Hi @CongTang

Could you provide more detail of what you are doing like a minimum, reproducible example?

---

<div class="post-metadata">

**Author:** ![CongTang](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/congtang/32/3055_2.png) [@CongTang](https://discourse.holoviz.org/u/CongTang)\
**Post date:** [March 23, 2023, 9:52pm UTC](https://discourse.holoviz.org/t/how-to-use-pn-state-on-session-destroyed/5121/3 "2023-03-23T21:52:07Z")

</div>

Hi Marc

I am trying to user on\_session\_destroyed to remove the name.

Please see the code below:

```auto
import panel as pn
import pandas as pd
import numpy as np
import string
import random
 
pn.extension(sizing_mode='stretch_width',comms = 'vscode',notifications=True) 

if 'user_infor' not in pn.state.cache:
    pn.state.cache['user_infor'] = pd.DataFrame(columns = ['Name','Role']).set_index('Name')
player_name = ''.join(random.choices(string.ascii_uppercase + string.digits, k=5))
pn.state.cache['user_infor'].loc[player_name] = 'game_role'

table = pn.pane.DataFrame(
    pn.state.cache['user_infor']
)

def update():
    table.object = pn.state.cache['user_infor']
    
game_page_cb = pn.state.add_periodic_callback(update, 5000,start =True,timeout = 60000)

def user_logout():
    pn.state.cache['user_infor'].drop(player_name)

pn.state.on_session_destroyed(user_logout)

app = pn.Column(table)  

app.servable();

```

and get an error:ValueError: Callback functions must have signature func(session\_context), got func()

Any suggestion will be greatful 😀

Kind regards  
Cong

---

<div class="post-metadata">

**Author:** ![Marc](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/marc/32/24_2.png) [@Marc](https://discourse.holoviz.org/u/Marc)\
**Post date:** [March 24, 2023, 4:51am UTC](https://discourse.holoviz.org/t/how-to-use-pn-state-on-session-destroyed/5121/4 "2023-03-24T04:51:42Z")

</div>

Hi @CongTang

As I read the error message your `update` callback signature needs to change to `def update(session_context)`.

If I change to that, I can get the below working.

```python
import panel as pn
import pandas as pd
import numpy as np
import string
import random
 
pn.extension(sizing_mode='stretch_width',comms = 'vscode',notifications=True) 

if 'user_infor' not in pn.state.cache:
    pn.state.cache['user_infor'] = pd.DataFrame(columns = ['Name','Role']).set_index('Name')
player_name = ''.join(random.choices(string.ascii_uppercase + string.digits, k=5))
pn.state.cache['user_infor'].loc[player_name] = 'game_role'

table = pn.pane.DataFrame(
    pn.state.cache['user_infor']
)

def update():
    table.object = pn.state.cache['user_infor']
    
game_page_cb = pn.state.add_periodic_callback(update, 5000,start =True,timeout = 60000)

def user_logout(sessionContext):
    print(sessionContext)
    pn.state.cache['user_infor'].drop(player_name)
    print("dropped")

pn.state.on_session_destroyed(user_logout)

app = pn.Column(table)  

app.servable()

```

```bash
$ panel serve 'scripts\specify_value.py' --autoreload
2023-03-24 05:48:37,500 Starting Bokeh server version 2.4.3 (running on Tornado 6.2)
2023-03-24 05:48:37,501 User authentication hooks NOT provided (default user enabled)
2023-03-24 05:48:37,503 Bokeh app running at: http://localhost:5006/specify_value
2023-03-24 05:48:37,503 Starting Bokeh server with process id: 34328
2023-03-24 05:48:41,577 WebSocket connection opened
2023-03-24 05:48:41,578 ServerConnection created
2023-03-24 05:48:41,578 404 GET /favicon.ico (::1) 0.00ms
2023-03-24 05:48:50,253 WebSocket connection closed: code=1001, reason=None
2023-03-24 05:48:59,854 WebSocket connection opened
2023-03-24 05:48:59,855 ServerConnection created
2023-03-24 05:49:10,740 WebSocket connection closed: code=1001, reason=None
<bokeh.server.contexts.BokehSessionContext object at 0x0000019377B37F70>
dropped

```

---

<div class="post-metadata">

**Author:** ![Marc](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/marc/32/24_2.png) [@Marc](https://discourse.holoviz.org/u/Marc)\
**Post date:** [March 24, 2023, 5:06am UTC](https://discourse.holoviz.org/t/how-to-use-pn-state-on-session-destroyed/5121/5 "2023-03-24T05:06:15Z")

</div>

I’ve made a PR to describe the required callback signature. Please take a look @CongTang and let me know if this improvement would have solved your issue up front.

[Describe on\_session\_destroyed callback signature by MarcSkovMadsen · Pull Request #4555 · holoviz/panel (github.com)](https://github.com/holoviz/panel/pull/4555)

Thanks.

---

<div class="post-metadata">

**Author:** ![CongTang](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/congtang/32/3055_2.png) [@CongTang](https://discourse.holoviz.org/u/CongTang)\
**Post date:** [March 26, 2023, 3:42pm UTC](https://discourse.holoviz.org/t/how-to-use-pn-state-on-session-destroyed/5121/6 "2023-03-26T15:42:17Z")

</div>

Hi Marc

Really thanks for your help. That work pretty well. 😀

Kind regards  
Victor

---

<div class="post-metadata">

**Author:** ![CongTang](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/congtang/32/3055_2.png) [@CongTang](https://discourse.holoviz.org/u/CongTang)\
**Post date:** [March 26, 2023, 5:46pm UTC](https://discourse.holoviz.org/t/how-to-use-pn-state-on-session-destroyed/5121/7 "2023-03-26T17:46:26Z")

</div>

Hi Marc

Just noticed an issue(not too sure if it is a mechanism or a bug).

The pn.state.on\_session\_destroyed is only working with the --atuoreload , otherwise it will end up with

```auto
<bokeh.server.contexts.BokehSessionContext object at 0x0000025CA72F3BE0>
2023-03-26 18:41:37,316 DocumentLifeCycleHandler on_session_destroyed callback <function user_logout at 0x0000025CA72EBA30> failed with following error: name 'pn' is not defined

```

Kind regards  
Vcitor

---

<div class="post-metadata">

**Author:** ![Marc](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/marc/32/24_2.png) [@Marc](https://discourse.holoviz.org/u/Marc)\
**Post date:** [March 26, 2023, 6:22pm UTC](https://discourse.holoviz.org/t/how-to-use-pn-state-on-session-destroyed/5121/8 "2023-03-26T18:22:07Z")

</div>

It looks like a bug to me. Could you report it on github @CongTang ?

As a workaround you can try adding

```python
import panel as pn

```

to your `user_logout` callback.

---

<div class="post-metadata">

**Author:** ![CongTang](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/congtang/32/3055_2.png) [@CongTang](https://discourse.holoviz.org/u/CongTang)\
**Post date:** [March 26, 2023, 6:40pm UTC](https://discourse.holoviz.org/t/how-to-use-pn-state-on-session-destroyed/5121/9 "2023-03-26T18:40:00Z")

</div>

Sure. I will report it to GitHub.

Yes, if I import it, it will work. But it will not unable to process some parameters of the original program.

and i would see it is not a serious bug as it still works with --atuoreload

Thanks for your answer and support. 😀

Kind regards  
Victor

---

<div class="post-metadata">

**Author:** ![Material-Scientist](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/material-scientist/32/503_2.png) [@Material-Scientist](https://discourse.holoviz.org/u/Material-Scientist)\
**Post date:** [March 27, 2023, 1:19am UTC](https://discourse.holoviz.org/t/how-to-use-pn-state-on-session-destroyed/5121/10 "2023-03-27T01:19:31Z")

</div>

It happens as sessions are being unloaded from memory. I’ve encountered the same bug numerous times:

[[BUG] background thread stops when session is destroyed, leading to weird errors - Panel - HoloViz Discourse](https://discourse.holoviz.org/t/bug-background-thread-stops-when-session-is-destroyed-leading-to-weird-errors/2962/4)

`'Exception' is not defined` - lol

 ![image](https://discourse.holoviz.org/uploads/default/original/2X/b/b7824c5219b1fcce99ab4c393c7d460b3b3c3b24.jpeg)

`pn.state.on_session_destroyed` callback also doesn’t work when you use lifecycle hooks in a separate file (even though it’s in the state’s callbacks). However, the `on_session_destroyed` callback does get called from within the app\_hooks.py file 🤷‍♂️

Extra FYI:  
The session unloading seems to happen more aggressively when using `--num-threads`  
This is actually a nice bug (feature? 😁 ) as you can get around memory leaks. Even better if you periodically restart your cluster workers to release memory back to the OS:  
 ![image](https://discourse.holoviz.org/uploads/default/original/2X/4/471b0249058c11d79e672ff324f8fe95c314db23.png)

Haven’t had issues with memory leaks since.

Ah, btw - this also makes watcher callbacks fail. Can only let them fail silently as sessions are being unloaded.

![image](https://discourse.holoviz.org/uploads/default/original/2X/a/a0de7dbfb1f45d1457ca66b06ad712a83ec95e53.png)
