Skip to content

fix: resolve session lifecycle bugs in Solara session management#980

Merged
dfguerrerom merged 2 commits intomainfrom
fix/session-lifecycle-bugs
Mar 18, 2026
Merged

fix: resolve session lifecycle bugs in Solara session management#980
dfguerrerom merged 2 commits intomainfrom
fix/session-lifecycle-bugs

Conversation

@dfguerrerom
Copy link
Collaborator

Summary

  • Make create_session idempotent — skip creation if a session already exists for the kernel, preventing leaked GEEInterface threads/event loops on every Solara re-render
  • Fix GEEInterface.close() — the hasattr guards checked _sync_loop/_sync_thread but the constructor creates _async_loop/_async_thread, so cleanup never actually stopped the background loop or joined the thread
  • Fail loud in multi-user contextget_current_gee_interface() and get_current_drive_interface() now raise RuntimeError when SessionManager is active but no session exists for the current kernel, instead of silently falling back to shared process-level credentials. The fallback is preserved for non-Solara contexts (notebooks, scripts).

Test plan

  • Deploy a Solara app with @with_sepal_sessions and verify session is created once per kernel (check logs for "skipping creation" on re-renders)
  • Verify GEEInterface.close() stops the background thread on kernel shutdown (no lingering threads)
  • Confirm that calling get_current_gee_interface() without @with_sepal_sessions in a Solara app raises RuntimeError
  • Confirm notebook/script usage still gets the fallback GEEInterface without error

- Make create_session idempotent by skipping if kernel already has a session,
  preventing leaked GEEInterface threads on every Solara re-render
- Fix GEEInterface.close() using wrong attribute names (_sync_loop/_sync_thread
  instead of _async_loop/_async_thread), which prevented cleanup from ever
  stopping the background event loop and thread
- Raise RuntimeError in get_current_gee_interface/get_current_drive_interface
  when SessionManager is active but no session exists, instead of silently
  falling back to shared process-level credentials in multi-user deployments
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves Solara session lifecycle handling in pysepal to prevent per-render session leaks, ensure GEEInterface background resources are actually cleaned up, and avoid silently falling back to shared process credentials when a per-kernel session is expected.

Changes:

  • Make SessionManager.create_session() idempotent per kernel to prevent recreating interfaces on re-renders.
  • Fix GEEInterface.close() cleanup guards to reference the correct async loop/thread attributes.
  • Raise RuntimeError in Solara contexts when no per-kernel session exists (instead of falling back to shared credentials).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
pysepal/solara/utils.py Raises explicit errors when session manager is active but no kernel session exists; keeps fallback for non-Solara contexts.
pysepal/solara/session_manager.py Adds an idempotency guard to avoid recreating sessions for the same kernel.
pysepal/scripts/gee_interface.py Corrects close() to stop/close the async loop and join the correct background thread.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Convert kernel_id to str in get_kernel_id() so the return type
  matches the Dict[str, ...] type hints and method signatures
- Extend test_close to verify _async_thread is stopped and
  _async_loop is closed after close(), preventing regression
  of the thread/loop leak fix
@dfguerrerom dfguerrerom merged commit b24242d into main Mar 18, 2026
8 checks passed
@dfguerrerom dfguerrerom deleted the fix/session-lifecycle-bugs branch March 18, 2026 10:31
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.

2 participants