Function sticking cause of session_state not clearing on page reload or browser tab close

Hello everyone,

I’m grappling with a change in the logic of session_state starting from release 1.28.0.

I have a multipage application where, upon the user clicking a form button, I call a function that makes an API request. The response might take around 3-10 minutes, and it can’t be cached because the results may differ even with the same arguments. In this function, I pass st.session_state to control user actions. That is, if a user doesn’t want to wait, they can reload the page or stop execution or close the browser tab, and the session state becomes empty, stopping the execution of the function. However, this logic breaks in version 1.28.0 and above. Now, the session_state passed into the function doesn’t clear if a reload or tab closure occurs. This, I believe, causes the function to get stuck in a thread and not stop. When I try to stop the server with Ctrl+C, it doesn’t stop and requires a force stop, leading to an error: RuntimeError(‘Event loop is closed’).

The new logic of session state is preventing me from upgrading. Any suggestions on how to fix this?

Additional info:

In config.toml, runner.fastReruns = false.
Behind the API request is a long chain with RabbitMQ, and in some cases, a message can be acked manually from the queue and never return a result (which is normal behavior). That’s why I can’t leave it, as it may be stuck without session_state clearing.

Here’s a quick example of the problem:
In version 1.27.0 work fine and stops function if reload page. In version 1.28.0 and above dont work and stuck in event loop

import streamlit as st
import time


def mock_api_call(st):
    count = 0
    while st:
        count += 1
        print('#'*30)
        print(f'Count: {count}')
        print(f"Type: {type(st)}")
        print((f"id: {id(st)}"))
        print(st)
        print('#' * 30)
        time.sleep(3)
    print(f"END WHILE st {st}")

st.write("first time session_state", st.session_state)
st.write("id of session_state", id(st.session_state))


btn = st.button("Start")

if btn:
    st.session_state['is_alive'] = True
    mock_api_call(st.session_state)

1 Like