]> git.ipfire.org Git - thirdparty/public-inbox.git/log
thirdparty/public-inbox.git
6 months agoinit: move --skip-artnum handling to {-creat_opt}
Eric Wong [Sat, 18 Jan 2025 01:26:06 +0000 (01:26 +0000)] 
init: move --skip-artnum handling to {-creat_opt}

It makes more sense to have inbox creation options bundled
together and reduces the amount of potentially confusing
positional parameters we must pass around.

6 months agoinbox_writable: match v1 and v2 init semantics
Eric Wong [Sat, 18 Jan 2025 01:26:05 +0000 (01:26 +0000)] 
inbox_writable: match v1 and v2 init semantics

More consistent code between v1 and v2 will make maintenance
easier going forward.

6 months agov2writable: simplify ->new by reducing arg flexibility
Eric Wong [Sat, 18 Jan 2025 01:26:04 +0000 (01:26 +0000)] 
v2writable: simplify ->new by reducing arg flexibility

We can update callers easily enough for internal-only APIs,
so there's no need to deal with unwarranted flexibility for
V2Writable->new.

6 months agoinbox_writable: use autodie::open
Eric Wong [Sat, 18 Jan 2025 01:26:03 +0000 (01:26 +0000)] 
inbox_writable: use autodie::open

autodie should give us more consistent error reporting going
forward.

6 months agodoc: add an example of acceptable marketing
Eric Wong [Sat, 18 Jan 2025 01:50:18 +0000 (01:50 +0000)] 
doc: add an example of acceptable marketing

Presenting specific solutions to random comments is probably
acceptable since it's potentially helpful to some people;
but disclaimers must be present to lower expectations.

6 months agosearch_query: fix warnings on bogus `o=' query param
Eric Wong [Sun, 19 Jan 2025 04:40:58 +0000 (04:40 +0000)] 
search_query: fix warnings on bogus `o=' query param

Users may specify non-numeric values for the `o' parameter
which won't be captured.  Avoid uninitialized variable warnings
by assuming `0' when no numeric value is specified.

6 months agoconfig: force absolute path when `-C /' (chdir) is used
Eric Wong [Thu, 16 Jan 2025 03:28:51 +0000 (03:28 +0000)] 
config: force absolute path when `-C /' (chdir) is used

For rare cases where we rely on `-c' to override temporary
options, we also chdir(2) to `/' to avoid hitting a users'
$worktree/.git/config.  Thus, the config file must be given as
as an absolute path.  While the majority of or code assumes
absolute paths are used for config files, it's possible we end
up on some strange setups where $ENV{HOME} is a relative path.

6 months ago(ext)index: eliminate $sync entirely
Eric Wong [Fri, 10 Jan 2025 23:21:00 +0000 (23:21 +0000)] 
(ext)index: eliminate $sync entirely

Finally, the elimination of this variable simplifies subroutine
calls hopefully makes object lifetimes easier to reason about.

6 months ago(ext)index: eliminate $sync->{ibx}
Eric Wong [Fri, 10 Jan 2025 23:20:59 +0000 (23:20 +0000)] 
(ext)index: eliminate $sync->{ibx}

Perhaps the trickiest field to eliminate from $sync {ibx}
due to the way -extindex handles cross-posted messages.  We
now eliminate the per-request $req->{ibx} for non-crossposted
messages and use local-ized $self->{ibx} directly.

6 months ago(ext)index: move {ranges} to $self
Eric Wong [Fri, 10 Jan 2025 23:20:14 +0000 (23:20 +0000)] 
(ext)index: move {ranges} to $self

Another field we can trivially `local'-ize in our quest to
eliminate the clumsy $sync structure.

6 months ago(ext)index: move {unindexed} to $self
Eric Wong [Fri, 10 Jan 2025 23:20:13 +0000 (23:20 +0000)] 
(ext)index: move {unindexed} to $self

As with most things that were formerly in $sync, we can just
rely on `local' to flatten the data structure graph and work
towards eliminating $sync.

6 months agov2writable: hoist out process_todo sub for extindex
Eric Wong [Fri, 10 Jan 2025 23:20:12 +0000 (23:20 +0000)] 
v2writable: hoist out process_todo sub for extindex

We can have consistent $self->{quit} detection this way and
eliminate an early return from index_todo.

6 months agov2writable: {in_unindex} moved to self
Eric Wong [Fri, 10 Jan 2025 23:20:11 +0000 (23:20 +0000)] 
v2writable: {in_unindex} moved to self

{in_unindex} is already local-ized for $sync, so moving it to
$self is trivial since we use ->async_wait_all to ensure
cat-file requests are done.

6 months ago(ext)index: move {todo} into $self
Eric Wong [Fri, 10 Jan 2025 23:20:10 +0000 (23:20 +0000)] 
(ext)index: move {todo} into $self

Another trivial field to `local'-ize and another step towards
eliminating the $sync structure.

6 months agoextindex: simplify data structures used for dedupe
Eric Wong [Fri, 10 Jan 2025 23:20:09 +0000 (23:20 +0000)] 
extindex: simplify data structures used for dedupe

We can stuff more into $self via `local' and eliminate the $per_mid
structure and extra lookups.

6 months agoextindex: move {dedupe_cull} to self
Eric Wong [Fri, 10 Jan 2025 23:20:08 +0000 (23:20 +0000)] 
extindex: move {dedupe_cull} to self

This allows us to eliminate the $per_mid->{sync} field used for
dedupe, as well.

6 months ago(ext)index: eliminate redundant $sync->{epoch_max}
Eric Wong [Fri, 10 Jan 2025 23:20:07 +0000 (23:20 +0000)] 
(ext)index: eliminate redundant $sync->{epoch_max}

