On 8 February 2016, Bram Moolenaar <b...@moolenaar.net> wrote:
> 
> Thanks for the feedback.  I think it's time to sketch the upcoming work.
> It appears some thought that sockets was the end of it, that's not so.
> 
> 
> For jobs the most useful are probably:
> - A deamon, serving several Vim instances, connect by socket.
> - One server working with one Vim instance, asynchronously.
> - A server performing some work for a short time, asynchronously.
> - Running a filter, synchronously (existing functionality)
> 
> A channel can communicate over:

    I don't really understand what problem do channels solve, or where
is all this heading.  Thus I'll refer mostly to jobs below, and I'll
comment only on a few implementation details for channels.

> - A socket (what ch_open() currently does)
> - A pipe (only possible with an associated job) connected to
>   stdin/stdout/stderr.

    There are also UNIX domain sockets (a.k.a. named pipes), which you
get essentially for free once you have the code for INET sockets.  They
are as efficient as (unnamed) pipes.  The code is already there, but
it's mutually exclusive with INET sockets.  I don't think there is any
reason why the two can't coexist as separate mechanisms.

[...]
> Some combinations are likely to be most useful.  I heard some people
> mention using a server over pipes to write a message to and call a
> callback when the response is received.  I assume this would work best
> with NL separated messages.
>
> Using pipes only works when starting a job.  Thus these are closely
> coupled.

    As you say, getting a program's output with callbacks over pipes
only works for jobs.  The main applications to this are:

(1) running something like make in background
(2) running a slow linter in background.

    With (1) we care to be notified when make is done, and its exit
code.  We care about the output only if there have been errors (I'm
simplifying, of course).  We don't really care what's going on before
make is finished.

    With (2) we care to be notified about lint messages as soon as the
linter prints them, so that we can highlight syntax errors on the fly,
and perhaps also update a quickfix list.  That's the main point of
having callbacks for the job's stdout and stderr.  It's probably safe to
assume the output to consist of lines of text.

    Both (1) and (2) are short-lived processes: they might be slow
anough to make running them in foreground annoying, but we expect them
to be finished (one way or another) when Vim exits.

    Starting a (presumably long-lived) server from Vim on the other hand
is a very different animal.  A server might print things like error
messages before it goes to background.  After that it isn't supposed
to print anything or need output from stdin (doing that would rise a
signal).  A server in background is supposed to communicate with other
processes only though a socket (INET, or UNIX domain).

> Some parts that we still need that require some thougths:
> 
> - Communicating over a socket requires knowing the port number.  For a
>   deamon this would be a known number.  For a server started by Vim it's
>   best to let the server pick an available port.  Then how does it tell
>   Vim what port it picked?  In test_channel we write the port number in
>   a file.  That's not ideal, but perhaps there is no better solution.
>   Having Vim pick a free port and pass it to the server has race conditions
>   (but it might still be an acceptable solution).

    Communicating with a remote server requires a known address, and a
known port.  Remote servers are not started by Vim though.

    Servers started by Vim run on the local machine, and thus can use
UNIX domain sockets instead of INET.  A path pointing to an unique named
pipe could be passed on to the server as a shared meeting point.

> - When starting a job, where does it's stdin/stdout/stderr go?
>   Possibly the same terminal as Vim, a newly started terminal, a file or
>   /dev/null.  No, running a terminal inside Vim is not an option.  But
>   we could write stdout/stderr into a buffer.

    The answer depends on whether the job is a daemon, or a short-lived
process.  In the former case, as I said, we only need to catch messages
at startup (after that stdin, stdout, and stderr should be closed).

    In the later case I think the output should go to the callback
functions.  Default callback function could just send everything to
/dev/null.  And if the user cares to print the output to the terminal
she could override the callbacks with echo or echomsg.  No need to make
any special cases for it in Vim.

    A further difference between long-lived and short-lived processes is
the way process groups are handled.  For short-lived processes, the
sequence should be something like this:

- fork()
- in the child: exec()
- in the parent: install a SIGCHLD and waitpid()

    For daemons the sequence should be:

- fork()
- in the child: setsid(), fork() again, and exit
- in the second child: exec()
- in the parent: blocking waitpid().

    To kill the group of a daemon, you need to kill() the negated PID of
the _first_ child, because that's the session leader.

[...]
> For {options} the main thing we're missing is what to do with
> stdin/stdout/stderr:
>       "term": "pty"               // use current terminal
>       "term": "open"              // start a terminal
> This would result in stdin/stdout/stderr to connect to the terminal,
> unless specified otherwise.  Except that reading from the current
> terminal won't happen (Vim is reading that).
[...]

    Why is it important for the job to be able to access a pty?

    /lcd

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui