Re: [PATCH 03/10] hook: convert 'post-rewrite' hook in sequencer.c to hook.h
- From
- Phillip Wood <phillip.wood123@gmail.com>
- Date
- Sep 29, 2025, 10:11 UTC
- Message-ID
- <991b43cb-72bb-441a-bd42-2091bb31de06@gmail.com>
- In-Reply-To
- <87zfahmcqi.fsf@collabora.com>
Hi Adrian
On 26/09/2025 16:53, Adrian Ratiu wrote:
Show 6 quoted lines
> On Fri, 26 Sep 2025, Phillip Wood <phillip.wood123@gmail.com> wrote: >> On 25/09/2025 13:53, Adrian Ratiu wrote: > > I actually thought about putting pipe_from_strbuf() into hook.c or > someplace similar because it's a generic utility function, however this > is the only hook which needs it, so I've left it in sequencer.c.
Yes, I was surprised that was the only place we ended up needing that function. I think it makes sense to leave it where it is if that's the only place that needs it.
Show 19 quoted lines
>> Why are we running the hook if there is nothing to pass to it? > > run-commands has a ppoll loop which calls the stdin feed callback > (pipe_from_stdbuf in this case) repeatedly until it signals reading is > finished by return 1; > > Now that I look again at this code, I made the mistake of assuming it > needs to work recursively: > 1. write the strbuf > 2. reset the strbuf (return 0) > 3. next callback sees the strbuf is empty and stops the loop > (return 1) > > The line you're asking asking here is actually step 3. :) > > This all can be simplified by writing just once and returning 1 > immediately since it's just a simple strbuf to write to stdin. > > We still need to keep the pointer null check though, just in case.
We should make that a BUG() I think
Show 13 quoted lines
>>> + ret = write_in_full(hook_stdin_fd, to_pipe->buf, to_pipe->len); >> >> This will block until the hook has read all of the input. Unless the >> hook drains and closes stdin before it does anything else it will >> block the parallel execution of other hooks. > > I double checked the write_in_full / xwrite implementations. :) > > Sorry for the wall of text btw, I try to explain as best I can. > > I think it blocks only if/when the stdin fd pipe is full, which can't > happen in this specific instance because the strbuf data is small, so > the write_in_full() call just writes all it has, then returns.
Oh sorry, I'd forgotten this was just used on a short buffer, and not used when we're rebasing. Good point, it should be fine.
Show 23 quoted lines
> In other words, the most important aspect I think is how much data we > are writing to the pipe in every single callback call. > > The idea of these callbacks is to write small chunks of data at a time, > then switch context: it's usually the child hook processes which end up > blocking for their stdin input which is fed by the parent which > multiplexes between the parallel processes. > > Of course, a balance needs to be found: I've noticed, in other hooks, > that if we write too small chunks of data in each callback, we > unnecessarily increase wait times for hooks. > > This can be seen especially in hooks like post-receive which can get a > lot of data: if we feed one line at a time and let's say run-command's > ppoll loop adds 100ms delay between callbacks, then from 7-800 ms we end > up with something like 90 seconds! > > Of course that is a pathological case and the solution there is to batch > more data in a single callback write. I've actually batched 500 lines in > every write for those update hooks (we can do more or less). > > None of this is set in stone and can be changed. What I tried is to get > similar performance with what we had before these callbacks.
That's great, getting a good balance between not blocking for too long and doing a reasonable amount of work in each call to the callback sounds like a good plan.
Thanks
Phillip