[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

XARGS_SEQ code & docs patch

From: C Blake
Subject: XARGS_SEQ code & docs patch
Date: Sun, 28 Oct 2012 15:02:46 -0400
User-agent: Mutt/1.5.21 (2010-09-15)

Hey.  So, in parallel mode it can be very useful for client programs
to know in what sequence xargs executed them.  For example, to generate
output files that are easily re-combined to have output order be
guaranteed to exactly match input order, one might like to do something
like this:

    seq 1 9 | xargs -n2 -P2 sh -c "echo $$ > $XARGS_SEQ"
    cat out.*

In serial/-P1 mode a client program could always maintain this state
in the filesystem (e.g. sharing the output file with appending, etc.).
In parallel mode it makes more sense for xargs itself to maintain and
export this information than for clients to implement more complex
machinery to re-construct it.

For example, a high-resolution time stamp read by clients at start-up
approximately works, but is subject to a race condition -- before the
first child gets scheduled to read the time, xargs and the OS may have
started the next child.  That rare case would result in the child for
later input reading an earlier time than the child for earlier input.
There are convolutions clients may use to ensure reliable sequencing,
but it seems simpler overall for xargs to provide a reliable number.

An environment variable is one simple and natural method for exporting
said number to client programs.  E.g., GNU parallel has a $PARALLEL_SEQ
(as well as a {#} substituted into the command feature).  Of course,
one does not always need or want the complexity of GNU parallel.

The attached patch file should apply cleanly to the current version
control findutils.  It implements and documents this new feature.

Besides whether maintainers find this feature useful enough to add
(which I hope they do) there are a five possible issues or points
of possible disagreement - the name of the variable, zero padding,
the environment overhead adjustment and the range of the counter.
The name is trivial.  I motivate other implementation choices below.

Filename generation by shells is usually lexicographically sorted.
Padding makes makes "cat out.*" generally just "do the right thing" when
text matching "*" comes from $XARGS_SEQ values as in my initial example.
Padding is a non-critical choice as users can either remove 0-padding
by using, e.g., `echo $XARGS_SEQ | sed 's/\<0*//'`, or add it using,
e.g., `printf %09d $XARGS_SEQ`.  (Numbers start at 1.  So, lone 0s do
not occur.)  Personally, I think it easiest for xargs to pad and for
clients to remove the 0s in the (I believe) rare cases when padding is
undesired.  So, my patch pads.  One could also allow users to specify
what they want with a new command-line option, but simply settling on
one way or the other is probably adequate.

Padding to a fixed size variable also simplifies adjusting the POSIX
compliance 2048 byte head room calculation which I also tried to update.
It's a bit open to interpretation whether any adjustment is even needed
since setting the variable at all is not in POSIX and $XARGS_SEQ might
conceptually "count" as a client program variable.  However, my patch
assumes one wants a more conservative interpretation since the intent
of the limit seems to be to let client programs assume they can use at
least 2048 bytes more environment data over what xargs uses.  So, the
patch bumps the headroom by the amount used by XARGS_SEQ.  Because we
just use a flat 20 + 8, we bump by slightly more than we use on CPU
architectures with smaller than 8 byte pointers.  That is easy enough
to fine-tune if adjustment precision is the only deal breaker, though.

One might also want to only provide the variable in parallel mode.
That also makes the adjustment slightly more work, and there are uses
for XARGS_SEQ in serial mode (granted, those uses may have simple
enough workarounds, unlike true parallel operation).  It's probably
simpler to explain to users that it is just always provided.

The fourth objection I can foresee at the moment might be using only a
4 byte counter.  At 100,000 jobs per seconds, 4 GigaJobs might overflow
the counter in just 12 hours.  On the other hand, 4 GigaJobs is an awful
lot of jobs.  Combining 4 billion outputs (i.e. actually using the full
range of the counter) is unlikely to be the way this feature is applied.
On yet another hand, xargs has always largely been about avoiding system
limit problems.  In any case, it's probably easy to change to 8 bytes
if desired.

Attachment: xargs_seq.patch
Description: Text Data

reply via email to

[Prev in Thread] Current Thread [Next in Thread]