Repository: holoviz/panel

Issue:
Caching per_session not working
I'm on panel==1.3.6. I would like to cache per session. But I don't believe its working.

```python
import panel as pn

pn.extension()

@pn.cache(per_session=True)
def get_data():
    print("running get_data")
    return "Some data"

pn.panel(get_data()).servable()
```

I would expect to get "running get_data" printed each time new session/ ServerConnection is created. But its not.

```bash
$ panel serve script.py --autoreload --index script.py
running get_data
2024-01-07 07:09:59,739 Starting Bokeh server version 3.3.2 (running on Tornado 6.3.3)
2024-01-07 07:09:59,741 User authentication hooks NOT provided (default user enabled)
2024-01-07 07:09:59,743 Bokeh app running at: http://localhost:5006/
2024-01-07 07:09:59,743 Bokeh app running at: http://localhost:5006/script
2024-01-07 07:09:59,743 Starting Bokeh server with process id: 31575
2024-01-07 07:10:01,916 WebSocket connection opened
2024-01-07 07:10:01,916 ServerConnection created
2024-01-07 07:10:11,724 WebSocket connection closed: code=None, reason=None
2024-01-07 07:10:11,910 WebSocket connection opened
2024-01-07 07:10:11,910 ServerConnection created
2024-01-07 07:10:12,850 WebSocket connection closed: code=None, reason=None
2024-01-07 07:10:13,019 WebSocket connection opened
2024-01-07 07:10:13,019 ServerConnection created
2024-01-07 07:10:13,829 WebSocket connection closed: code=None, reason=None
2024-01-07 07:10:14,132 WebSocket connection opened
2024-01-07 07:10:14,133 ServerConnection created
2024-01-07 07:10:14,621 WebSocket connection closed: code=None, reason=None
2024-01-07 07:10:14,785 WebSocket connection opened
2024-01-07 07:10:14,785 ServerConnection created
2024-01-07 07:10:15,324 WebSocket connection closed: code=None, reason=None
2024-01-07 07:10:15,504 WebSocket connection opened
2024-01-07 07:10:15,505 ServerConnection created
2024-01-07 07:10:15,990 WebSocket connection closed: code=None, reason=None
2024-01-07 07:10:16,203 WebSocket connection opened
2024-01-07 07:10:16,204 ServerConnection created
2024-01-07 07:10:16,638 WebSocket connection closed: code=None, reason=None
2024-01-07 07:10:16,796 WebSocket connection opened
2024-01-07 07:10:16,797 ServerConnection created
2024-01-07 07:10:17,326 WebSocket connection closed: code=None, reason=None
2024-01-07 07:10:17,679 WebSocket connection opened
2024-01-07 07:10:17,680 ServerConnection created
2024-01-07 07:10:17,971 WebSocket connection closed: code=None, reason=None
2024-01-07 07:10:18,152 WebSocket connection opened
2024-01-07 07:10:18,152 ServerConnection created
2024-01-07 07:10:31,463 WebSocket connection opened
2024-01-07 07:10:31,463 ServerConnection created
```


Discussion:

Resolving patch:
diff --git a/panel/io/cache.py b/panel/io/cache.py
--- a/panel/io/cache.py
+++ b/panel/io/cache.py
@@ -350,7 +350,8 @@ def cache(
             max_items=max_items,
             ttl=ttl,
             to_disk=to_disk,
-            cache_path=cache_path
+            cache_path=cache_path,
+            per_session=per_session,
         )
     func_hash = None # noqa
 
@@ -434,7 +435,7 @@ def wrapped_func(*args, **kwargs):
                     func_cache[hash_value] = (ret, time, 0, time)
             return ret
 
-    def clear(session_context=None):
+    def clear():
         global func_hash
         # clear called before anything is cached.
         if 'func_hash' not in globals():
@@ -448,10 +449,13 @@ def clear(session_context=None):
         else:
             cache = state._memoize_cache.get(func_hash, {})
         cache.clear()
+
     wrapped_func.clear = clear
 
     if per_session and state.curdoc and state.curdoc.session_context:
-        state.curdoc.on_session_destroyed(clear)
+        def server_clear(session_context):
+            clear()
+        state.curdoc.on_session_destroyed(server_clear)
 
     try:
         wrapped_func.__dict__.update(func.__dict__)


Test patch:
diff --git a/panel/tests/io/test_cache.py b/panel/tests/io/test_cache.py
--- a/panel/tests/io/test_cache.py
+++ b/panel/tests/io/test_cache.py
@@ -3,10 +3,13 @@
 import pathlib
 import time
 
+from collections import Counter
+
 import numpy as np
 import pandas as pd
 import param
 import pytest
+import requests
 
 try:
     import diskcache
@@ -15,7 +18,8 @@
 diskcache_available = pytest.mark.skipif(diskcache is None, reason="requires diskcache")
 
 from panel.io.cache import _find_hash_func, cache
-from panel.io.state import set_curdoc
+from panel.io.state import set_curdoc, state
+from panel.tests.util import serve_and_wait
 
 ################
 # Test hashing #
@@ -219,6 +223,26 @@ def test_per_session_cache(document):
         assert fn(a=0, b=0) == 0
     assert fn(a=0, b=0) == 1
 
+def test_per_session_cache_server(port):
+    counts = Counter()
+
+    @cache(per_session=True)
+    def get_data():
+        counts[state.curdoc] += 1
+        return "Some data"
+
+    def app():
+        get_data()
+        get_data()
+        return
+
+    serve_and_wait(app, port=port)
+
+    requests.get(f"http://localhost:{port}/")
+    requests.get(f"http://localhost:{port}/")
+
+    assert list(counts.values()) == [1, 1]
+
 @pytest.mark.xdist_group("cache")
 @diskcache_available
 def test_disk_cache():