We already had $self->{epoch_max}, and it's easy enough to
`local'-ize it to ensure it doesn't outlive its usefulness when
-extindex handles multiple inboxes.

6 months ago(ext)index: $sync->{unit} => $self->{unit}
Eric Wong [Fri, 10 Jan 2025 23:20:06 +0000 (23:20 +0000)] 
(ext)index: $sync->{unit} => $self->{unit}

Since we were using `local' anyways on the $sync hashref, it's a
trivial swap to move it into $self.

6 months agov2writable: eliminate $sync->{art_end}
Eric Wong [Fri, 10 Jan 2025 23:20:05 +0000 (23:20 +0000)] 
v2writable: eliminate $sync->{art_end}

Instead of creating a long-lived {art_end} entry or even
local-izing it in $self, pass the `$art_end' value on stack to
achieve symmetry with the existing `$arg_beg' arg in calls to
index_xap_step().

6 months agoextindex: eliminate repeated ->eidx_key method call
Eric Wong [Fri, 10 Jan 2025 23:19:04 +0000 (23:19 +0000)] 
extindex: eliminate repeated ->eidx_key method call

No need to make two relatively expensive `->' method calls when
one will do.

6 months ago(ext)index: eliminate most uses of `$sync->{ibx}'
Eric Wong [Fri, 10 Jan 2025 23:19:03 +0000 (23:19 +0000)] 
(ext)index: eliminate most uses of `$sync->{ibx}'

Yet another step towards eliminating the $sync structure.
There's still a few remaining dependencies due to cross-inbox
linkage but the goal is to reduce refcount traffic for the
majority of Inbox object references.  This field in $sync will
be completely eliminated in the next few commits.

6 months agov2writable: move {mm_tmp} to $self
Eric Wong [Fri, 10 Jan 2025 23:19:02 +0000 (23:19 +0000)] 
v2writable: move {mm_tmp} to $self

Another variable we can easily local-ize to limit scope and
reduce refcount traffic from copying into the per-cat_async $arg
structure.

6 months agosearchidx: eliminate $sync from subroutines
Eric Wong [Fri, 10 Jan 2025 23:19:01 +0000 (23:19 +0000)] 
searchidx: eliminate $sync from subroutines

Eliminating this variable will hopefully reduce cognitive
overhead as well as reducing overhead from argument passing.

6 months agoindex: move {reindex} to $self
Eric Wong [Fri, 10 Jan 2025 23:19:00 +0000 (23:19 +0000)] 
index: move {reindex} to $self

Again, we can easily contain the scope of {reindex} to $self via
`local', so there's no need to rely on another temporary structure.

6 months agoindex: move {D} (delete state) to $self
Eric Wong [Fri, 10 Jan 2025 23:18:59 +0000 (23:18 +0000)] 
index: move {D} (delete state) to $self

The {D} delete state is short-lived and may have its scope
limited via `local', so take another step towards reducing
internal data structures.

6 months ago(ext)index: move {max_size} and related bits to $self
Eric Wong [Fri, 10 Jan 2025 23:18:58 +0000 (23:18 +0000)] 
(ext)index: move {max_size} and related bits to $self

`--max-size' is persistent for a process, so having it in $self
is more appropriate anyways than the shorter-lived $sync.  The
{index_oid} function pointer is tied to max-size handling, so
we'll move that over to $self as well.

6 months agosearchidx: rename {sidx} to {self}
Eric Wong [Fri, 10 Jan 2025 23:18:57 +0000 (23:18 +0000)] 
searchidx: rename {sidx} to {self}

While this is v1-only code, {self} is more consistent with the
rest of the code and the eventual goal is to eliminate $sync
entirely in favor of $self for temporary state.

6 months agosearchidx: move {ntodo} to $self
Eric Wong [Fri, 10 Jan 2025 23:18:56 +0000 (23:18 +0000)] 
searchidx: move {ntodo} to $self

Another step towards eliminating the temporary $sync structure
to flatten the internal data structures.

6 months agoextindex: move {id2pos} to $self
Eric Wong [Fri, 10 Jan 2025 23:18:55 +0000 (23:18 +0000)] 
extindex: move {id2pos} to $self

{id2pos} doesn't need a different hash table entry for every
request, instead it is tied to the inboxes associated with the
ExtSearchIdx ($self) object so we can just store it and give it
the same lifetime as the associated inbox references.

6 months agoextindex: {boost_in_use} field to $self
Eric Wong [Fri, 10 Jan 2025 23:18:16 +0000 (23:18 +0000)] 
extindex: {boost_in_use} field to $self

There's no need to repeatedly propagate this field to every
cat-file blob request since this field is tied to the attached
config and inboxes associated with an inbox.

6 months ago(ext)index: move {quit} from $sync to $self
Eric Wong [Fri, 10 Jan 2025 23:18:15 +0000 (23:18 +0000)] 
(ext)index: move {quit} from $sync to $self

No need to localize it, either, since we don't expect to
use the $self instance after {quit} is set.

6 months ago(ext)index: avoid needless {git} ref with --max-size
Eric Wong [Fri, 10 Jan 2025 23:18:14 +0000 (23:18 +0000)] 
(ext)index: avoid needless {git} ref with --max-size

We can access the PublicInbox::Git object via {ibx} directly to
avoid redundant refs and cut down the $sync struct further.

6 months agosearchidx: prefix v1 code with `v1_'
Eric Wong [Fri, 10 Jan 2025 23:18:13 +0000 (23:18 +0000)] 
searchidx: prefix v1 code with `v1_'

