Re: [BuildStream] Proposal: Moving UI into a subprocess



# Tldr: 

Based on discussion that happened on IRC, there seems to be a
vague agreement towards the approach (originally suggested by Tristan
in [0]) of having the UI run in the main `bst` process, with `Stream`
running in a subprocess, assuming we can make signal handling and the
interactive shell both work together nicely. 

I've attempted to articulate in a bit more detail what I think this
approach will look like, and a couple of possible approaches to handle
the interactive shell. 


# The process model

The front-end would remain in the parent process. Each of the main
`Stream` entry points would be spawned into a separate process. This
subprocess would call `setsid` to ensure that signals are received and
handled only by the front-end process. I'll add some more detail on
this bellow.


# Message handling

The message handler in `Context` will send messages over a queue to the
front-end to handle. Currently, the front-end uses global state to gain
some of the information it renders. After the split, all state needed
by the front-end will be passed as explicit parameters of each `Message`
object (with the exception of any BuildStream configuration, which
will be still loaded and available before the `Stream` process is
spawned and therefore available to the front-end without any changes
needed).


# Signal handling

All signals will be caught by the front-end process. The font-end will
be responsible for terminating/suspending/resuming the `Stream` process
as appropriate. Although I'm still a bit hazy on the implementation
details here, I imagine this will work in a very similar way to how we
currently interact with scheduler jobs and will reuse much of the same
code.


# Interactive UI prompts

The front-end will provide a service which can called to display
interactive prompts. I think this would work something like:

0) `Stream` process sends a message to the front-end saying "please
   display this interactive prompt" 

1) Front-end stops displaying new messages, queuing them up for later 

2) Front-end displays prompt

3) Front-end waits for input which it then passes back to the
   `Stream` process 

4) `Stream` process does any necessary input
   validation

5) If the input is valid:
   * the `Stream` sends message back to accept the provided value
   * The front-end resumes displaying the queued messages
6) If the input is invalid:
   * The `Stream` sends a message back to the front-end rejecting the
     returned value, with an optional helpful error message.
   * The front-end will display the error message if provided
   * Go back to 3

I would imagine this service would be accessed via the context


# The Interactive shell

As pointed out by Tristan, calling `setsid` in the `Stream` process means 
the `Stream` is not in the process group which owns the terminal. As a
result, it wouldn't be easy (or possible?) to have a shell created in
the `Stream` process take over the terminal.

One approach I think would circumvent this limitation would be for
the front-end to provide an API along the lines of
execute_in_foreground, this would do the specified work in the
front-end process, taking over the terminal while it it running. This
would:
* pause the displaying of messages, allowing any new messages to queue
  up.
* execute the given work in the front-end process
* pass any return value back to the calling process
* Continue printing queued messages 

Another approach would be to simply special case the `Stream.shell`
method, so that it does not run in a subprocess. The shell only
displays loading and staging messages and as so far as I can see will
never be rendering a large number of messages. While I'm not really a
fan of special casing one of the `Stream` methods, this would have the
advantage of reducing the complexity of the implementation.

What do people think?


Cheers,
Phil

[0] https://mail.gnome.org/archives/buildstream-list/2019-May/msg00015.html
-- 
Phil Dawson, Software Engineer                          Codethink Ltd
https://www.codethink.co.uk/          
We respect your privacy. See https://www.codethink.co.uk/privacy.html


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]