Conversation
|
PR 766 is based upon v2.29.0 whereas 717 was based on v2.28.0+strvec. |
For the record, if you hit Edit next to the PR title, it lets you re-target the PR to another branch. |
03cfed4 to
18ebeea
Compare
bd48cf2 to
55c2bc8
Compare
55c2bc8 to
a1b15fb
Compare
|
This force-push moves the base to v2.30.0. |
|
/submit |
|
Submitted as pull.766.git.1610465492.gitgitgadget@gmail.com To fetch this version into To fetch this version to local tag |
| @@ -0,0 +1,31 @@ | |||
| simple-ipc API | |||
There was a problem hiding this comment.
On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this):
On Tue, Jan 12 2021, Jeff Hostetler via GitGitGadget wrote:
> From: Jeff Hostetler <jeffhost@microsoft.com>
>
> Brief design documentation for new IPC mechanism allowing
> foreground Git client to talk with an existing daemon process
> at a known location using a named pipe or unix domain socket.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
> ---
> Documentation/technical/api-simple-ipc.txt | 31 ++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
> create mode 100644 Documentation/technical/api-simple-ipc.txt
>
> diff --git a/Documentation/technical/api-simple-ipc.txt b/Documentation/technical/api-simple-ipc.txt
> new file mode 100644
> index 00000000000..920994a69d3
> --- /dev/null
> +++ b/Documentation/technical/api-simple-ipc.txt
> @@ -0,0 +1,31 @@
> +simple-ipc API
> +==============
> +
> +The simple-ipc API is used to send an IPC message and response between
> +a (presumably) foreground Git client process to a background server or
> +daemon process. The server process must already be running. Multiple
> +client processes can simultaneously communicate with the server
> +process.
> +
> +Communication occurs over a named pipe on Windows and a Unix domain
> +socket on other platforms. Clients and the server rendezvous at a
> +previously agreed-to application-specific pathname (which is outside
> +the scope of this design).
> +
> +This IPC mechanism differs from the existing `sub-process.c` model
> +(Documentation/technical/long-running-process-protocol.txt) and used
> +by applications like Git-LFS because the server is assumed to be very
s/to be very long running/to be a long running/, or at least "s/to be
very/to be a very/.
> +long running system service. In contrast, a "sub-process model process"
> +is started with the foreground process and exits when the foreground
> +process terminates. How the server is started is also outside the
> +scope of the IPC mechanism.
> +
> +The IPC protocol consists of a single request message from the client and
> +an optional request message from the server. For simplicity, pkt-line
> +routines are used to hide chunking and buffering concerns. Each side
> +terminates their message with a flush packet.
> +(Documentation/technical/protocol-common.txt)
> +
> +The actual format of the client and server messages is application
> +specific. The IPC layer transmits and receives an opaque buffer without
> +any concern for the content within.
|
User |
|
On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this): |
|
User |
|
On the Git mailing list, Jeff Hostetler wrote (reply to this): |
|
User |
|
On the Git mailing list, Junio C Hamano wrote (reply to this): |
|
On the Git mailing list, Jeff Hostetler wrote (reply to this): |
|
On the Git mailing list, Jeff Hostetler wrote (reply to this): |
|
On the Git mailing list, Junio C Hamano wrote (reply to this): |
| @@ -196,7 +196,7 @@ int packet_write_fmt_gently(int fd, const char *fmt, ...) | |||
|
|
|||
There was a problem hiding this comment.
On the Git mailing list, Jeff King wrote (reply to this):
On Tue, Jan 12, 2021 at 03:31:23PM +0000, Jeff Hostetler via GitGitGadget wrote:
> Teach packet_write_gently() to use a stack buffer rather than a static
> buffer when composing the packet line message. This helps get us ready
> for threaded operations.
Sounds like a good goal, but...
> static int packet_write_gently(const int fd_out, const char *buf, size_t size)
> {
> - static char packet_write_buffer[LARGE_PACKET_MAX];
> + char packet_write_buffer[LARGE_PACKET_MAX];
> size_t packet_size;
64k is awfully big for the stack, especially if you are thinking about
having threads. I know we've run into issues around that size before
(though I don't offhand recall whether there was any recursion
involved).
We might need to use thread-local storage here. Heap would also
obviously work, but I don't think we'd want a new allocation per write
(or maybe it wouldn't matter; we're making a syscall, so a malloc() may
not be that big a deal in terms of performance).
-Peff
There was a problem hiding this comment.
On the Git mailing list, Jeff Hostetler wrote (reply to this):
On 1/13/21 8:29 AM, Jeff King wrote:
> On Tue, Jan 12, 2021 at 03:31:23PM +0000, Jeff Hostetler via GitGitGadget wrote:
>
>> Teach packet_write_gently() to use a stack buffer rather than a static
>> buffer when composing the packet line message. This helps get us ready
>> for threaded operations.
>
> Sounds like a good goal, but...
>
>> static int packet_write_gently(const int fd_out, const char *buf, size_t size)
>> {
>> - static char packet_write_buffer[LARGE_PACKET_MAX];
>> + char packet_write_buffer[LARGE_PACKET_MAX];
>> size_t packet_size;
>
> 64k is awfully big for the stack, especially if you are thinking about
> having threads. I know we've run into issues around that size before
> (though I don't offhand recall whether there was any recursion
> involved).
>
> We might need to use thread-local storage here. Heap would also
> obviously work, but I don't think we'd want a new allocation per write
> (or maybe it wouldn't matter; we're making a syscall, so a malloc() may
> not be that big a deal in terms of performance).
>
> -Peff
>
Good point.
I'll look at the callers and see if I can do something safer.
Jeeff
|
User |
|
On the Git mailing list, Jeff King wrote (reply to this): |
unix-socket.c
Outdated
| @@ -121,3 +121,42 @@ int unix_stream_listen(const char *path) | |||
| errno = saved_errno; | |||
There was a problem hiding this comment.
On the Git mailing list, Jeff King wrote (reply to this):
On Tue, Jan 12, 2021 at 03:31:29PM +0000, Jeff Hostetler via GitGitGadget wrote:
> From: Jeff Hostetler <jeffhost@microsoft.com>
>
> Create a gentle version of `unix_stream_listen()`. This version does
> not call `die()` if a socket-fd cannot be created and does not assume
> that it is safe to `unlink()` an existing socket-inode.
The existing one is meant to be gentle. Maybe it is worth fixing it
instead.
> `unix_stream_listen()` uses `unix_stream_socket()` helper function to
> create the socket-fd. Avoid that helper because it calls `die()` on
> errors.
Yeah, I think this is just a bug. My thinking in the original was that
socket() would basically never fail. And it generally wouldn't, but
things like EMFILE do happen. There are only two callers, and both would
be one-liners to propagate the error up the stack.
> `unix_stream_listen()` always tries to `unlink()` the socket-path before
> calling `bind()`. If there is an existing server/daemon already bound
> and listening on that socket-path, our `unlink()` would have the effect
> of disassociating the existing server's bound-socket-fd from the socket-path
> without notifying the existing server. The existing server could continue
> to service existing connections (accepted-socket-fd's), but would not
> receive any futher new connections (since clients rendezvous via the
> socket-path). The existing server would effectively be offline but yet
> appear to be active.
The trouble here is that one cannot tell if the existing file is active,
and you are orphaning an existing server, or if there is leftover cruft
from an exited server that did not clean up after itself (you will get
EADDRINUSE either way).
Handling those cases (and especially doing so in a non-racy way) is
probably outside the scope of unix_stream_listen(), but it makes sense
for this to be an option. And it looks like you even made it so here,
so unix_stream_listen() could just become a wrapper that sets the
option. Or since there is only one caller in the whole code-base,
perhaps it could just learn to pass the option struct. :)
Likewise for the no-chdir option added in the follow-on patch.
> Furthermore, `unix_stream_listen()` creates an opportunity for a brief
> race condition for connecting clients if they try to connect in the
> interval between the forced `unlink()` and the subsequent `bind()` (which
> recreates the socket-path that is bound to a new socket-fd in the current
> process).
I'll be curious to see how you do this atomically. From my skim of patch
10, you will connect to see if it's active, and unlink if it's not. But
then two simultaneous new processes could both see an inactive one and
race to forcefully create the new one. One of them will lose and be
orphaned with a socket that has no filesystem name.
There might be a solution using link() to have an atomic winner, but it
gets tricky around unlinking the old name out of the way. You might need
a separate dot-lock to make sure only one process does the
unlink-and-create process at a time.
-Peff
There was a problem hiding this comment.
On the Git mailing list, Chris Torek wrote (reply to this):
I had saved this to comment on, but Peff beat me to it :-)
On Wed, Jan 13, 2021 at 6:07 AM Jeff King <peff@peff.net> wrote:
> There might be a solution using link() to have an atomic winner, but it
> gets tricky around unlinking the old name out of the way.
You definitely should be able to do this atomically with link(), but
the cleanup is indeed messy, and there's already existing locking
code, so it's probably better to press that into service here.
Chris
|
On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this): |
|
User |
a1b15fb to
1ac56be
Compare
1ac56be to
9cc735d
Compare
|
This patch series was integrated into seen via git@b24af91. |
|
There was a status update about the branch A simple IPC interface gets introduced to build services like fsmonitor on top. Will merge to 'next'. |
|
This patch series was integrated into seen via git@667a6e3. |
|
This patch series was integrated into seen via git@0e46061. |
|
This patch series was integrated into seen via git@1f6aaaa. |
|
There was a status update about the branch A simple IPC interface gets introduced to build services like fsmonitor on top. Expecting an update for SQUASH??? |
|
This patch series was integrated into seen via git@48491b7. |
Create Unix domain socket based implementation of "simple-ipc". A set of `ipc_client` routines implement a client library to connect to an `ipc_server` over a Unix domain socket, send a simple request, and receive a single response. Clients use blocking IO on the socket. A set of `ipc_server` routines implement a thread pool to listen for and concurrently service client connections. The server creates a new Unix domain socket at a known location. If a socket already exists with that name, the server tries to determine if another server is already listening on the socket or if the socket is dead. If socket is busy, the server exits with an error rather than stealing the socket. If the socket is dead, the server creates a new one and starts up. If while running, the server detects that its socket has been stolen by another server, it automatically exits. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Create t0052-simple-ipc.sh with unit tests for the "simple-ipc" mechanism. Create t/helper/test-simple-ipc test tool to exercise the "simple-ipc" functions. When the tool is invoked with "run-daemon", it runs a server to listen for "simple-ipc" connections on a test socket or named pipe and responds to a set of commands to exercise/stress the communication setup. When the tool is invoked with "start-daemon", it spawns a "run-daemon" command in the background and waits for the server to become ready before exiting. (This helps make unit tests in t0052 more predictable and avoids the need for arbitrary sleeps in the test script.) The tool also has a series of client "send" commands to send commands and data to a server instance. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
132b6f3 to
8b5dcca
Compare
|
/submit |
|
Submitted as pull.766.v7.git.1616408989.gitgitgadget@gmail.com To fetch this version into To fetch this version to local tag |
|
This patch series was integrated into seen via git@8652114. |
|
This patch series was integrated into seen via git@d562ddd. |
|
This patch series was integrated into seen via git@17271fa. |
|
There was a status update about the branch A simple IPC interface gets introduced to build services like fsmonitor on top. Will merge to 'next'. |
|
This patch series was integrated into seen via git@3ecd81b. |
|
This patch series was integrated into seen via git@32f3cf4. |
|
This patch series was integrated into next via git@3ebcedf. |
|
This patch series was integrated into seen via git@bc9ebc4. |
|
This patch series was integrated into seen via git@910d4f2. |
|
There was a status update about the branch A simple IPC interface gets introduced to build services like fsmonitor on top. Will merge to 'master'. |
|
This patch series was integrated into seen via git@99e734d. |
|
This patch series was integrated into seen via git@ff338b5. |
|
This patch series was integrated into seen via git@861794b. |
|
This patch series was integrated into next via git@861794b. |
|
This patch series was integrated into master via git@861794b. |
|
Closed via 861794b. |
Here is version V7 of my simple-ipc series. The only change from V6 is to squash in
the CALLOC_ARRAY() suggestion.
$ git range-diff v2.31.0-rc1..pr-766/jeffhostetler/simple-ipc-v6 v2.31.0-rc1..HEAD
1: fe35dc3 = 1: fe35dc3 pkt-line: eliminate the need for static buffer in packet_write_gently()
2: de11b30 = 2: de11b30 pkt-line: do not issue flush packets in write_packetized_*()
3: 3718da3 = 3: 3718da3 pkt-line: add PACKET_READ_GENTLE_ON_READ_ERROR option
4: b43df7a = 4: b43df7a pkt-line: add options argument to read_packetized_to_strbuf()
5: f829feb = 5: f829feb simple-ipc: design documentation for new IPC mechanism
6: 58c3fb7 = 6: 58c3fb7 simple-ipc: add win32 implementation
7: 4e8c352 = 7: 4e8c352 unix-socket: eliminate static unix_stream_socket() helper function
8: 3b71f52 = 8: 3b71f52 unix-socket: add backlog size option to unix_stream_listen()
9: 5972a19 = 9: 5972a19 unix-socket: disallow chdir() when creating unix domain sockets
10: 02c885f = 10: 02c885f unix-stream-server: create unix domain socket under lock
11: 4c21992 ! 11: eee5f47 simple-ipc: add Unix domain socket implementation
@@ compat/simple-ipc/ipc-unix-socket.c (new)
+ pthread_cond_init(&server_data->work_available_cond, NULL);
+
+ server_data->queue_size = nr_threads * FIFO_SCALE;
-+ server_data->fifo_fds = xcalloc(server_data->queue_size,
-+ sizeof(*server_data->fifo_fds));
++ CALLOC_ARRAY(server_data->fifo_fds, server_data->queue_size);
+
+ server_data->accept_thread =
+ xcalloc(1, sizeof(*server_data->accept_thread));
12: 132b6f3 = 12: 8b5dcca t0052: add simple-ipc tests and t/helper/test-simple-ipc tool
Jeff
cc: Ævar Arnfjörð Bjarmason avarab@gmail.com
cc: Jeff Hostetler git@jeffhostetler.com
cc: Jeff King peff@peff.net
cc: SZEDER Gábor szeder.dev@gmail.com
cc: Johannes Schindelin Johannes.Schindelin@gmx.de
cc: Chris Torek chris.torek@gmail.com