Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add module for managing multiple running sessions #3

Merged
merged 4 commits into from
Jan 8, 2021
Merged

Conversation

jonatanklosko
Copy link
Member

@jonatanklosko jonatanklosko commented Jan 8, 2021

Adds SessionSupervisor - a dynamic supervisor that allows for spawning multiple notebook session processes. Each process is assigned a random id and is registered using the :global module.

I also added a basic UI with updates via PubSub.

sessions.mp4

Supervisor.terminate_child(LiveBook.Supervisor, LiveBook.SessionSupervisor)
Supervisor.restart_child(LiveBook.Supervisor, LiveBook.SessionSupervisor)
end)
end
Copy link
Member Author

Choose a reason for hiding this comment

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

Is there any simpler way of cleaning the Supervisor children (and consequently the :global entries), given it's a part of the application supervision tree?

Phoenix.PubSub.subscribe(LiveBook.PubSub, "sessions")
end

session_ids = LiveBook.SessionSupervisor.get_session_ids()
Copy link
Member Author

Choose a reason for hiding this comment

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

Eventually we will be getting more session/notebook data by querying each session process, but I just used ids for now to have some UI.

"""
@spec create_session() :: {:ok, Session.session_id()} | {:error, any()}
def create_session() do
id = UUID.uuid4()
Copy link
Contributor

Choose a reason for hiding this comment

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

This is fine for now but in the future the session id will be something based on the filename.

Copy link
Contributor

Choose a reason for hiding this comment

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

Btw, I wouldn't use an external dep here either. This is likely good enough for random tokens:

:crypto.strong_rand_bytes(20) |> Base.encode32(case: :lower)

Copy link
Member Author

Choose a reason for hiding this comment

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

This is fine for now but in the future the session id will be something based on the filename.

The filename can change while the session is running (or perhaps not be specified at all) and will be just stored in session state. Also people could start multiple sessions by importing the same file. I introduced the id primarily for registering the processes with :global, anything I am missing here?

Copy link
Contributor

Choose a reason for hiding this comment

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

The thing is that sessions can be persisted to disk and when we do so, there is definitely a filename. However, if you want to keep a session in memory only, we would need random session IDs. Sounds good to me, we can revisit this once we have persistence and filenames come more into play.

# Start a fresh SessionSupervisor for each test
Supervisor.terminate_child(LiveBook.Supervisor, LiveBook.SessionSupervisor)
Supervisor.restart_child(LiveBook.Supervisor, LiveBook.SessionSupervisor)
end)
Copy link
Contributor

Choose a reason for hiding this comment

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

I generally prefer to write the tests in a way that it doesn't require the session to be restarted. Luckily you already wrote most tests like this, except for the DynamicSupervisor.which_children(SessionSupervisor) call below, which you can replace by this:

assert List.keymember?(DynamicSupervisor.which_children(SessionSupervisor), pid, 1)

:)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, although create_session returns id rather than pid, so I matched against which_children to get the pid and check if it's correctly registered in the :global module. I tried another approach in this commit by introducing get_session_pid method, which enabled us to still test the same behavior without matching on children. What do you think?

lib/live_book/session.ex Outdated Show resolved Hide resolved
Copy link
Contributor

@josevalim josevalim left a comment

Choose a reason for hiding this comment

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

This looks really good, I have posted some minor comments. Btw, we are still deciding the color palete we will use for Nx, but once we do I will let you know!

@jonatanklosko jonatanklosko merged commit 5cdcb15 into main Jan 8, 2021
@jonatanklosko jonatanklosko deleted the sessions branch January 8, 2021 13:14
@josevalim josevalim mentioned this pull request Nov 10, 2023
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.

None yet

2 participants