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 RFC for server boot logic #20

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

jamshark70
Copy link

@jamshark70 jamshark70 commented Sep 12, 2022

Summary

I propose to replace the current server boot logic with a state-machine approach. At the same time, it is an opportunity to reconsider the various server-initialization issues, and streamline and standardize.

Motivation

Server boot logic has been a thorny problem for years. Even after multiple attempts to fix it, there remain edge cases, particularly with respect to remote server connection.

At least these, perhaps others.

There is also not a clear, central place to observe the boot/init process. The process is divided somewhat haphazardly between Server and ServerStatusWatcher methods and is not at all straightforward to trace.

Specification

  1. Clarify the roles of Server and ServerStatusWatcher. I am leaning toward Server for user-facing control, and ServerProcess to manage a specific server process. A ServerProcess would be created when booting, or connecting to a remote server, and destroyed when that process exits. (Here, we might want a ServerRemoteProcess as well.)
    • Currently, we have an awkward 1:1 mapping between Server and ServerStatusWatcher, which manifests as a lack of clarity in these classes' responsibilities.
    • I would propose a 1:M relationship between a Server object and the processes that may exist for it. We would not allow multiple "running" server processes for one Server object, but, for instance, server.reboot may be simplified by switching out ServerProcess objects.
  2. Because node, buffer, bus allocators are intimately connected to the server process's state, probably these should be managed in ServerProcess.
  3. ServerProcess could centralize and streamline by borrowing the idea of a state machine. It would implement status_(newState) where newState is a symbol descriptor. Each status change would perform initialization or shutdown tasks (below).

A sketch of statuses and permitted state transitions:

  • 'idle' state (no server process) may go to 'booting'
    • Or, Server.remote could go directly to 'handshake'
  • 'booting' may go to:
    • 'handshake'
    • 'idle' (server process terminated for some reason)
  • 'handshake' may go to:
    • 'initialize'
    • 'idle' (server process terminated for some reason)
  • 'initialize' (new allocators, ServerBoot, ServerTree etc.) may go to:
    • 'running'
    • 'idle' (server process terminated for some reason)
  • 'running' may go to:
    • 'quitting'
    • 'idle' (server process terminated for some reason)
  • 'quitting' may go to:
    • 'idle' (success)

Upon a second read of this, I would add an 'unresponsive' state. If the aliveThread doesn't get a response, status = \unresponsive (and perhaps ignore these during init states). If the process shuts down (detected by unixCmd's action function), then status = \idle (and a transition into idle status is normal only from 'quitting' status -- otherwise the user would get a warning that the server crashed).

Significant advantages would be 1/ we always know the current status, 2/ it's easy to evaluate whether the process flow is normal or abnormal, based on the previous state and the new state, and 3/ state changes would be centralized in one place.

I may have missed some details -- comments are more than welcome.

Drawbacks

I welcome discussion on this.

Unresolved Questions

Did I miss any statuses?

Did I overlook any subtleties of Server.remote?

@dyfer
Copy link
Member

dyfer commented Sep 12, 2022

Thanks @jamshark70
For reference: I just came across https://github.com/supercollider/supercollider/wiki/%5BWIP%5D-notes-for-refactoring-the-server-implementation - I haven't fully digested it, but I think it may contain some relevant points on the matter.

@smrg-lm
Copy link

smrg-lm commented Sep 12, 2022

Just to contribute a thought to this. The current implementation doesn't make a clear difference between the language as a process that creates another process and the language as a client that connects to a, possibly remote, server. I gave it some thoughts in the past and that was a key problem because process instantiation errors can't be caught and described and they might mix with connection issues. For this the server process could return different errnos (this was discussed in the past, I don’t remember where) to be handled.

@jamshark70
Copy link
Author

The current implementation doesn't make a clear difference between the language as a process that creates another process and the language as a client that connects to a, possibly remote, server.

A ServerProcess object could help with this by subclassing: ServerProcess, ServerInternalProcess, ServerRemoteProcess.

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.

3 participants