Since there's no or v1-specific modules such as `V1Writable',
prefixing v1-specific subs seems like a prudent way to demarcate
subs used for dealing with the old v1 storage format.

We'll also take this opportunity to rearrange the order of subs
to take advantage of prototypes and compile-time checking with
`perl -c'.

6 months agosmsg->populate: rename $sync to $cmt_info
Eric Wong [Fri, 10 Jan 2025 23:18:12 +0000 (23:18 +0000)] 
smsg->populate: rename $sync to $cmt_info

We only use this hashref to propagate author and commit time
from the commit, so give it a more descriptive name rather than
overloading the to-be-eliminated `$sync' struct.  There's no
need to explicitly vivify into a hashref, either.

6 months ago(ext)index: move {latest_cmt} to $self (from $sync)
Eric Wong [Fri, 10 Jan 2025 23:18:11 +0000 (23:18 +0000)] 
(ext)index: move {latest_cmt} to $self (from $sync)

No more sigil and brace overload from ${$sync->{latest_cmt}}
and another step towards $sync elimination.

6 months ago(ext)index: move {-regen_fmt} from $sync to $self
Eric Wong [Fri, 10 Jan 2025 23:18:10 +0000 (23:18 +0000)] 
(ext)index: move {-regen_fmt} from $sync to $self

We rely on `local' anyways in some cases.  This is yet another
step towards eliminating the $sync structure.

6 months ago(ext)index: move {-opt} from $sync to $self
Eric Wong [Fri, 10 Jan 2025 23:18:09 +0000 (23:18 +0000)] 
(ext)index: move {-opt} from $sync to $self

Another step towards eradicating the $sync structure.

This intermediate step does introduce the $self arg into
log2stack() and prepare_stack() but $self will eventually
eliminate $sync entirely.

6 months ago(ext)index: ${$sync->{nr}} to $self->{nrec}
Eric Wong [Fri, 10 Jan 2025 23:18:08 +0000 (23:18 +0000)] 
(ext)index: ${$sync->{nr}} to $self->{nrec}

{nrec} is probably less confusing as a name in a long-lived
context and we can get rid of the awkward scalar dereferencing
by using $self.

6 months agoExtMsg, NewsWWW: account for publicinbox.nameIsUrl
Eric Wong [Wed, 8 Jan 2025 10:12:05 +0000 (10:12 +0000)] 
ExtMsg, NewsWWW: account for publicinbox.nameIsUrl

As with WwwListing, these generate full URLs which go across
multiple inboxes, so support the new publicinbox.nameIsUrl
feature which allows users with many inboxes on the same domain
to avoid setting `publicinbox.*.url' for each one.

6 months agot/lei-sigpipe.t: use correct pipe size
Alyssa Ross [Tue, 7 Jan 2025 17:46:23 +0000 (18:46 +0100)] 
t/lei-sigpipe.t: use correct pipe size

According to fcntl(2), Linux will round up pipe sizes lower than a
page to a whole page.  Additionally, the kernel may use a larger size
in general, "if that is convenient for the implementation".  The
actual size of the pipe is returned from fcntl, so the test should use
that return value, rather than assuming the size requested was
accepted exactly.  This fixes the test on my system with 16K pages.

6 months agoextindex: use nproc_shards directly from IPC
Eric Wong [Thu, 2 Jan 2025 22:50:31 +0000 (22:50 +0000)] 
extindex: use nproc_shards directly from IPC

There's no reason to use it from the V2Writable namespace
since it was moved to PublicInbox::IPC in commit
9225145d (ipc: move nproc_shards from v2writable, 2023-03-21)
Import it early via `use' so we can take advantage of prototype
checking while we're at it.

6 months agowatch: don't propagate header changes to other inboxes
Eric Wong [Wed, 1 Jan 2025 23:11:53 +0000 (23:11 +0000)] 
watch: don't propagate header changes to other inboxes

Message-IDs may be appended by v2 inboxes for messages with with
conflicting Message-IDs or SpamAssassin (or another spam filter)
can change headers of both v1 and v2 messages.  So we rely on
`local' to reach into Eml internals to localize ->header_set
modifications and rely on modern Perl having copy-on-write
scalars to minimize memory traffic in the common case.

6 months agowatch: import_eml: avoid Eml dup for non-scrub case
Eric Wong [Mon, 30 Dec 2024 22:28:46 +0000 (22:28 +0000)] 
watch: import_eml: avoid Eml dup for non-scrub case

Most inboxes don't use filters, so the destructive ->scrub won't
be called and we can avoid duplicating the Eml object in the
common case.  We'll also drop the last inbox optimization for
net_cb since it's likely unnecessary given that filters are not
very common.

This may be more noticeable for users who map multiple inboxes
to a single Maildir|IMAP|NNTP source.

6 months agowatch|mda|purge: Filter::*->scrub is destructive
Eric Wong [Mon, 30 Dec 2024 22:28:45 +0000 (22:28 +0000)] 
watch|mda|purge: Filter::*->scrub is destructive

-watch was failing to properly account for inboxes having
different filters and ->scrub behavior during message removal
(but not adds).  Explicitly duplicate and simplify the -watch
code for handling message removal and update the rest of the
callers to reflect the standardized destructive behavior of
->scrub.  While most filters were destructive anyways, the Vger
filter was a notable exception and updated to be destructive.

