Skip to content

MediaFile Grace Period using KEEP_DELAY = 5 seconds#1494

Merged
nthmost merged 13 commits intostreamlit:developfrom
nthmost:mediafile_grace_period
Jun 20, 2020
Merged

MediaFile Grace Period using KEEP_DELAY = 5 seconds#1494
nthmost merged 13 commits intostreamlit:developfrom
nthmost:mediafile_grace_period

Conversation

@nthmost
Copy link
Copy Markdown
Contributor

@nthmost nthmost commented May 22, 2020

Fixes #1440, Fixes #1294, Fixes #1454

Description:

The MediaFileManager currently uses a method of management that involves assuming that when a Session has completed its run, those files are no longer needed and can be safely deleted.

However, the reality is that the browser may not have had enough time between session runs to request that file, particularly in rapid-fire script reruns, resulting in broken images being shown to the user as the browser tries to request files that have already been deleted.

Examples of rapid-fire session creation-and-destruction include:

  • Using the slider to generate pyplots.
  • Rapidly checking and unchecking a checkbox that generates/shows an image.
  • Streaming a video from YouTube and using an st.image element to show each frame from that video.

This PR introduces a KEEP_DELAY (which could potentially be configurable, but for now is statically defined) in MediaFileManager.py (MFM) and presently set to 5 seconds (a setting found by experimentation... I tried 1-2 seconds and that didn't work too well).

When a MediaFile is created, it gets a ttd (time to die) time set to time.time() + KEEP_DELAY

Each time a session finishes, it triggers the checking of each file_id currently stored in the MFM to see if its ttd has expired compared to time.time()

This results in enough of a grace period before wiping expired media files to eliminate the effects seen in #1440 and similar bugs (see issues listed above).


Contribution License Agreement

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.

@nthmost nthmost requested a review from a team as a code owner May 22, 2020 17:53
Copy link
Copy Markdown
Contributor

@tvst tvst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! But PTAL at potential improvements in the comments

LOGGER.debug(
"Sessions still active: %r", self._files_by_session_and_coord.keys()
)
self._del_expired_files()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that files from one session will linger until some other session happens to start or end, and that even happens to take place KEEP_DELAY secs later. To improve this, how about running _del_expired_files from a timer?

The only wrinkle with this idea is that one of the places where clear_session_files is called is when the script is about to run, so we can't simply add a time.sleep(KEEP_DELAY) here. So we have to schedule the run via Tornado's IOLoop instead. But since this function is always called from the actual Script thread, we can't just use tornado.ioloop.IOLoop.current() to get the current IOLoop. So we need to do a tiny bit of piping:

# In Server.py __init__ method
    media_file_manager.set_ioloop(ioloop = self._ioloop)

# In MediaFileManager
    def __init__(self):
        # (..._)
        self._ioloop = None

    def set_ioloop(self, ioloop):
        self._ioloop = ioloop

    def clear_session_files(...):
        # (...)
        self._ioloop.call_later(KEEP_DELAY_SEC, self._del_expired_files)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this seems to work. I've had to adjust KEEP_DELAY_SEC to be longer (4 or 5, more testing required).

A lot of tests need to be adjusted now, due to the change in Server.py...

@nthmost nthmost changed the title MediaFile Grace Period using KEEP_DELAY = 2 seconds MediaFile Grace Period using KEEP_DELAY = 5 seconds Jun 20, 2020
@nthmost nthmost merged commit 284b528 into streamlit:develop Jun 20, 2020
@JohnPaton
Copy link
Copy Markdown

JohnPaton commented Jun 22, 2020

Thanks for the fix! Looks like the issue is gone in the nightly version 🎉

tconkling added a commit that referenced this pull request Jun 22, 2020
* develop:
  Formatting changes from `make pyformat` (#1621)
  Add config to disable CSRF + conflict check with CORS (#1571)
  MediaFile Grace Period using KEEP_DELAY = 5 seconds (#1494)
  Fix server.cookieSecret config option. (#1603)
  Create a config option to toggle websocket compression (#1544)
  Remove Python 2 and Python 3.5 staleness (#1600)
  Disable/Remove scroll when in full screen mode (#1586)
  Better welcome message when running `streamlit hello` (#1585)
  Scale image to approximate size on screen (#1594)
@hb-cam
Copy link
Copy Markdown

hb-cam commented Aug 27, 2021

Hi, I'm currently having this issue with an AppEngine hosted flask app which generates multiple plots on the fly. The app takes a user loaded file, processes it, then charts the resultant analyses - however, the charts randomly load,,, sometimes the user will get 2 of 5, other times 3 of 5, and which charts load is random. Any thought?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

st.image() blinks sporadically in 0.59 Many (maybe most) images generated by st.pyplot() break in version 0.59 Images sometimes do not appear

4 participants