Hi everyone.  Rob emailed me about dpkg triggers and said he was happy
to redirect this.  I think it's probably best to have the conversation
on a public list.  (Please retain the CC to me, since I don't reliably
read debian-emacsen.)

Rob Browning writes ("dpkg trigger questions (and/or broader emacs add-on 
options)"):
> Hey, Sean mentioned your discussion about triggers, and I ended up first
> thinking that it might mean triggers wouldn't work for our purposes, but
> now I'm not so sure, and wondered if you might have time to discuss that
> a bit.  (However, if you don't have time for this right now, no
> worries.)

I'll try.

Firstly, a disclaimer: it's been a very long time since I did all
this, so I am likely to have misremembered some things - it's likely
that at least something I'm going to say is false.  It now seems to me
from what you quote here, and my reading of the doc, that some of the
things I said to Sean on irc were false.

Some background: the principal design goal of triggers was to make it
possible to optimise away redundant work by delaying work until the
end of processing.

Before triggers, the principle was that every package's postinst would
do all necessary processing.  In the presence of multiple interacting
packages, that can mean processing more than once: typically, once for
each interacting package.

Also, some tasks are much more efficient when performed in aggregate:
for example, adding soemthing to the initramfs is done by rebuilding
the initramfs, so postponing initramfs rebuilding can help a lot with
install performance.

The model assumes that the "interested" package is more central and
lower in the dependency stack.

> What led us to the current attempt to rework emacsen-common / emacs
> policy is the realization that dpkg doesn't actually promise much about
> the state of a package's dependencies during maintainer script
> invocations, outside of "postinst configure",

I'm not sure why that's a problem for emacs addons.  In this scheme
you only need to run *compilation* of some addon during that addon's
postinst, and the postinst of the emacs flavour.  In each case you can
do processing only of packages that are `configured`, plus this one.

The cleanup tasks don't seem like they'd need much in the way of
working dependencies.

I mention all this because I want to make sure we all have a proper
understanding.

> One thing I wondered about was this triggers.txt statement:
> 
>   Packages in t-awaited and t-pending demand satisfaction of their
>   dependencies just like packages in installed.
> 
> Does that mean that all of the dependencies of a package in one of those
> states should be past their postinst configure, or something else?

Yes, I think so.

However, note that dpkg does *not* bring packages out of `installed`
just because their dependencies regress to less good states, provided
the dependency isn't actually removed.

> So one of the options I've been considering is to switch to triggers
> (and dropping the attempt to promise that once an add-on's postinst
> configure finishes it's "ready").

ISTM that you ought to aim to promise that once an add-on is in state
`installed` it is ready (subject to the caveat above).  That would
mean any things that invoke the addon, and Depend on it, will work
properly.

I think this means that an addon with old bytecode needs to be either
in `unpacked`, or `triggers-awaited`.  Assuming we're using triggers,
that means the addon which needs rebuilds is in `triggers-awaited`.

Let's consider three packages: emacsen package E (of some flavour);
addon packages A and B where B uses features from A.

When we reinstall A we need to rebuild both it and B.

We could achive this by doing it in A's postinst but in a large run
it'll probably have to done again later, eg if emacsen are being
updated too.

Realistically, E must be interested in A, so that A gets rebuilt.  (We
don't want to do this the other way around, because that would cause
an emacs to be considered not-`installed` simply because some addon
hadn't been compiled.)

If we update E, E's postinst will need to rebuild both A and B.  So
E's postinst needs to be able to do a topological sort of the addons,
so that it can compile them in the right order.

Given that E's postinst can do the sort, it can reliably recompile
everything.

Ideally, though we'd not recompile unchanged packages lower in the
stack when E's postinst is running for a trigger rather than for
configure.  That optimisation can be done by examining the triggering
package names.

> Given (A) above, I was pondering the possibility of having some
> idempotent "rebuild" trigger that would (assuming we can) just examine
> what add-ons and flavors are ready (i.e. successfully past their
> postinat configures), and rebuild any combinations that are stale[2].
> Both flavors and add-ons would trigger "rebuild".

I think my analysis above has come to the conclusion that something
like that is indeed the best design.

> Of course there are many variants of the idea, depending on what exactly
> our existing semantics allow.
> 
>   [2] One option might be to just do nothing in the trigger until it is
>       invoked when the entire add-on tree is past all of the add-on
>       postinst configures, and then rebuild everything that needs it --
>       i.e. instead of trying to rebuild stale add-ons in any *subtrees*
>       that are ready during intermediate trigger invocations.

dpkg tries to defer trigger processing.  And you mustn't "defer work"
and return success from a trigger processing postinst invocation,
since you might never be called again.  (I guess you could manually
retrigger but this seems fraught and also unnecessary.)

Ian.

-- 
Ian Jackson <ijack...@chiark.greenend.org.uk>   These opinions are my own.  

Pronouns: they/he.  If I emailed you from @fyvzl.net or @evade.org.uk,
that is a private address which bypasses my fierce spamfilter.

Reply via email to