We'll also update some variables from `$mime' uses to `$eml' to
reflect the switch from (Email|PublicInbox)::MIME to
PublicInbox::Eml years ago.

Finally, the Vger filter includes updated comments and uses
v5.10.1+ features, now.

6 months agotest_common: support `require_mods "v2"' for v2 inboxes
Eric Wong [Wed, 1 Jan 2025 22:36:59 +0000 (22:36 +0000)] 
test_common: support `require_mods "v2"' for v2 inboxes

For our purposes, `v2' should be interpreted as a public-inbox
format and not as a Perl version (e.g. `use v5.12').  This ensures
v2index-late-dupe.t correctly depends on DBD::SQLite and git
v2.6+ via `require_mods "v2"' instead of requiring Perl v2.x.

On a side note, it's unlikely public-inbox-v3 format will ever
be necessary as the v2 format appears scalable enough; thus we
won't hit v5 and risk conflicting with in-use Perl versions.
However, I'm not ruling out a v2.112 format for (nearly)
transparent v1->v2 migrations.

6 months agowatch: don't count invalid paths against batch limit
Eric Wong [Thu, 26 Dec 2024 21:48:51 +0000 (21:48 +0000)] 
watch: don't count invalid paths against batch limit

Invalid paths such as `.', `..', `.mh_sequence', and perhaps
other implementation-specific files may throw off the count and
cause premature commits.  While the premature commit isn't too
harmful in the common case, it's possible a pathological case of
having too many non-mail entries in a directory can cause
noticeable slowdowns and storage wear.

So have _try_path() and _remove_spam() return a true value if
a file was actually read.  We'll also simplify the $inboxes
check by relying simply on `eq', since the `ref' check isn't
necessary as the `eq' against a ref will never match the
"watchspam" literal.

7 months agoimport: fix space calculation when reusing epochs
Eric Wong [Tue, 17 Dec 2024 21:27:37 +0000 (21:27 +0000)] 
import: fix space calculation when reusing epochs

Dividing the result of $git->packed_bytes by $PACKING_FACTOR
_twice_ was completely wrong for v2.  Just calculate
$unpacked_bytes once and use it for the Import->{bytes_added}
field.  The calculation for lei/store was actually correct,
just redundant since repeated division is unnecessary.

7 months agov2writable: simplify epoch directory generation
Eric Wong [Tue, 17 Dec 2024 21:27:36 +0000 (21:27 +0000)] 
v2writable: simplify epoch directory generation

As noted in a now-removed comment, InboxWritable->git_dir_latest
seems redundant and an unnecessary function.  Instead, we can
use MultiGit->epoch_dir for these v2-only (non-extindex)
codepaths.

7 months agot/filter_base: relax Regexp class match with ->isa
Eric Wong [Fri, 13 Dec 2024 18:36:31 +0000 (18:36 +0000)] 
t/filter_base: relax Regexp class match with ->isa

It would be nice to support alternative Regexp engines such
as re::engine::PCRE2 in the future.  The exact ref() name
can't match, however ->isa() works with re::engine::PCRE2.
So future-proof our code for potential changes in case PCRE2
becomes usable.

7 months agolei: use PublicInbox::Eml::warn_ignore_cb
Eric Wong [Sat, 14 Dec 2024 14:58:04 +0000 (14:58 +0000)] 
lei: use PublicInbox::Eml::warn_ignore_cb

The open-coded callback was identical to the existing callback
generated by our Eml package, so just use the existing code
instead unless a user uses `lei import --noisy'

7 months agoadmin: common warn_cb
Eric Wong [Sat, 14 Dec 2024 14:58:03 +0000 (14:58 +0000)] 
admin: common warn_cb

I noticed verbose output from t/extsearch.t was not correctly
commenting out (`# ') informational messages when the
{current_info} prefix is in use.  This also appears to affect
other indexers with the exception of the new -cindex.

So consolidate all the common warning code into
PublicInbox::Admin module so we can handle {current_info}
properly in all contexts.

-cindex gets some unnecessary Eml warning filtering, but that's
probably not a real problem and worth the overall code savings
since PublicInbox::Admin is loaded by script/public-inbox-cindex
anyways.

7 months agot/extindex: add --max-size test
Eric Wong [Sat, 14 Dec 2024 14:58:02 +0000 (14:58 +0000)] 
t/extindex: add --max-size test

I noticed this missing coverage while working on another
series of changes which aren't quite ready, yet.

7 months agosearchidx: consolidate checkpoint accounting
Eric Wong [Thu, 12 Dec 2024 10:10:40 +0000 (10:10 +0000)] 
searchidx: consolidate checkpoint accounting

We can eliminate check_batch_limit() and checkpoint_due() from
extsearchidx in favor of update_checkpoint() in searchidx.  We
can also get rid of the awkward scalar deref for setting the
{need_checkpoint} field.

The only behavioral difference is the checkpoint interval is
standardized to 5s and -extindex no longer uses 10s for its
checkpoints.  In retrospect, 5s should work more nicely for
public-facing indices since they spend less time waiting on
writers, but it has the downside of potentially hurting writer
performance.

This is another step in the gradual shift away from the $sync
arg in favor of `local $self->{...}'.

7 months agoextindex: move {checkpoint_unlocks} to $self
Eric Wong [Thu, 12 Dec 2024 10:10:39 +0000 (10:10 +0000)] 
extindex: move {checkpoint_unlocks} to $self

One small step towards eliminating the $sync structure.

7 months agosearchidx: update_checkpoint: take bytes arg directly
Eric Wong [Thu, 12 Dec 2024 10:10:38 +0000 (10:10 +0000)] 
searchidx: update_checkpoint: take bytes arg directly

Passing $smsg limits flexibility in case we reuse it for deletes
and/or commit search.

7 months agoover_idx: simplify each_by_mid
Eric Wong [Wed, 11 Dec 2024 08:10:47 +0000 (08:10 +0000)] 
over_idx: simplify each_by_mid

Eliminate a useless use of `map {}' and avoid a needless `push'
op since the `join' op can just take extra arg.

7 months agocindex: adjust estimated memory cost for deletes
Eric Wong [Wed, 11 Dec 2024 08:10:46 +0000 (08:10 +0000)] 
cindex: adjust estimated memory cost for deletes

Based on my conversations with the Xapian lead, the cost of
deletes were overestimated by 7x in cindex.  Adjust the estimate
cost of a deleted document to a more reasonable number based on
calculations discussed on the xapian-discuss list.

In any case, all of our batch size memory cost estimates are
rough since since Xapian provides no way of letting us know the
memory cost of the current transaction.

7 months agolei/store: use global checkpoint interval
Eric Wong [Wed, 11 Dec 2024 08:10:45 +0000 (08:10 +0000)] 
lei/store: use global checkpoint interval

Maybe this can be made configurable at some point, but it
probably needs to be stored in the config since per-invocation
intervals won't work when multiple lei clients can be writing to
the lei/store.

7 months ago(ext)index: use time-based commits to avoid busy timeout
Eric Wong [Wed, 11 Dec 2024 08:10:44 +0000 (08:10 +0000)] 
(ext)index: use time-based commits to avoid busy timeout

With public-facing read-only daemons typically run from a
different user than writers, we cannot rely on SQLite WAL
(write-ahead-log) for parallelism since all readers need write
permissions on read-write FSes to read from WAL DBs.  Since we
can't force or even encourage WAL use for public-facing inboxes,
we need to ensure long-running --reindex jobs can commit
occasionally to prevent read-only daemons from hitting the
default 30s busy_timeout set by DBD::SQLite (not SQLite itself).

This mainly affects --reindex users, but can also affect
newly-cloned inboxes which are being served by read-only
daemons while they're being indexed.

This change only benefits read-only processes, and is likely to
penalize writer performance and storage efficiency due to
increased write frequency.  We still maintain and respect
--batch-size for memory sized-based commits in addition to
time-based commits, but the new time-based commit interval is
necessary in case the batch size is too large or the system
is too slow to index a large batch.

While Xapian doesn't need time-based commits for read
parallelism, we commit to Xapian anyways since we want to
minimize consistency problems on interrupted indexing jobs.

Followup-to: 807abf67e14d (lei/store: auto-commit for long-running imports, 2024-11-15)
7 months agosearch_query: drop CR (`\r') from queries
Eric Wong [Mon, 9 Dec 2024 20:57:49 +0000 (20:57 +0000)] 
search_query: drop CR (`\r') from queries

w3m (and presumably other browsers) send CRLF instead of LF for
queries made from <textarea> from the VCS view.  CRs require
unnecessary escaping and make RLs look ugly, so omit them
to cleanup URLs and reduce memory traffic in Xapian.

7 months agosolver: fix and improve ambiguous OID debug messages
Eric Wong [Mon, 9 Dec 2024 20:01:28 +0000 (20:01 +0000)] 
solver: fix and improve ambiguous OID debug messages

Ambiguous messages from git start with "hint:" (at least
nowadays) so we need to account for that in the regexp.
Furthermore, do not limit objects to just blobs since our
ViewVCS package is capable of displaying tags, trees, and
commits in addition to blobs.

Finally, we can generate full URLs so linkification can pick
them up and generate <a> tags.

7 months agov2: don't set No_COW for git repos
Eric Wong [Sat, 7 Dec 2024 02:05:48 +0000 (02:05 +0000)] 
v2: don't set No_COW for git repos

Unlike Xapian and SQLite DBs, data stored in git is both
precious and written sequentially.  Thus disabling copy-on-write
doesn't make sense for git objects since the problems with
copy-on-write don't apply here while the benefits of CoW do.

7 months agoSQLiteUtil: hoist out common create_db code
Eric Wong [Wed, 4 Dec 2024 19:39:14 +0000 (19:39 +0000)] 
SQLiteUtil: hoist out common create_db code

We want all SQLite files we create to respect the current umask
and disable CoW for random access performance.

7 months agosqlite: use `BLOB' column type instead of `VARBINARY'
Eric Wong [Wed, 4 Dec 2024 19:39:13 +0000 (19:39 +0000)] 
sqlite: use `BLOB' column type instead of `VARBINARY'

`VARBINARY' isn't actually a documented type for SQLite but
rather the result of MySQL infecting my mind decades ago.
`BLOB' gives it the proper affinity and probably makes it easier
for 3rd-party and one-off scripts to deal with such columns and
should also make things more familiar to existing users.
Surprisingly, this appears to have no functional change with
forward or backwards compatibility since we ->bind_param binary
data with SQL_BLOB on INSERTs anyways to prevent the flexible
typing of SQLite from trying to guess types for us.

7 months agosqlite: avoid incorrect/deprecated `LIKE' use
Eric Wong [Wed, 4 Dec 2024 19:39:12 +0000 (19:39 +0000)] 
sqlite: avoid incorrect/deprecated `LIKE' use

The `case_sensitive_like' pragma is deprecated since
SQLite 3.44+.  Furthermore, our use of `LIKE' in SharedKV->keys
seemed to be broken anyways since `LIKE' doesn't seem to
work with binary data (stored with SQL_BLOB), but neither does
`GLOB'.

So avoid `LIKE' entirely.  For non-SQL_BLOB data we'll favor the
always-case-sensitive GLOB.  For SQL_BLOB data, we must rely on
the Perl regexp engine from what I can tell.  `GLOB' is
preferred where possible since SQLite will be able to use
indices in some cases whereas `REGEXP' cannot.

Fixing SharedKV->keys should improve bash completion for lei.

Some common SQLite-related utilities are now in a
PublicInbox::SQLiteUtil package which will be expanded to deal
with more commonalities between SQLite users in our tree.

7 months agodaemon: improve warning on missing SO_ACCEPTFILTER
Eric Wong [Sat, 30 Nov 2024 22:59:05 +0000 (22:59 +0000)] 
daemon: improve warning on missing SO_ACCEPTFILTER

I noticed tests were failing on a freshly booted FreeBSD
instance due to the accf_http module not being loaded and
triggering autodie-generated error messages from setsockopt.
Instead, give a helpful warning message for users to use
kldload(8) to load the necessary filter.

We'll also relax tests to ignore the kldload warning and fix an
overzealous use of /.*/ while we're at by using /[^\n]/ instead
to avoid filtering out subsequent lines.

7 months agowqblocked: use per-instance unique timer
Eric Wong [Sat, 30 Nov 2024 08:26:32 +0000 (08:26 +0000)] 
wqblocked: use per-instance unique timer

It was possible to end up with multiple timers being armed on a
busy system from LeiNoteEvent due to the often rapid nature of
renames.  Since ->flush_send will flush all pending messages for
the WQ, it's only necessary to arm a single timer for a given WQ
socket.  This saves some memory and unnecessary wakeups by using
the handy unique timer mechanism in DS.

7 months agosend_cmd: throttle `sleeping on sendmsg' messages
Eric Wong [Fri, 29 Nov 2024 23:54:00 +0000 (23:54 +0000)] 
send_cmd: throttle `sleeping on sendmsg' messages

Emitting a message every 100ms was too much for busy machines.
Throttle it to 1.6s to avoid flooding user terminals by emitting
every 16 sleeps.  A power-of-two (16) was chosen for its
optimization potential via bitwise AND.  Since perl(1) doesn't
do this optimization, we open code the bitwise AND.  I don't
assume an optimizing compiler for Inline::C, either, since I
find working in C far more enjoyable with optimizations off.

7 months agosend_cmd: use (practically) infinite retries for writers
Eric Wong [Fri, 29 Nov 2024 23:53:59 +0000 (23:53 +0000)] 
send_cmd: use (practically) infinite retries for writers

Write tools (-*index, -watch, -mda, lei) should never croak due
to the system being busy.  So make the retry infinite to benefit
users who run several parallel imports at once on a slower
system.  The previous 5s timeout was too close to failing in
my own experience using `lei import' on an old, busy machine.

For lei (inotify || EVFILT_VNODE) watches, we now retry on busy
sockets to avoid loss of FS change notifications.

On the contrary, public-facing read-only interfaces have always
been assumed to constantly be under attack.  Thus continuing to
drop requests due to a lack of kernel memory/buffers is probably
prudent.

7 months agolei/store: use WAL for over.sqlite3
Eric Wong [Fri, 29 Nov 2024 06:45:11 +0000 (06:45 +0000)] 
lei/store: use WAL for over.sqlite3

WAL (write-ahead log) improves parallelism for readers when
they also have write access to the SQLite DB.  While we
can't use WAL for public-inboxes where the -netd processes
are intended to only have read-only permssions, lei/store
always assumes read-write access.

The lei/store */ei15/over.sqlite3 DB was the only SQLite DB used
by lei without WAL.  lei already set WAL for mail_sync.sqlite3
and the saved-searches/*/over.sqlite3 DBs.

Now that all SQLite DBs used by lei are WAL, commit 807abf67
(lei/store: auto-commit for long-running imports, 2024-11-15)
is no longer strictly necessary for parallelism during
long-running imports.  However, 807abf67 may continue to be
useful to minimize the need to refetch after a power outage
during `lei import').

For saved-searches, we'll make use of the new mechanism for
setting {journal_mode} per-instance.

7 months agoxapcmd: suppress opendir + my usage warning
Eric Wong [Wed, 27 Nov 2024 02:35:17 +0000 (02:35 +0000)] 
xapcmd: suppress opendir + my usage warning

Apparently perl gets confused here regardless of autodie, so we
add a parenthese around the subroutine call to disambiguate.
This only appears to happen when the target directory name is a
scalar variable and not if it's a constant and when the result
of opendir isn't explicitly checked.

7 months agolei: avoid repeatedly recreating anonymous subs
Eric Wong [Tue, 26 Nov 2024 21:29:23 +0000 (21:29 +0000)] 
lei: avoid repeatedly recreating anonymous subs

The SIGTERM handler doesn't change, so we can reuse it across
different instances without repeatedly creating a new one since
(AFAIK) perl(1) isn't able to deduplicate identical subs.  In
any case, looping `local $SIG{TERM} = $coderef' reveals a minor
speedup compared to the equivalent `local $SIG{TERM} = sub {...}'.

7 months agoimport: allow $noisy toggle, simplify `lei rediff'
Eric Wong [Tue, 26 Nov 2024 21:29:22 +0000 (21:29 +0000)] 
import: allow $noisy toggle, simplify `lei rediff'

Creating an anonymous sub for $SIG{__WARN__} every time
`lei rediff' is called is wasteful.  Instead, provide a
knob to prevent the unnecessary warning from being emitted
by PublicInbox::Import in the first place so we can use the
existing warn_ignore_cb.

7 months agodevel/try-lei: for interactive testing + debugging
Eric Wong [Mon, 25 Nov 2024 22:27:48 +0000 (22:27 +0000)] 
devel/try-lei: for interactive testing + debugging

This script allows creating a clean lei instance for interactive
testing without modifying a user's current lei $HOME||$XDG_*
directories.  I used this to debug and test fixes leading to
99fc3d76 (v2writable: done: force synchronous awaitpid, 2024-11-19) and
807abf67 (lei/store: auto-commit for long-running imports, 2024-11-15)
fixes for long-running `lei import' runs.

7 months agoimap_searchqp: attempt to suppress error messages harder
Eric Wong [Mon, 25 Nov 2024 08:59:33 +0000 (08:59 +0000)] 
imap_searchqp: attempt to suppress error messages harder

In addition to setting $::RD_ERRORS and $::RD_WARN to `undef'
for parsing the generated $prd object, we'll make those `undef'
on Parse::RecDescent object instantion, too, in an attempt to
reduce test failures.

Furthermore, add a note about the occasional test failure and
maybe somebody else can help us figure it out since it's been
sporadically failing for a while...

Followup-to: 31ca305f28d747a0 (t/imap_searchqp: hopefully fix test reliability, 2024-04-28)
Followup-to: fa8bce03925461ef (t/imap_searchqp.t: retry bad query test on failure, 2023-10-10)
7 months agospawn: send_cmd: respect retries arg
Eric Wong [Mon, 25 Nov 2024 07:47:14 +0000 (07:47 +0000)] 
spawn: send_cmd: respect retries arg

Unfortunately, this is hard to test but obvious the
5th arg needs to be used as it is in the pure Perl
and XS implementation.

7 months agolei import: non-noisy by default, add --noisy switch
Eric Wong [Fri, 22 Nov 2024 23:05:57 +0000 (23:05 +0000)] 
lei import: non-noisy by default, add --noisy switch

Email::Address::XS is too noisy by default to be useful given
the poorly formatted messages which exist in history.  Quiet it
down by default since users often don't have the means to fix
such historical messages anyways.

8 months agov2writable: done: force synchronous awaitpid
Eric Wong [Tue, 19 Nov 2024 21:47:52 +0000 (21:47 +0000)] 
v2writable: done: force synchronous awaitpid

We need to shut down shards synchronously to reliably release
the inbox write lock when inside the DS event loop (as the
lei/store subprocess is, unlike most v2writable users).

This seems to fix long-running `lei import' failures to
lei/store after repeated tests.  It is a good idea anyways to
ensure exit status of shard workers are correct before returning
from ->done.

8 months agotreewide: warn on SQLite `PRAGMA optimize' failure
Eric Wong [Tue, 19 Nov 2024 21:47:51 +0000 (21:47 +0000)] 
treewide: warn on SQLite `PRAGMA optimize' failure

While `PRAGMA optimize' isn't a strict requirement for proper
functionality anywhere, displaying the failure can help detect
bigger problems in the future in case of failing hardware.

8 months agov2writable: use DS and import now() sub
Eric Wong [Tue, 19 Nov 2024 21:47:50 +0000 (21:47 +0000)] 
v2writable: use DS and import now() sub

There'll be more uses of this function, so import DS
to avoid surprises even though it's pulled in by other
modules, already.

8 months agospamc: autodie for open + sysseek
Eric Wong [Sat, 16 Nov 2024 07:09:53 +0000 (07:09 +0000)] 
spamc: autodie for open + sysseek

autodie allows us to shorten some lines and generate
error messages which are more consistent with the rest
of the codebase.

8 months agoxapcmd: use autodie for numerous syscalls
Eric Wong [Sat, 16 Nov 2024 07:09:52 +0000 (07:09 +0000)] 
xapcmd: use autodie for numerous syscalls

autodie allows us to simplify a multi-line statement for
conditional rename() and improve error message consistency
with the rest of our codebase.

syswrite() error checking was missing before and now exists
trivially due to autodie.

8 months agoadmin: autodie chdir + open
Eric Wong [Sat, 16 Nov 2024 07:09:51 +0000 (07:09 +0000)] 
admin: autodie chdir + open

autodie gives us more consistent error messages and reduces
visual noise on our end.  We can also open() directly into a
hash entry without relying on a temporary variable.

8 months agolei_blob: use autodie for open + seek
Eric Wong [Sat, 16 Nov 2024 07:09:50 +0000 (07:09 +0000)] 
lei_blob: use autodie for open + seek

The numerous open() calls are less noisy on our end and more
consistent.  Our seek() call needed error checking anyways, and
autodie provides it.

8 months agoover: use autodie for open
Eric Wong [Sat, 16 Nov 2024 07:09:49 +0000 (07:09 +0000)] 
over: use autodie for open

autodie improves the consistency of error messages in
most places, so we use it here since there's no detail
lost.

8 months agoindex: use v5.12, remove outdated comment
Eric Wong [Sat, 16 Nov 2024 07:09:48 +0000 (07:09 +0000)] 
index: use v5.12, remove outdated comment

There's no unicode_strings-dependent code in this script, so
v5.12 is safe.  The comment about libeatmydata shouldn't be
necessary for -index any longer since we support --no-fsync
nowadays and Xapian 1.4+ is fairly widespread.

8 months agolei/store: auto-commit for long-running imports
Eric Wong [Fri, 15 Nov 2024 22:23:15 +0000 (22:23 +0000)] 
lei/store: auto-commit for long-running imports

DBD::SQLite (not SQLite itself) sets a 30s busy_timeout which we
currently do not override.  This means readers can wait up to
30s for a writer to finish.  For long imports exceeding 30s,
SQLite readers (for deduplication during import) can die with a
"database is locked" message while the lei/store process holds a
long write transaction open.

Forcing commits every 5s ought to fix the problem in most cases,
assuming commits themselves happen in under 25s (which isn't
always true on slow devices).  5 seconds was chosen since it
matches the default commit interval on ext* filesystems and the
vm.dirty_writeback_centisecs sysctl.

Many (but not all) failures around long-running `lei import'
processes.

8 months agoview: fix obfuscation in message/* attachments
Eric Wong [Fri, 15 Nov 2024 02:59:32 +0000 (02:59 +0000)] 
view: fix obfuscation in message/* attachments

Our address obfuscation currently relies on HTML-escaped output,
so we need to call obfuscate_addrs() after ascii_html().  This
bug only affected rare messages which include another message/*
attachment.  Without this fix it didn't fail to obfuscate, but
rather showed the showed `&#8226;' in the HTML instead of the
entity it represents.

8 months agoview: reduce ops for <b> encasement
Eric Wong [Fri, 15 Nov 2024 02:59:31 +0000 (02:59 +0000)] 
view: reduce ops for <b> encasement

We can rely on print to concatenate its args and
reduce the amount of needless copies and string ops before the
print.

8 months agonntp: integerize {article} to save memory
Eric Wong [Fri, 15 Nov 2024 02:59:30 +0000 (02:59 +0000)] 
nntp: integerize {article} to save memory

The NNTP article number is always an integer, so ensure it's
stored as one to avoid malloc overhead since NNTP clients may
linger for minutes at a time.

8 months agonntp: improve protocol error messages
Eric Wong [Fri, 15 Nov 2024 02:59:29 +0000 (02:59 +0000)] 
nntp: improve protocol error messages

NNTP clients (e.g. lei :P) may display the message from the
server, so it's helpful to tell them the article number or
Message-ID that's missing.

8 months agotest_common: disable fsync in git(1) commands
Eric Wong [Fri, 15 Nov 2024 02:59:28 +0000 (02:59 +0000)] 
test_common: disable fsync in git(1) commands

As with git itself, fsync(2) results in needless overhead and
storage wear in test cases where data integrity is not an issue.
I normally point TMPDIR to tmpfs when running tests, but this
still affects initial setup of data for stuff in t/data-gen as
well as improving life for users with too little RAM for a tmpfs
TMPDIR.

8 months agotests: fix missing modules under TEST_RUN_MODE=0
Eric Wong [Fri, 15 Nov 2024 02:59:27 +0000 (02:59 +0000)] 
tests: fix missing modules under TEST_RUN_MODE=0

By default, we rely heavily on preload to speed up tests and
missing modules were always present by the time we hit some
tests.  However, the more realistic (and significantly slower)
TEST_RUN_MODE=0 doesn't preload so we must explicitly load
missing modules.

8 months agolei_mirror: favor File::Spec::Functions
Eric Wong [Tue, 12 Nov 2024 20:34:33 +0000 (20:34 +0000)] 
lei_mirror: favor File::Spec::Functions

Functions calls are preferable over `->' method dispatch in
tight loops.  This can be the case when scanning alternates in
v1_done().  Since we're at it, replace all other `File::Spec->'
method dispatches with function calls since function calls can
be used to validate function prototypes at compile time.

8 months agohval: use File::Spec::Functions::abs2rel
Eric Wong [Tue, 12 Nov 2024 20:34:32 +0000 (20:34 +0000)] 
hval: use File::Spec::Functions::abs2rel

Function calls are faster than method dispatch and abs2rel() may
be called hundreds/thousands of times when listing associated
inboxes||coderepos.

8 months agowww_coderepo: drop unused File::Spec import
Eric Wong [Tue, 12 Nov 2024 20:34:31 +0000 (20:34 +0000)] 
www_coderepo: drop unused File::Spec import

I initially thought File::Spec->abs2rel would be used in this
file, but it turns out `prurl' is a better place to call abs2rel.

8 months agocindex: rework path canonicalization check
Eric Wong [Tue, 12 Nov 2024 20:34:30 +0000 (20:34 +0000)] 
cindex: rework path canonicalization check

While reading the code, I noticed inadvertant `$_' use when the
loop iterator is  `$d'.  Using `$_' here would result in
uninitialized variable access.  I've yet to hit this case in
real-world access.

Furthermore, we can use a single pass to canonicalize existing
directories instead of relying on a grep block, first.

Finally, favor File::Spec::Functions since `->' method dispatch
is slower than normal subroutine calls by a small amount even
when both the package and method names are static and known
early in advance..

8 months agoview: avoid uninitialized var from diff query textarea
Eric Wong [Mon, 11 Nov 2024 21:56:56 +0000 (21:56 +0000)] 
view: avoid uninitialized var from diff query textarea

Rare commits without titles and emails without a Subject: header
should not litter stderr or syslog with uninitialized variable
warnings.

8 months agoimport: avoid uninitialized comparison on failures
Eric Wong [Mon, 11 Nov 2024 21:56:55 +0000 (21:56 +0000)] 
import: avoid uninitialized comparison on failures

readline may return undef when fast-import fails (as triggered
by t/lei-store-fail.t).  Ensure we give a more informative error
message in the syslog when this happens.  Arguably, having this
in the syslog when a client is connected via terminal is probably
not great, but perhaps unavoidable...

8 months agot/spawn: increase timeout for slow systems
Eric Wong [Mon, 11 Nov 2024 21:56:54 +0000 (21:56 +0000)] 
t/spawn: increase timeout for slow systems

Smetimes the SIGXCPU handler doesn't fire in time on an
overloaded VPS, so hopefully increasing the timeout is now
enough.  The $rset allocation and bitset is now moved before
the spawn to avoid measuring any possible overhead from the
scalar creation.