Eric Wong [Sat, 26 Dec 2020 12:25:42 +0000 (12:25 +0000)]
eml: fix undefined vars on <Perl 5.28
Encode::MIME::Header::_decode_octets did not correctly default
to Encode::FB_DEFAULT until Encode 2.93 (perl5.git commit
0c541dc5633a341cf44b818014b58e7f8be532e9). Provide the default
again to work with older Perls.
Reported-by: Ali Alnubani <alialnu@nvidia.com>
Link: https://public-inbox.org/meta/DM6PR12MB49106F8E3BD697B63B943A22DADB0@DM6PR12MB4910.namprd12.prod.outlook.com/
Tested-by: Ali Alnubani <alialnu@nvidia.com>
Eric Wong [Sat, 26 Dec 2020 12:30:35 +0000 (12:30 +0000)]
t/config: test --get-urlmatch for git <2.26
While git 1.8.5 learned --get-urlmatch, git did not learn to
match URLs against wildcards until 2.26. So only depend on
1.8.5 for this test since 2.26 is too new.
Reported-by: Ali Alnubani <alialnu@nvidia.com>
Link: https://public-inbox.org/meta/DM6PR12MB49106F8E3BD697B63B943A22DADB0@DM6PR12MB4910.namprd12.prod.outlook.com/
Tested-by: Ali Alnubani <alialnu@nvidia.com>
Eric Wong [Sat, 26 Dec 2020 01:44:36 +0000 (01:44 +0000)]
default to CORE::warn in $SIG{__WARN__} handlers
As with CORE::die and $SIG{__DIE__}, it turns out CORE::warn is
safe to use inside $SIG{__WARN__} handlers without triggering
infinite recursion. So fall back to reusing CORE::warn instead
of creating a new sub.
Eric Wong [Sat, 26 Dec 2020 08:12:52 +0000 (08:12 +0000)]
inbox: name variable for values loop iterator
->on_inbox_unlock callbacks could clobber $_, and this seems to
fix a problem with -extindex --watch failing to index some
inboxes after SIGHUP reload.
Eric Wong [Sat, 26 Dec 2020 09:34:39 +0000 (09:34 +0000)]
inboxidle: avoid needless syscalls on refresh
We don't have to replace a bunch of existing watches
with identical new ones. On Linux with Linux::Inotify2
installed, this avoids a storm of inotify_add_watch(2)
and inotify_rm_watch(2) syscalls on SIGHUP with -imapd
and "-extindex --watch"
Eric Wong [Sat, 26 Dec 2020 05:59:22 +0000 (05:59 +0000)]
inboxidle: clue users into resolving ENOSPC from inotify
It may not be obvious to users a ENOSPC error is from hitting
a (tunable) kernel-imposed limit on inotify watches, and not
some storage device running out of space. Give them a hint
here to reduce our own support burden.
Eric Wong [Fri, 25 Dec 2020 10:21:15 +0000 (10:21 +0000)]
index: filter out indexlevel=basic from extindex
extindex users will likely want to use indexlevel=basic for
per-inbox indices, however extindex itself doesn't support basic
index level (yet?). Let's ensure we don't trip up extindex
users who specify "-L basic" on the -index command-line.
Eric Wong [Fri, 25 Dec 2020 10:21:14 +0000 (10:21 +0000)]
v2writable: don't verify tip if reindexing
We only rely on git-rev-parse to resolve symbolic names ("HEAD")
to a SHA-* git commit ID. We'll assume any git commit IDs we
get from SQLite DBs are valid and let "git-log" fail if it
isn't.
Eric Wong [Fri, 25 Dec 2020 10:21:13 +0000 (10:21 +0000)]
index: fix --no-fsync flag propagation to extindex
Negation in flag names are confusing, but trying to deviate from
the DB_NO_SYNC name used by Xapian is also confusing.
Eric Wong [Fri, 25 Dec 2020 10:21:12 +0000 (10:21 +0000)]
index: do not attach inbox to extindex unless updated
We'll count the number of log changes (regardless of index or
unindex) and only attach inboxes to ExtSearchIdx objects when
they get new work. We'll also reduce lock bouncing and only
update external indices after all per-inbox indexing is done.
This also updates existing v2 indexing/unindexing callers
to be more consistent and ensures unindex log entries update
per-inbox last commit information.
Eric Wong [Fri, 25 Dec 2020 10:21:11 +0000 (10:21 +0000)]
extsearchidx: close DB handles after use if FD constrained
Most distros ship with low RLIMIT_NOFILE limits and surprises
may lurk for admins who configure many inboxes. Keep FD usage
under control to avoid EMFILE errors at inopportune times during
reindex.
From what I can tell, this is the only place where extindex can
have unpredictable FD growth when there's thousands of inboxes,
and it's in an extremely rare code path.
Eric Wong [Fri, 25 Dec 2020 10:21:10 +0000 (10:21 +0000)]
extsearchidx: delay SQLite availability checks
This will make attach_inbox faster for no-op calls. It also
helps us avoid races in case msgmap or over.sqlite3 gets
unlinked while -extindex is running.
Eric Wong [Fri, 25 Dec 2020 10:21:09 +0000 (10:21 +0000)]
index: disable --fast-noop on --reindex
These options make no sense when used together, just inform the
user and move on since it's probably harmless to continue.
Eric Wong [Sat, 26 Dec 2020 01:44:38 +0000 (01:44 +0000)]
init: use the return value of rel2abs_collapsed
:x
Fixes: 9fcce78e40b0a7c6 ("script/public-inbox-*: favor caller-provided pathnames")
Eric Wong [Thu, 24 Dec 2020 10:09:19 +0000 (10:09 +0000)]
index: support --fast-noop / -F switch
Note: I'm not sure if it's worth documenting and supporting this
long-term.
We can can avoid taking locks for invocations of "index --all"
and rely on high-resolution ctime (struct timespec st_ctim)
comparisons of msgmap.sqlite3 and the packed-refs + refs/heads
directory of the newest epoch.
This cuts public-inbox-index invocations with
"--all --no-update-extindex -L basic" down from 0.92s to 0.31s.
The change with "-L medium" or "-L full" and (default) non-zero
jobs is even more drastic, reducing a 12-13s no-op invocation
down to the same 0.31s
Eric Wong [Thu, 24 Dec 2020 10:09:18 +0000 (10:09 +0000)]
inboxwritable: delay umask_prepare calls
This simplifies all ->with_umask callers and opens the
door for further optimizations to delay/elide process spawning.
Eric Wong [Wed, 23 Dec 2020 23:02:55 +0000 (23:02 +0000)]
index: update [extindex "all"] by default, support -E
In most cases, this ensures users will only have to opt-in to
using -extindex once and won't have to issue extra commands
to keep external indices up-to-date when using
public-inbox-index.
Since we support arbitrary numbers of external indices for
ease-of-development, we'll support repeating "-E"
("--update-extindex=") in case users want to test changes in
parallel.
Eric Wong [Wed, 23 Dec 2020 08:38:53 +0000 (08:38 +0000)]
config: config_fh_parse: micro-optimize harder
Instead of relying on split() and a regexp, we'll drop split()
entirely and rely on index() + two substr() calls to operate on
fixed strings. This brings PublicInbox::Config->new time down
from 0.98s down to 0.84s.
Eric Wong [Wed, 23 Dec 2020 08:38:52 +0000 (08:38 +0000)]
config: config_fh_parse: micro-optimize
We can avoid a slow regexp capture and instead and rely on
rindex + substr to extract the section from the config file.
Then we use the defined-or-assignment (//=) operator combined
with the documented return value of `push' to ensure @section_order
is unique without repeating a hash lookup.
Finally, we avoid short-lived variables inside the loop and
declare them subroutine-wide to knock a teeny bit of allocation
time.
Combined, these optimizations bring the ~1.22s
PublicInbox::Config->new time down to ~0.98s with 50K inboxes.
Eric Wong [Wed, 23 Dec 2020 08:38:51 +0000 (08:38 +0000)]
config: git_config_dump: pre-compile RE for split
It appears the Perl split() operator is not optimized for fixed
strings at all. With this change, PublicInbox::Config->new (w/o
->fill_all) time is reduced from 1.81s to 1.22s on a config file
with 50K inboxes.
Eric Wong [Wed, 23 Dec 2020 08:38:50 +0000 (08:38 +0000)]
config: _fill: inbox name extraction optimization
Using substr() instead of a string copy + s// substitution here
reduces ->fill_all from 4.00s to 3.88s with 50K inboxes on my
workstation.
Eric Wong [Wed, 23 Dec 2020 08:38:49 +0000 (08:38 +0000)]
extsearchidx: close SQLite handles after attaching
This is needed to prevent us from running out of FDs when
indexing many inboxes. Perhaps checking these on attach_inbox
is unnecessary and may be removed entirely down the line.
Eric Wong [Wed, 23 Dec 2020 08:38:48 +0000 (08:38 +0000)]
miscsearch: index UIDVALIDITY, use as startup cache
This brings -nntpd startup time down from ~35s to ~5s with 50K
inboxes.
Further improvements ought to be possible with deeper changes to
MiscIdx, since -mda having to load every inbox seems unreasonable;
but this general change is fairly unintrusive.
Eric Wong [Wed, 23 Dec 2020 08:38:47 +0000 (08:38 +0000)]
inboxwritable: _init_v1: set created_at ASAP
This ensures we have UIDVALIDITY to index earlier
rather than later for v1 inboxes, matching v2 behavior.
Eric Wong [Wed, 23 Dec 2020 08:38:46 +0000 (08:38 +0000)]
inbox: git_epoch: correct false comment
The original comment hasn't been true since
PublicInbox::Git->modified was changed to use cat_async blob
responses. In any case, manifest.js.gz generation already
cleans up per-epoch git processes used for ->modified.
Eric Wong [Wed, 23 Dec 2020 08:38:45 +0000 (08:38 +0000)]
xt: add create-many-inboxes helper test
I've been using something like this to mock out thousands
of inboxes for testing.
Eric Wong [Wed, 23 Dec 2020 08:38:44 +0000 (08:38 +0000)]
miscsearch: load Xapian at initialization
We need Xapian bindings loaded before calling
(Search::)Xapian::Database->new
Eric Wong [Tue, 22 Dec 2020 05:04:16 +0000 (05:04 +0000)]
wwwstream: show relative coderepo URLs correctly
Trying to link "foo.git" relative to the current URL usually
does not provide correct results, so prefix it by going
into the parent directory if an absolute (or protocol-relative)
URL is not supplied.
Eric Wong [Tue, 22 Dec 2020 06:01:44 +0000 (06:01 +0000)]
admin: resolve inboxes to absolute paths for index
Some of my ancient v1-only scripts called public-inbox-index
to operate on GIT_DIR:
GIT_DIR=/path/to/foo.git public-inbox-index
This change ensures they keep working, otherwise "." will be
passed to the --git-dir= switch of git(1) because that's the
default directory if no inboxes are specified on the
command-line.
Fixes: 9fcce78e40b0a7c6 ("script/public-inbox-*: favor caller-provided pathnames")
Uwe Kleine-König [Tue, 22 Dec 2020 17:18:10 +0000 (18:18 +0100)]
public-inbox-v[12]-format.pod: make lexgrog happy
The Debian package linter (lintian) emits the following warning:
W: bad-whatis-entry
N:
N: A manual page should start with a NAME section, which lists the
N: program name and a brief description. The NAME section is used to
N: generate a database that can be queried by commands like apropos and
N: whatis. You are seeing this tag because lexgrog was unable to parse
N: the NAME section.
N:
N: Manual pages for multiple programs, functions, or files should list
N: each separated by a comma and a space, followed by \- and a common
N: description.
N:
N: Listed items may not contain any spaces. A manual page for a two-level
N: command such as fs listacl must look like fs_listacl so the list is
N: read correctly.
N:
N: Refer to the lexgrog(1) manual page, the groff_man(7) manual page, and
N: the groff_mdoc(7) manual page for details.
N:
N: Severity: warning
N:
N: Check: documentation/manual
N:
N: Renamed from: manpage-has-bad-whatis-entry
N:
for public-inbox-v1-format and public-inbox-v2-format.
Adapt the descriptions to make lexgrog and so lintian happy.
Eric Wong [Mon, 21 Dec 2020 22:10:55 +0000 (22:10 +0000)]
support multiple CODE_URLs
public-inbox.org will expire in a few years, so ensure Tor .onions
can be known before then.
Eric Wong [Mon, 21 Dec 2020 07:51:22 +0000 (07:51 +0000)]
extsearch*: drop unnecessary path canonicalization
Unlike inboxdir, the canonical-ness of -extindex paths is not
relevant at the moment, and may never be relevant at all. So
don't mislead others into thinking these paths being
canonicalized matters.
Eric Wong [Mon, 21 Dec 2020 07:51:21 +0000 (07:51 +0000)]
searchidx: rename get_val to int_val and return IV
Values can be strings in Xapian, although we currently use
integer values exclusively. Give the wrapper a more appropriate
name in case we start using string columns.
For future-proofing, we'll now return `undef' on missing columns
and coerce the return value to an IV (integer value) to save
memory, as sortable_unserialise returns a PV (pointer value)
scalar despite it existing to support numeric values.
Eric Wong [Mon, 21 Dec 2020 07:51:20 +0000 (07:51 +0000)]
use rel2abs_collapsed when loading Inbox objects
We need to canonicalize paths for inboxes which do not have
a newsgroup defined, otherwise ->eidx_key matches can fail
in unexpected ways.
Eric Wong [Mon, 21 Dec 2020 07:51:19 +0000 (07:51 +0000)]
isearch: use numeric sort for article numbers
Perl sort is alphabetical by default and Xapian uses numeric
document IDs, so sort must be told explicitly to use numeric
comparisons even if the scalars are integer values (IV)
internally.
And eliminate extra hash marks ("#") since they're probably too
noisy if there are many IDs.
Note: I haven't seen this warning message in syslog, yet :>
Eric Wong [Mon, 21 Dec 2020 07:51:18 +0000 (07:51 +0000)]
inbox: delay ->version detection
Our read-only code won't need to know the version until an inbox
is accessed. This is a small step towards eliminating many
stat() calls on read-only daemon startup.
Eric Wong [Mon, 21 Dec 2020 19:41:21 +0000 (19:41 +0000)]
manifest.js.gz: fix per-inbox /$INBOX/manifest.js.gz
/$INBOX/manifest.js.gz should not attempt to match every inbox
in the domain (or every inbox); that is for /manifest.js.gz
(without a /$INBOX prefix).
Fixes: f303b4add8ea1883 ("wwwlisting: avoid hogging event loop")
Eric Wong [Sun, 20 Dec 2020 06:30:16 +0000 (06:30 +0000)]
config: eliminate unnecessary join call up front
We can rely on implicit join in string interpolation on die()
iff needed.
And just creating the arrayref up front to avoid an extra
backslash seems nicer at the moment.
Eric Wong [Sun, 20 Dec 2020 06:30:15 +0000 (06:30 +0000)]
daemon: kill_workers: eliminate unnecessary loop
The `kill' perl op takes multiple PIDs, so there's no need to
iterate through the %pids hash.
Eric Wong [Sun, 20 Dec 2020 06:30:14 +0000 (06:30 +0000)]
daemon: unconditionally call IO::Handle::blocking(0)
IO::Handle::blocking will always return the initial value from
the F_GETFL op and it won't issue F_SETFL if a socket is already
non-blocking.
Eric Wong [Sun, 20 Dec 2020 06:30:13 +0000 (06:30 +0000)]
daemon: lazy load Cwd only for --daemonize users
systemd users won't need it polluting the namespace; though
other things are still likely to load it.
Eric Wong [Sun, 20 Dec 2020 06:30:12 +0000 (06:30 +0000)]
inboxidle: remove needless check for {inboxdir}
->each_inbox will never attempt to iterate an object
without {inboxdir}, and simplify + short-circuit the
corresponding code
Eric Wong [Sun, 20 Dec 2020 06:30:11 +0000 (06:30 +0000)]
script/public-inbox-*: favor caller-provided pathnames
We'll try to avoid calling Cwd::abs_path and use
File::Spec->rel2abs instead, since abs_path will resolve
symlinks the user specified on the command-line.
Unfortunately, ->rel2abs still leaves "/.." and "/../"
uncollapsed, so we still need to fall back to Cwd::abs_path in
those cases.
While we are at it, we'll also resolve inboxdir from deep inside
v2 directories instead of misdetecting them as v1 bare git
repos.
In any case, stop matching directories by name and instead rely
on the unique combination of st_dev + st_ino on stat() as we
started doing in the extindex code.
Eric Wong [Fri, 18 Dec 2020 20:53:09 +0000 (20:53 +0000)]
wwwstream: linkify coderepo URLs
It seems like a good idea to get more cgit visibility.
Eric Wong [Thu, 17 Dec 2020 19:40:06 +0000 (19:40 +0000)]
extsearchidx: improve missing machine-id fallback
It's likely most GNU/Linux systems have /etc/machine-id these
days, so anything missing it is likely a *BSD, most of which
support and favor "sysctl -n kern.hostid". We'll also support
"ghostid" since GNU utils are commonly prefixed with 'g' on
non-GNU platforms.
In any case, we'll suppress stderr from missing commands and
fall back to hard coding an $OSNAME-based identifier as a last
resort and hope the hostname is unique.
Eric Wong [Fri, 18 Dec 2020 11:54:37 +0000 (11:54 +0000)]
nntpd: skip inboxes w/o {newsgroup}
So we don't trigger an uninitialized variable warning :x
Uwe Kleine-König [Fri, 18 Dec 2020 11:56:14 +0000 (12:56 +0100)]
Fix manpage section of perl module documentation
On Debian (at least) perl documentation is supposed to be installed in
section 3pm. With the build system hardcoding this to 3 instead this
results in a warning by the Debian package linter:
W: public-inbox: wrong-manual-section usr/share/man/man3/PublicInbox::Git.3.gz:74 3 != 3pm
W: public-inbox: wrong-manual-section usr/share/man/man3/PublicInbox::Import.3.gz:74 3 != 3pm
W: public-inbox: wrong-manual-section usr/share/man/man3/PublicInbox::SaPlugin::ListMirror.3.gz:74 3 != 3pm
W: public-inbox: wrong-manual-section ... use --no-tag-display-limit to see all (or pipe to a file/program)
So use "$(MAN3EXT)" instead of "3".
Eric Wong [Thu, 17 Dec 2020 09:14:48 +0000 (09:14 +0000)]
import: drop X-Status in addition to Status
It's actually supported by mutt, dovecot[1], and likely some other
software to augment the Status: header. While dovecot doesn't
expose X-Status to clients, mutt will write 'A' (answered) and
'F' to X-Status (but not T (draft)).
So we'll drop it like we do Status since it's not suitable for
public mail, but stick it in an @UNWANTED_HEADERS array will
allow us to configure an override if needed.
[1] https://doc.dovecot.org/configuration_manual/mail_location/mbox/
Eric Wong [Wed, 16 Dec 2020 23:19:06 +0000 (23:19 +0000)]
extsearchidx: no need to make InboxWritable
extindex treats v1/v2 public inboxes as read-only, so there's
no need to scare people by using the InboxWritable package
now that ->git_dir_n is gone and we can use ->max_git_epoch
instead of ->git_dir_latest.
Eric Wong [Wed, 16 Dec 2020 23:19:05 +0000 (23:19 +0000)]
inboxwritable: drop git_dir_n sub
There's only one caller, unlikely to be any more, and
should be harmless to open code.
Eric Wong [Wed, 16 Dec 2020 23:19:04 +0000 (23:19 +0000)]
inbox: simplify v2 epoch counting
Perl readdir detects list context and can return an array
suitable for the grep op. From there, we can rely on
substr to remove the ".git" suffix and integerize the value
to save a few bytes before letting List::Util::max return
the value.
This is how we detect Xapian shards nowadays, too, and
we'll also use defined-or (//) to simplify the return
value there.
We'll also simplify InboxWritable->git_dir_latest,
remove some callers, and consider removing it entirely.
Eric Wong [Wed, 16 Dec 2020 23:19:03 +0000 (23:19 +0000)]
index: ignore some warnings, set {current_info} for v1
-index runs on data that's already frozen in git, so there's
no point in warning users about it.
While we're at it, set the {current_info} prefix for v1 as
we do in v2 inboxes in case new problems show up.
Eric Wong [Wed, 16 Dec 2020 23:19:02 +0000 (23:19 +0000)]
inboxwritable: warn_ignore: "Bad UTF7 data escape"
As with the other messages in this callback, there's
nothing we can do about invalid messages ending up in
our Maildirs for -watch.
Eric Wong [Wed, 16 Dec 2020 23:04:53 +0000 (23:04 +0000)]
extsearchidx: lock eidxq on full --reindex
Incremental indexing can use the `eidxq' reindexing queue for
handling deletes and resuming interrupted indexing. Ensure
those incremental -extindex invocations do not steal (and
prematurely perform) work that an "-extindex --reindex"
invocation is handling.
Eric Wong [Tue, 15 Dec 2020 02:02:24 +0000 (02:02 +0000)]
searchidxshard: simplify newline elimination
This overdue change fixes {current_info} to not inject a newline
into every warning message.
Simpler code helps us avoid bugs and the need to make
fixes like commit
44de182766037948d62bc2a8ba924de2264dd5fc
("searchidxshard: chomp $eidx_key from pipe").
Eric Wong [Tue, 15 Dec 2020 02:02:23 +0000 (02:02 +0000)]
extsearchidx: reindex releases over.sqlite3 handles properly
When checkpointing and yielding the lock to other processes,
we need to ensure any open DB statement handles are closed,
since they reference and prevent DB FDs from being closed
and unlocked.
And clean up some progress reporting while we're at it.
Eric Wong [Tue, 15 Dec 2020 02:02:22 +0000 (02:02 +0000)]
extsearchidx: simplify reindex code paths
Since we're inside a Xapian transaction, calling ->index_raw
followed by ->shard_add_eidx_info calls on the same docid
doesn't seem to hurt indexing performance. It definitely
reduces FS read traffic and IPC from git at the cost of some
more IPC between the parent and workers. Nevertheless, the code
and FD reductions seem worth it.
Eric Wong [Tue, 15 Dec 2020 02:02:21 +0000 (02:02 +0000)]
extsearchidx: checkpoint releases locks
--reindex can take many hours or days, ensure we release
locks according to --batch-size so automated fetch+index
jobs can write new data to indices while we update old data.
Eric Wong [Tue, 15 Dec 2020 02:02:20 +0000 (02:02 +0000)]
extsearchidx: reindex works on Xapian, too
Instead of just working on over.sqlite3, we need to work on
the Xapian DBs as well. While no changes to our Xapian use
have taken place recently, they could in the future and
--reindex exists to account for that.
Eric Wong [Tue, 15 Dec 2020 02:02:19 +0000 (02:02 +0000)]
extindex: support --rethread and content bifurcation
--rethread is useful for dealing with bugs and behaves
just like it does with current inboxes.
This is in case our content deduplication logic changes for
whatever reason and causes previously merged messages to be
considered "different". As with v2, this won't allow us to
merge messages in a way that allows deduplicating messages which
were previously considered different, but v2 inboxes do not
allow that, either.
In other words, this makes the --reindex and --rethread
switches of -extindex match the behavior of v2 -index.
Eric Wong [Tue, 15 Dec 2020 02:02:18 +0000 (02:02 +0000)]
over: sort xref3 by xnum if ibx_id repeats
While unlikely to happen, it may be possible for messages
from the same inbox to get indexed multiple times. Provide
consistent results in this case for ease-of-testing.
Eric Wong [Tue, 15 Dec 2020 02:02:17 +0000 (02:02 +0000)]
extindex: delete stale messages from over.sqlite3
In addition to removing stale messages from Xapian, we must
also remove them from over.sqlite3.
Eric Wong [Tue, 15 Dec 2020 02:02:16 +0000 (02:02 +0000)]
extindex: preliminary --reindex support
--reindex allows us to catch missed and stale messages due to
-extindex vs -index races prior to commit
02b2fcc46f364b51
("extsearchidx: enforce -index before -extindex").
We'll also rely on reindex to internally deal with v1/v2 inbox
removals and partial-unindexing of messages which are only
removed from one inbox out of many.
This reindex design is completely different than how normal
v1/v2 inbox reindex operates due to extindex having multiple
histories to work with. Instead of scanning git history, this
relies exclusively on comparing over.sqlite3 contents between
the v1/v2 inboxes and the extindex.
Changes to Xapian behavior also get picked up, now. Xapian indexing
is handled by workers with minimal IPC to the parent process.
This results in more read I/O but fewer writes when dealing
with cross-posted messages.
Changes to $smsg->populate and --rethread still need further
work.
Eric Wong [Wed, 16 Dec 2020 04:39:37 +0000 (04:39 +0000)]
t/psgi_v2: ignore warnings on missing P::M::ReverseProxy
Plack::Test::ExternalServer doesn't depend on
Plack::Middleware::ReverseProxy, so we need to account for
some warnings in stderr if P::M::RP is missing.
Eric Wong [Wed, 16 Dec 2020 23:56:29 +0000 (23:56 +0000)]
inbox: ->uidvalidity returns undef w/o ->mm
While totally unindexed inboxes are rare, we still support
them for v1 and may hit code which calls this method. Just
return `undef' when ->mm access fails.
Eric Wong [Wed, 16 Dec 2020 23:55:34 +0000 (23:55 +0000)]
imap: rename parse_query => parse_imap_query
Avoid confusing hackers since this conflicts with a method name
provided by (Search::)Xapian::QueryParser.
Eric Wong [Tue, 15 Dec 2020 11:47:17 +0000 (11:47 +0000)]
daemon: simplify fork() failure checks
The defined-or `//' operator in 5.10 allows us to golf down
our code slightly.
Eric Wong [Tue, 15 Dec 2020 11:47:16 +0000 (11:47 +0000)]
daemon: support --daemonize without Net::Server::Daemonize
We don't actually need Net::Server::Daemonize to support
the --daemonize flag, since the daemonize() sub provided
by N::S::D doesn't exactly do the things we want.
Eric Wong [Fri, 11 Dec 2020 20:49:58 +0000 (20:49 +0000)]
PublicInbox::Feed owns `feedmax' default value
There's no need to have extra code in the Inbox package for this
or to waste dozens of bytes for every Inbox object which uses
the default value.
This makes our code more flexible w.r.t Inbox-like ExtSearch
objects and fixes uninitialized value warnings with ->ALL.
Kyle Meyer [Sat, 12 Dec 2020 18:24:48 +0000 (18:24 +0000)]
doc: v2-format: drop repeated word
Eric Wong [Sat, 12 Dec 2020 09:31:42 +0000 (09:31 +0000)]
doc: add public-inbox-extindex-format(5) manpage
The CLI tool still needs usability work, and "misc" is still in
flux, but the core message indexing part is stable (since it's
stolen from v2 :P).
Eric Wong [Thu, 10 Dec 2020 22:38:47 +0000 (22:38 +0000)]
nntp+www: drop List-* and Archived-At headers
These headers can conflict with headers in the DKIM signature;
and parsing the DKIM-Signature header to determine whether or
not we can safely add a header would be more code and CPU
cycles.
Since IMAP seems fine without these headers (and JMAP will
likely be, too), there's likely no need to continue appending
these to every message. Nowadays, developers seem sufficiently
trained to use URLs with Message-IDs in them. So drop the
headers and save some cycles and bandwidth all around.
Eric Wong [Thu, 10 Dec 2020 23:04:50 +0000 (23:04 +0000)]
extmsg: avoid exceptions when /all/$MSGID/ fails
If a message can't be found in ->ALL, we shouldn't attempt to
enter code paths which iterate normal inboxes or attempt to
access non-existent fields (e.g. {name}, {newsgroup},
{inboxdir}) in the ExtSearch object.
Eric Wong [Thu, 10 Dec 2020 08:35:47 +0000 (08:35 +0000)]
manifest: account for future cache in MiscIdx docdata
We'll be storing private data inside the "" (empty string) key
of the JSON doc we use for store for manifest.js.gz generation.
This private data will allow us to reduce FS activity at and
speed up startup times, but some will also be in Xapian boolean
terms and values for searching and filtering.
Eric Wong [Wed, 9 Dec 2020 09:25:12 +0000 (09:25 +0000)]
extsearchidx: enforce -index before -extindex
We cannot set xref3 data without the `xnum' column to
tie it to the per-inbox over.sqlite3 DB. So ensure we don't
read brand-new history that only exists in git, but instead
rely on last_commit and last_xap15-$EPOCH metadata in msgmap
to decide how far we can index.
Before this change, it was possible to miss messages in
the extindex if -index did not run (which will be fixable by
upcoming --reindex support in -extindex).
Eric Wong [Wed, 9 Dec 2020 09:25:11 +0000 (09:25 +0000)]
t/extsearch: use indexlevel=basic in inboxes
There's no need for per-inbox Xapian DBs when using extindex, so
reduce wear on the poor systems this test runs on.
Eric Wong [Wed, 9 Dec 2020 09:25:10 +0000 (09:25 +0000)]
searchidx: all indexers check for bad blobs
This should help us detect bugs in our code or storage
synchronization problems more easily. This probably won't
detect corrupted git storage, but can detect corrupted SQLite
files.
"Bad blobs, bad blobs, whatcha gonna do when they come for you?"
Eric Wong [Wed, 9 Dec 2020 23:33:00 +0000 (23:33 +0000)]
www+nntp: deal with lack of addresses for ->ALL
Since extindex is an amalgamation of several inboxes, discerning
an appropriate address for List-Post: would be expensive and
most likely unnecessary. Some legacy/historical inboxes may
have no active address, either, so don't attempt to set the
List-Post header if no addresses are configured.
Eric Wong [Tue, 8 Dec 2020 21:21:30 +0000 (21:21 +0000)]
extsearchidx: ck_existing: set $OID for warning context
The content_hash() hash in the same scope may trigger warnings
for a given blob, so ensure we correctly report the blob where
it happens.
Eric Wong [Tue, 8 Dec 2020 21:21:29 +0000 (21:21 +0000)]
admin: resolve_repo_dir => resolve_inboxdir
We've stopped referring to inboxdirs as "repos" a while ago
since v2 inboxes have multiple git repos associated with them.
So update the name to reflect that and avoid an unnecessary
export that's only used by a test case.
Eric Wong [Tue, 8 Dec 2020 21:21:28 +0000 (21:21 +0000)]
extindex: do not use current dir like -index does
At least not for resolving inboxes, since there's no good way
for a user to specify what is an inbox or extindex directory
without a command-line switch.
Instead of changing the -extindex command, we change the -index
command internals to rely on the new {-use_cwd} flag to avoid
internal use of negation, since double-negatives and the like
are confusing to me.
Eric Wong [Tue, 8 Dec 2020 21:21:27 +0000 (21:21 +0000)]
rename {pi_config} fields to {pi_cfg}
{pi_config} may be confused with the documented `PI_CONFIG'
environment variable, and we'll favor vowel-removal to be
consistent with our usage of object references.
The `pi_' prefix may stay in some places, for now; since a
separate namespace may come into this codebase for local/private
client-tooling.
For InboxIdle, we'll also remove an invalid comment about
holding a reference to the PublicInbox::Config object, too.
Eric Wong [Tue, 8 Dec 2020 21:21:26 +0000 (21:21 +0000)]
nntp: replace {ng} with {ibx} for consistency
They're PublicInbox::Inbox objects just like the rest of
the non-NNTP code. So rename the NNTP code for consistency
with the rest of the codebase. Furthermore, {ng} and $ng
may be confused with the `--ng' switch for -init, and that's
a non-ref scalar string.
Eric Wong [Tue, 8 Dec 2020 21:21:25 +0000 (21:21 +0000)]
treewide: replace {-inbox} with {ibx} for consistency
{ibx} is shorter and is the most prevalent abbreviation
in indexing and IMAP code, and the `$ibx' local variable
is already prevalent throughout.
In general, the codebase favors removal of vowels in variable
and field names to denote non-references (because references are
"lighter" than non-references).
So update WWW and Filter users to use the same code since
it reduces confusion and may allow easier code sharing.
Eric Wong [Sat, 5 Dec 2020 22:22:46 +0000 (22:22 +0000)]
search: reinstate "uid:" internal search prefix
User-supplied queries (via PublicInbox::IMAPsearchqp) may
restrict messages to certain UID ranges in addition to the
limits we impose ourselves for mailbox slices. So we'll
continue to ask Xapian::QueryParser to "uid:" numeric ranges.
Fixes: 4b551c884a648b45 ("imap: support isearch and reduce Xapian queries")
Eric Wong [Mon, 7 Dec 2020 07:40:53 +0000 (07:40 +0000)]
shard_add_eidx_info: pass $eidx_key instead of $ibx object
This improves consistency with sibling methods such as
->shard_remove_eidx_info and ->add_xref3. Passing the
$eidx_key scalar is preferable to the entire $ibx object
for IPC-friendliness.
Eric Wong [Mon, 7 Dec 2020 07:40:52 +0000 (07:40 +0000)]
searchidx: remove $oid parameter from most calls
Xapian docids have been tied to the over {num} column for
nearly 3 years, now; and OIDs are no longer stored in Xapian
document data. There's no need to increase code and IPC
complexity by passing the OID around.
Eric Wong [Mon, 7 Dec 2020 07:40:51 +0000 (07:40 +0000)]
extsearchidx: remove needless SHA-1 check
There is no need to verify checksums of data already stored in
git. Doing this ourselves also limits flexibility in moving to
other hashes.
Eric Wong [Mon, 7 Dec 2020 07:40:50 +0000 (07:40 +0000)]
overidx: wrap eidx_key => ibx_id mapping
This makes things a little less noisy and will be
called by ExtSearchIdx.
Eric Wong [Mon, 7 Dec 2020 07:40:49 +0000 (07:40 +0000)]
over: gracefully show invalid ibx_id
While "public-inbox-extindex --gc" invocations try to ensure
proper ordering, it is still possible for users to change
the `inboxes' tables via sqlite3(1) or similar means. So
show a "missing://ibx_id=$ibx_id" placeholder to avoid undefined
variable warnings.
URLs such as "imaps://..." will eventually be supported as
eidx_keys, so having a URL-like "missing://" as a placeholder
probably makes sense.
Eric Wong [Sat, 5 Dec 2020 22:59:31 +0000 (22:59 +0000)]
overidx: {num} column is INTEGER PRIMARY KEY
INTEGER PRIMARY KEY can be an alias for ROWID in SQLite and is
already unique, so there's no need for a separate UNIQUE(num)
index.
With a smallish ~3K, freshly indexed v2 inbox, this results in a
~40K space savings, reducing over.sqlite3 from 1.375M to 1.335M
(post-VACUUM).
This only affects newly-indexed inboxes; existing DBs will
require manual intervention to take advantage of space savings.
Link: https://www.sqlite.org/rowidtable.html
Eric Wong [Sat, 5 Dec 2020 11:10:45 +0000 (11:10 +0000)]
imap: support isearch and reduce Xapian queries
Since IMAP search (either with Isearch or traditional per-Inbox
search) only returns UIDs, we can safely set the limit to the
UID slice size(*). With isearch, we can also trust the Xapian
result to fit any docid range we specify.
Limiting Xapian results to 1000 was making ->ALL docid <=>
per-Inbox UID impossible since results could overlap between
ranges unpredictably.
Finally, we can map the ->ALL docids into per-Inbox UIDs and
show them to the client in the UID order of the Inbox, not the
docid order of the ->ALL extindex.
This also lets us get rid of the "uid:" query parser prefix
and use the Xapian::Query API directly to reduce our search
prefix footprint.
For mbox.gz downloads in WWW, we'll also make a best effort to
preserve the order from the Inbox, not the order of extindex;
though it's possible large result sets can have non-overlapping
windows.
(*) by definition, UID slice size is a "safe" value which
shouldn't OOM either the server or clients.
Eric Wong [Sat, 5 Dec 2020 10:11:38 +0000 (10:11 +0000)]
isearch: emulate per-inbox search with ->ALL
Using "eidx_key:" boolean prefix to limit results to a given
inbox, we can use ->ALL to emulate and replace per-Inbox
xap15/[0-9] search indices.
With this change, the presence of "extindex.all.topdir" in the
$PI_CONFIG will cause the WWW code to use that extindex and
ignore per-inbox Xapian DBs in xap15/[0-9].
Unfortunately IMAP search still requires old per-inbox indices,
for now. Mapping extindex Xapian docids to per-Inbox UIDs and
vice-versa is proving tricky. Fortunately, IMAP search is
rarely used and optional. The RFCs don't specify expensive
phrase search, either, so `indexlevel=medium' can be used in
per-inbox Xapian indices to save space.
For primarily WWW (and future JMAP) users; this should result in
significant disk space, FD, and page cache footprint savings for
large instances with many inboxes and many cross-posted
messages.
Eric Wong [Sat, 5 Dec 2020 10:11:37 +0000 (10:11 +0000)]
inbox: simplify ->search and callers
Stop leaking WWW/PSGI-specific logic into classes like
PublicInbox::Inbox, which is used universally.
We'll also decouple $ibx->over from $ibx->search and just deal
with duplicate the code inside ->over to reduce argument
complexity in ->search.
This is also a step in moving away from using {psgi.errors}
to ease code sharing between IMAP, NNTP, and command-line
interfaces. Perl's built-in `warn' and `local $SIG{__WARN__}'
provides all the flexibility we need to control warning output
and should be universally understood by Perl hackers who may
be unfamiliar with PSGI.
Eric Wong [Fri, 4 Dec 2020 22:03:49 +0000 (22:03 +0000)]
extmsg: use ->ALL for "global" MID lookups
As with NewsWWW and NNTP, we can use ->ALL to completely
avoid trying SQLite/Xapian lookups across hundreds/thousands
of inboxes.
Eric Wong [Fri, 4 Dec 2020 22:03:48 +0000 (22:03 +0000)]
newswww: use ->ALL to avoid O(n) inbox scan
We can avoid doing a Message-ID lookup on every single inbox
by using ->ALL to scan its over.sqlite3 DB. This mimics NNTP
behavior and picks the first message indexed, though redirecting
to /all/$MESSAGE_ID/ could be done.
With the current lore.kernel.org set of inboxes (~140), this
provides a 10-40% speedup depending on inbox ordering.
Eric Wong [Fri, 4 Dec 2020 22:03:47 +0000 (22:03 +0000)]
search: remove mdocid export
There's no need to export it, as shown by the change to
SearchView. This should pave the way to making search
more flexible and allow per-Inbox search to reuse ->ALL.
Eric Wong [Fri, 4 Dec 2020 22:03:46 +0000 (22:03 +0000)]
nntp: small speed up for multi-line responses
Using a non-zero-length separator for `join' requires extra work
inside Perl. We can shove the cost of appending "\r\n" into the
`map' loop, instead. This speeds up the `join' operation.
The "deferred" log entry for a "LISTGROUP org.kernel.vger.linux-kernel"
command (with nearly 3.8 million messages) goes from ~3.96s to 3.86s
on my workstation.
Eric Wong [Fri, 4 Dec 2020 22:03:45 +0000 (22:03 +0000)]
nntp: xref_by_tc: simplify slightly
We can invalidate ibx->{newsgroup} at config load-time to avoid
having to check ibx->{newsgroup} validity in To/Cc: matching.
This saves us some hash lookups in all cases.
Eric Wong [Fri, 4 Dec 2020 12:09:29 +0000 (12:09 +0000)]
over: ensure old, merged {tid} is really gone
We must use the result of link_refs() since it can trigger
merge_threads() and invalidate $old_tid. In case
merge_threads() isn't triggered, link_refs() will return
$old_tid anyways.
When rethreading and allocating new {tid}, we also must update
the row where the now-expired {tid} came from to ensure only the
new {tid} is seen when reindexing subsequent messages in
history. Otherwise, every subsequently reindexed+rethreaded
message could end up getting a new {tid}.
Reported-by: Kyle Meyer <kyle@kyleam.com>
Link: https://public-inbox.org/meta/87360nlc44.fsf@kyleam.com/