about summary refs log tree commit homepage
path: root/lib/PublicInbox/Git.pm
DateCommit message (Collapse)
2021-10-24git: avoid Perl5 internal scratchpad target cache
Creating a scalar ref directly off substr() seemed to be causing the underlying non-ref scalar to end up in Perl's scratchpad. Assign the substr result to a local variable seems sufficient to prevent multi-megabyte SVs from lingering indefinitely when a read-only daemon serves rare, oversized blobs.
2021-10-23git: simplify local_nick, avoid "foo.git.git"
We need to use a non-greedy regexp to avoid capturing the ".git" suffix in the pathname before blindly appending our own.
2021-10-15git: cat-file --batch are their own pgrp
We want these long-lived processes to die naturally when their parent dies. Hopefully this improves graceful shutdown for -extindex because I'm interrupting a lot of reindexing...
2021-10-15git: ->fail invokes current callback
While we try to invoke all pending callbacks to force error handling, the current callback wasn't getting invoked on invoked on async_abort if my_read/my_readline failed.
2021-10-15git: async_err shows retried requests properly
We make $req a reference upon retrying, but "SCALAR(...)" in error messages isn't helpful, so dereference the scalar ref.
2021-10-08git: fatalize async callback errors by default
This should help us catch BUG: errors (and then some) in -extindex and other read-write code paths. Only read-only daemons should warn on async callback failures, since those aren't capable of causing data loss.
2021-10-08git: async_abort includes --batch-check requests
We need to abort both check-only and cat requests when aborting, since we'll be aborting more aggressively in in read-write paths.
2021-10-01inbox: keep DB handles if git processes are live
Having git processes outlive DB handles is likely to hurt from a fragmentation perspective if the DB handle needs to be recreated immediately due to a git->cat_async callback. So only unref DB handles when we're sure there's no live git users left, otherwise check the inodes. We'll also avoid needless localization checks in git->cleanup and make the return value more obvious since the pid fields are unconditionally deleted nowadays.
2021-09-29git: shorten --git-dir= in CLI with chdir in spawn
Long pathnames are difficult to read and distinguish in ps(1) output. Deep paths can also slow down pathname resolution when dealing with loose objects, so we put "cat-file --batch" deeper into the directory tree. Since v2 processes are in the form of $INBOXDIR/all.git, keep the basename of $INBOXDIR in --git-dir= so it's easy to distinguish between processes just by looking at ps(1). While "git -C" also exists, it's only present in git 1.8.5+. We also need to keep in mind the "directory" pointed to by --git-dir= need not be a directory (nor a symlink pointing to one). This reduces pathname resolution overhead for v1 and v2 inbox git processes, but unfortunately not for extindex since that needs to store alternates as absolute paths.
2021-09-29inbox: rewrite cleanup to be more aggressive
Avoid relying on a giant cleanup hash and instead use the new DS->add_uniq_timer API to amortize the pause times associated with having to cleanup many inboxes. We can also use smaller intervals for this, as well. We now discard SQLite DB handles at cleanup. Each of these can use several megabytes of memory, which adds up with hundreds/thousands of inboxes. Since per-inbox access intervals are unpredictable and opening an SQLite handle is relatively inexpensive, release memory more aggressively to avoid the heap having to hit swap.
2021-09-23daemons: revamp periodic cleanup task
Neither Inboxes nor ExtSearch objects were retrying correctly when there are live git processes, but the inboxes were getting rescanned for search or other reasons. Ensure the scan retries eventually if there's live processes. We also need to update the cleanup task to detect Xapian shard count changes, since Xapian ->reopen is enough to detect any other Xapian changes. Otherwise, we just issue an inexpensive ->reopen call and let Xapian check whether there's anything worth reopening. This also lets us eliminate the Devel::Peek dependency.
2021-09-23gcf2 + extsearch: check for unlinked files on Linux
Check for unlinked mmap-ed files via /proc/$PID/maps every 60s or so. ExtSearch (extindex) is compatible-enough with Inbox objects to be wired into the old per-inbox code, but the startup cost is projected to be much higher down the line when there's >30K inboxes, so we scan /proc/$PID/maps for deleted files before unlinking. With old Inbox objects, it was (and is) simpler to just kill processes w/o checking due to the low startup cost (and non-portability of checking). Reported-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org> Link: https://public-inbox.org/meta/20210921144754.gulkneuulzo27qbw@meerkat.local/
2021-09-13use POSIX::PIPE_BUF (instead of _POSIX_PIPE_BUF)
PIPE_BUF accounts for Linux being 4096 (and presumably other OSes differing), while _POSIX_PIPE_BUF is the minimum 512 value.
2021-09-12manifest.js.gz: avoid long-lived per-epoch cat-file processes
When generating per-inbox manifests, we were forgetting to cleanup per-epoch "git cat-file --batch" processes. Our previous method of generating modified times was also stupidly inefficient, so replace the pipeline with a single "git for-each-ref" invocation.
2021-05-09git: fix numerous bugs in git_quote and git_unquote
git always quotes with leading zeros to ensure the octal representation is 3 characters long. We enforce that to match low ASCII characters (e.g. [x01-\x06]) that don't need the range provided by 3 characters. git_unquote now does a single pass so it won't get fooled by decoded backslashes into parsing a digit as an octal character. git_unquote is also capped to "\377" so we don't overflow a byte.
2021-03-30git: local_nick: handle trailing or redundant '/' in git_dir
Some cgit configs use trailing slashes in pathnames which we preserve internally. Before this change, trailing slashes in cgit config files was causing ViewVCS (SolverGit) output to show up as "???" for coderepos without cgitUrl configured.
2021-03-17www: improve visibility of coderepos
By adding "+code" next to "mirror" at the top next to the search box. Instead of showing "/path/to/$FOO", showing "$FOO.git" makes it more obvious we're talking about a git repo, here, instead of some random directory.
2021-03-16git: drop async_prefetch method
That logic is inlined directly into git_async_prefetch in GitAsyncCat and I don't see it being useful outside of a DS event loop.
2021-02-10git: ->qx: respect caller's $/ in array context
This could lead to bad results when doing ls-tree -z for v2 import in case there's multiple files. In any case, the `local $/ = "\0"' in Import.pm is also eliminated to reduce potential confusion and surprises.
2021-02-08search: use one git-rev-parse process for all dates
This is necessary to avoid slowdowns with pathological cases with many dates in the query, since each rev-parse invocation takes ~5ms. This is immeasurably slower with one open-ended range, but already faster with any closed range featuring two dates which require parsing via git.
2021-02-08git: implement date_parse method
Users are expected to be familiar with git's "approxidate" functionality for parsing dates, so we'll expose that in our UIs. Xapian itself has limited date parsing functionality and I can't expect users to learn it. This takes around 4-5ms on my aging workstation, so it'll probably be made acceptable for the WWW UI, even. libgit2 has a git__date_parse function which I expect to have less overhead, but it's only for internal use at the moment.
2021-01-30git: synchronous cat_file may return type and OID
Instead of forcing callers to set a variable to write into, we'll just rely on wantarray.
2021-01-02git: manifest_entry: use ProcessPipe via popen_rd
Only saves us one line of code, but that's better than nothing.
2021-01-02git: qx: waitpid synchronously via ProcessPipe->CLOSE
If we're using ->qx, we're operating synchronously anyways, so there's little point in relying on the event loop for waitpid.
2021-01-01lei_store: quiet down "git var" failures
$git->qx and $git->popen now $env and $opt for redirects like lower-level popen_rd. This may be beneficial in other places.
2021-01-01update copyrights for 2021
Using "make update-copyrights" after setting GNULIB_PATH in my config.mak
2021-01-01avoid calling waitpid from children in DESTROY
Objects with DESTROY callbacks get propagated to children, so we must be careful to not invoke waitpid from children on their sibling processes. Only parents (and their parents...) can reap child processes.
2021-01-01use PublicInbox::DS for dwaitpid
This simplifies our code and provides a more consistent API for error handling. PublicInbox::DS can be loaded nowadays on all *BSDs and Linux distros easily without extra packages to install. The downside is possibly increased startup time, but it's probably not as a big problem with lei being a daemon (and -mda possibly following suite).
2020-12-28git: qx: avoid extra "local" for scalar context case
We can use the ternary operator to avoid an early return, here
2020-11-30git: ensure subclassed ->fail gets called
Some of these changes may not be strictly necessary, but it makes code easier to maintain and change. Hackers using/modifying this code will no longer wonder if a particular callsite needs to care about subclasses or not.
2020-11-30git: set non-blocking flag in case of other bugs
This makes GitAsyncCat more resilient to bugs in Gcf2 or even git-cat-file itself. I noticed -imapd stuck on read(2) from the Gcf2 pipe, so there may be a bug somewhere in Gcf2 or PublicInbox::Git. This should make us more resilient to them and hopefully help us notice and fix them.
2020-11-24git: add manifest_entry method
We'll be using this for MiscIdx and pre-generating the necessary JSON for manifest.js.gz, so make it easier to share code for generating per-repo JSON entries for grokmirror.
2020-10-17git: introduce async_wait_all
->cat_async and ->check_async may trigger each other (in future callers) while waiting, so we need a unified method to ensure both complete. This doesn't affect current code, but allows us to slightly simplify existing callers.
2020-10-16git: async: loop inflight checks for nested callbacks
We need to loop the inflight check for nested callback invocations to ensure we don't clog the pipe that feeds `git cat-file'. This bug was obscured by the fact that we're already accounting for 64-char git OIDs with SHA-256 in the pipe space calculation; perhaps we shouldn't do that.
2020-10-16git: *_async: support nested callback invocations
For external indices, we'll need to support nested cat_async invocations to deduplicate cross-posted messages. Thus we need to ensure we do not clobber the {inflight*} queues while stepping through and ensure {cat_rbuf} is stored before invoking callbacks. This fixes the ->cat_async-only case, but does not yet account for the mix of ->check_async interspersed with ->cat_async calls, yet. More work will be needed on that front at a later date.
2020-10-16git: ensure ->destroy clobbers check_async read buffer
It's currently not a problem as ->destroy doesn't happen for no reason, we'll need to ensure future uses of ->destroy correctly discard the check_async buffer.
2020-09-19gcf2: wire up read-only daemons and rm -gcf2 script
It seems easiest to have a singleton Gcf2Client client object per daemon worker for all inboxes to use. This reduces overall FD usage from pipes. The `public-inbox-gcf2' command + manpage are gone and a `$^X' one-liner is used, instead. This saves inodes for internal commands and hopefully makes it easier to avoid mismatched PERL5LIB include paths (as noticed during development :x). We'll also make the existing cat-file process management infrastructure more resilient to BOFHs on process killing sprees (or in case our libgit2-based code fails on us). (Rare) PublicInbox::WWW PSGI users NOT using public-inbox-httpd won't automatically benefit from this change, and extra configuration will be required (to be documented later).
2020-09-19gcf2: require git dir with OID
This amortizes the cost of recreating PublicInbox::Gcf2 objects when alternates change in v2 all.git.
2020-09-19gcf2: transparently retry on missing OID
Since we only get OIDs from trusted local data sources (over.sqlite3), we can safely retry within the -gcf2 process without worry about clients spamming us with requests for invalid OIDs and triggering reopens.
2020-09-16treewide: relax allow >=40 chars for git OID
This will help with eventual git SHA-256 transitions.
2020-08-27git: show more context info on failures
I'm seeing "read: Connection timed out" from in my syslog from -httpd. The fail() calls in PublicInbox::Git seems to be the only code path of ours which could trigger it... ETIMEDOUT shouldn't happen on pipes, only sockets; and all of our socket operations are non-blocking. So this could be cgit-wwwhighlight-filter.lua, but that's connecting over localhost, though on fairly loaded HW.
2020-07-26imap: introduce and use Git->async_prefetch
We can keep the git process more active by sending another request to it while fetch_run_ops() is running. This parallelization speeds up mutt's initial FETCH for headers by around ~35%(!).
2020-07-25searchidx: support async git check
This allows v1 indexing to run while the `cat-file --batch-check' process is waiting on high-latency storage.
2020-07-06git: use v5.10.1, parent.pm and Time::HiRes::stat
parent.pm is leaner than base.pm, and Time::HiRes::stat is more accurate, so take advantage of these Perl 5.10+-isms since it's been over a year since we left 5.8 behind.
2020-06-25git_async_cat: remove circular reference
While this circular reference was carefully managed to not leak memory; it was still triggering a warning at -imapd/-nntpd shutdown due to the EPOLL_CTL_DEL op failing after the $Epoll FD gets closed. So remove the circular reference by providing a ref to `undef', instead.
2020-06-13git: async: automatic retry on alternates change
This matches the behavior of the existing synchronous ->cat_file method. In fact, ->cat_file now becomes a small wrapper around the ->cat_async method.
2020-06-13git: move async_cat reference to PublicInbox::Git
Trying to avoid a circular reference by relying on $ibx object here makes no sense, since skipping GitCatAsync::close will result in an FD leak, anyways. So keep GitAsyncCat contained to git-only operations, since we'll be using it for Solver in the distant feature.
2020-06-13git: cat_async: provide requested OID + "missing" on missing blobs
This will make it easier to implement the retries on alternates_changed() of the synchronous ->cat_file API.
2020-06-13git: idle rbuf for async
We do this for the C10K-oriented HTTP/NNTP/IMAP processes, and we may support thousands of git-cat-file processes in the future.
2020-06-13imap: use git-cat-file asynchronously
This ought to improve overall performance with multiple clients. Single client performance suffers a tiny bit due to extra syscall overhead from epoll. This also makes the existing async interface easier-to-use, since calling cat_async_begin is no longer required.