cpan-authors / IPC-Run

https://metacpan.org/pod/IPC::Run
Other
21 stars 38 forks source link

How to know whether a harness is started #171

Open nrdvana opened 8 months ago

nrdvana commented 8 months ago

I have a situation where I want a generic function that finishes a harness and reports its result, but doesn't know if the caller started the harness yet. The module seems to be missing a "->started" accessor.

I can almost achieve this with 'pump', but that has the chance of throwing an exception if a pipe is broken.

From the code in pump, there is:

$self->start if $self->{STATE} < _started;
croak "process ended prematurely" unless $self->pumpable;

$self->{auto_close_ins} = 0;
$self->{break_on_io}    = 1;
$self->_select_loop;
return $self->pumpable;

I basically just want public access to that first line, and then call ->finish

Would you accept a PR for essentially this?

sub started { $self->{STATE} >= _started }
nmisch commented 8 months ago

Hello. Could you say more about what makes it hard for the application to know whether it has called start()? In other words, why would it be bad for your function to just document that it takes only started harnesses?

In general, the proposed method looks harmless and maintenance-free. On the other hand, every public API has some mental cost for users. I'm happy to have the method if it disproportionately simplifies your application.

nrdvana commented 8 months ago

The function is a logger of external commands, and the usual behavior is to pass it an @argv to make its own harness, execute, and record the exit status. In some cases, I want the full features of IPC::Run pipelines, so I decided to extend its API to pass a harness object or the traditional \@argv. But then, in some cases I want to start the harness in parallel with some other tasks so it has already been started when it reaches the logging function that finishes it and reports the command and its exit code.

If a harness was a one-shot object, this wouldn't be a problem. but because a harness can be run multiple times, it seems generally useful to inspect what state it's currently in so that that state doesn't need to be tracked externally.

nmisch commented 8 months ago

I'd accept such a PR. That said, how well would the following mitigate the trouble with using pump?

eval { $h->pump }; die $@ if $@ and $@ ne 'process ended prematurely';
nrdvana commented 8 months ago

That's sort of what I did in the meantime:

# Start if it isn't already started
eval { $h->pump }

But it would look cleaner for long-term maintenance if it was

$h->start unless $h->started;