def shutdown(self) -> None: """Shut down the AppSession. It's an error to use a AppSession after it's been shut down. """ if self._state != AppSessionState.SHUTDOWN_REQUESTED: LOGGER.debug("Shutting down (id=%s)", self.id) # Clear any unused session files in upload file manager and media # file manager self._uploaded_file_mgr.remove_session_files(self.id) in_memory_file_manager.clear_session_files(self.id) in_memory_file_manager.del_expired_files() # Shut down the ScriptRunner, if one is active. # self._state must not be set to SHUTDOWN_REQUESTED until # after this is called. if self._scriptrunner is not None: self._enqueue_script_request(ScriptRequest.SHUTDOWN) self._state = AppSessionState.SHUTDOWN_REQUESTED self._local_sources_watcher.close() if self._stop_config_listener is not None: self._stop_config_listener() secrets._file_change_listener.disconnect( self._on_secrets_file_changed)
def _on_script_finished(self, ctx: ScriptRunContext) -> None: """Called when our script finishes executing, even if it finished early with an exception. We perform post-run cleanup here. """ self._session_state.reset_triggers() self._session_state.cull_nonexistent(ctx.widget_ids_this_run) # Signal that the script has finished. (We use SCRIPT_STOPPED_WITH_SUCCESS # even if we were stopped with an exception.) self.on_event.send(ScriptRunnerEvent.SCRIPT_STOPPED_WITH_SUCCESS) # Delete expired files now that the script has run and files in use # are marked as active. in_memory_file_manager.del_expired_files() # Force garbage collection to run, to help avoid memory use building up # This is usually not an issue, but sometimes GC takes time to kick in and # causes apps to go over resource limits, and forcing it to run between # script runs is low cost, since we aren't doing much work anyway. if config.get_option("runner.postScriptGC"): gc.collect(2)