We know that streamlit will re-execute our script on a widget change. But is it guaranteed that the script will fully execute on each widget change? Or is it possible that if there are too frequent widget changes, one script execution gets interrupted midway?
Streamlit is just a software - a work in progress, written by humans to do its work as designed. It has documentations of what it is capable of, how to use it, etc. It might break depending upon how the users write their code.
@ferdy, I should have worded my question a bit better. Of course it wouldn’t be “guaranteed” in the sense that there can never be errors. But I am asking more from the design point-of-view; whether streamlit is designed to interrtupt script execution if there are too many widget changes, or does it always try to execute the script until it ends whether its sucessful or not? Concretely, I am having a problem with an application such as below (its not the actual code its just a short sample):
import streamlit as st
from threading import Lock
import time
@st.cache_resource
def some_lock() -> Lock:
return Lock()
# A dummy radio widget
st.radio("Select something", ["a", "b", "c"])
some_lock().acquire()
# Entering critical section
try:
time.sleep(1)
st.write("work")
except Exception as ex:
print(str(ex))
finally:
some_lock().release()
If you run the above example, and change the radio rapidly, the program will deadlock because the script will be interrupted in the critical section where the lock is not released. Then, when a re-exectuion happens the script indefinitely waits on the lock because it is already previously acquired. If you change the radio slowly then there is no deadlock because the script is not interrupted in the critical section.
In my problem, I have another solution that does not require locks. However, this behavior can cause many issues. For example, you might have a script that inserts data into a database, if the script gets interrupted without committing to the database all of that data would be lost.
I think that is the answer to your question and it is consistent with my own findings.
Note that the behavior could be different for code that runs in a separate thread or a separate process.
To avoid the deadlock, use the following construct.
import streamlit as st
from threading import Lock
import time
if 'lock' not in st.session_state:
st.session_state.lock = Lock()
# A dummy radio widget
st.radio("Select something", ["a", "b", "c"], key='rb')
st.write(st.session_state.rb)
with st.session_state.lock:
time.sleep(5)
st.write("work done")
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.