Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package perl-Mojo-IOLoop-ReadWriteProcess for openSUSE:Factory checked in at 2021-12-10 21:52:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Mojo-IOLoop-ReadWriteProcess (Old) and /work/SRC/openSUSE:Factory/.perl-Mojo-IOLoop-ReadWriteProcess.new.2520 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Mojo-IOLoop-ReadWriteProcess" Fri Dec 10 21:52:56 2021 rev:16 rq:939161 version:0.32 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Mojo-IOLoop-ReadWriteProcess/perl-Mojo-IOLoop-ReadWriteProcess.changes 2021-12-09 13:36:25.309801135 +0100 +++ /work/SRC/openSUSE:Factory/.perl-Mojo-IOLoop-ReadWriteProcess.new.2520/perl-Mojo-IOLoop-ReadWriteProcess.changes 2021-12-10 21:53:31.150922660 +0100 @@ -1,0 +2,28 @@ +Fri Dec 10 03:07:40 UTC 2021 - Tina M??ller <timueller+p...@suse.de> + +- updated to 0.32 + see /usr/share/doc/packages/perl-Mojo-IOLoop-ReadWriteProcess/Changes + + 0.32 2021-12-09T18:03:02Z + - Project moved to https://github.com/openSUSE/Mojo-IOLoop-ReadWriteProcess + - Introduce emit_from_sigchld() + - CI moved to GitHub Actions + +------------------------------------------------------------------- +Thu Dec 2 03:07:13 UTC 2021 - Tina M??ller <timueller+p...@suse.de> + +- updated to 0.31 + see /usr/share/doc/packages/perl-Mojo-IOLoop-ReadWriteProcess/Changes + + 0.31 2021-12-01T15:51:06Z + - Fix bad release to cpan + - Enable GitHub Actions for the project + - Fix ReadWriteProcess::Queue as regression of 1e0addb6 + - Fix race on `open3/fork` and `session->register($pid)` call -- second attempt + - Fix `args` processing + - Fix race of SIG{CHLD} handler setup + - Fix _getlines() to avoid extra newline (\n) in scalar context + - Session: Do not set SIG{CHLD} handler twice + - Match on 'armv7l' as well as 'arm' for prctl detection + +------------------------------------------------------------------- Old: ---- Mojo-IOLoop-ReadWriteProcess-0.28.tar.gz New: ---- Mojo-IOLoop-ReadWriteProcess-0.32.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Mojo-IOLoop-ReadWriteProcess.spec ++++++ --- /var/tmp/diff_new_pack.uFY7ih/_old 2021-12-10 21:53:31.710922908 +0100 +++ /var/tmp/diff_new_pack.uFY7ih/_new 2021-12-10 21:53:31.714922910 +0100 @@ -1,7 +1,7 @@ # # spec file for package perl-Mojo-IOLoop-ReadWriteProcess # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,35 +16,31 @@ # -# Do not change this file manually, use cpanspec.yml instead - +%define cpan_name Mojo-IOLoop-ReadWriteProcess Name: perl-Mojo-IOLoop-ReadWriteProcess -Version: 0.28 +Version: 0.32 Release: 0 -%define cpan_name Mojo-IOLoop-ReadWriteProcess Summary: Execute external programs or internal code blocks as separate process License: Artistic-1.0 OR GPL-1.0-or-later -Group: Development/Libraries/Perl URL: https://metacpan.org/release/%{cpan_name} Source0: https://cpan.metacpan.org/authors/id/S/SZ/SZARATE/%{cpan_name}-%{version}.tar.gz Source1: cpanspec.yml BuildArch: noarch -BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: perl BuildRequires: perl-macros BuildRequires: perl(IPC::SharedMem) BuildRequires: perl(Module::Build) >= 0.400500 -BuildRequires: perl(Mojolicious) >= 7.24 -BuildRequires: perl(Test::More) >= 0.98 +BuildRequires: perl(Mojolicious) +BuildRequires: perl(Test::Exception) Requires: perl(IPC::SharedMem) -Requires: perl(Mojolicious) >= 7.24 +Requires: perl(Mojolicious) %{perl_requires} %description Mojo::IOLoop::ReadWriteProcess is yet another process manager. %prep -%setup -q -n %{cpan_name}-%{version} +%autosetup -n %{cpan_name}-%{version} find . -type f ! -path "*/t/*" ! -name "*.pl" ! -path "*/bin/*" ! -path "*/script/*" ! -name "configure" -print0 | xargs -0 chmod 644 %build @@ -54,7 +50,7 @@ %check echo "ignoring unstable tests" echo "https://github.com/mudler/Mojo-IOLoop-ReadWriteProcess/issues/14" -rm t/{07_autodetect,12_mocked_container,04_queues,05_serialize,06_events}.t +rm t/{07_autodetect,12_mocked_container,04_queues,05_serialize}.t ./Build test %install @@ -62,8 +58,7 @@ %perl_gen_filelist %files -f %{name}.files -%defattr(-,root,root,755) -%doc Changes circle.yml codecov.yml minil.toml README.md +%doc Changes codecov.yml minil.toml README.md %license LICENSE %changelog ++++++ Mojo-IOLoop-ReadWriteProcess-0.28.tar.gz -> Mojo-IOLoop-ReadWriteProcess-0.32.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/Build.PL new/Mojo-IOLoop-ReadWriteProcess-0.32/Build.PL --- old/Mojo-IOLoop-ReadWriteProcess-0.28/Build.PL 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/Build.PL 2021-12-09 19:04:50.000000000 +0100 @@ -24,7 +24,7 @@ requires => { 'IPC::SharedMem' => '0', - 'Mojolicious' => '7.24', + 'Mojolicious' => '0', }, recommends => { @@ -37,7 +37,8 @@ }, test_requires => { - 'Test::More' => '0.98', + 'Test::Exception' => '0', + 'Test::More' => '0', }, name => 'Mojo-IOLoop-ReadWriteProcess', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/Changes new/Mojo-IOLoop-ReadWriteProcess-0.32/Changes --- old/Mojo-IOLoop-ReadWriteProcess-0.28/Changes 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/Changes 2021-12-09 19:04:50.000000000 +0100 @@ -1,6 +1,23 @@ Revision history for Perl extension Mojo-IOLoop-ReadWriteProcess +0.32 2021-12-09T18:03:02Z + - Project moved to https://github.com/openSUSE/Mojo-IOLoop-ReadWriteProcess + - Introduce emit_from_sigchld() + - CI moved to GitHub Actions + + +0.31 2021-12-01T15:51:06Z + - Fix bad release to cpan + - Enable GitHub Actions for the project + - Fix ReadWriteProcess::Queue as regression of 1e0addb6 + - Fix race on `open3/fork` and `session->register($pid)` call -- second attempt + - Fix `args` processing + - Fix race of SIG{CHLD} handler setup + - Fix _getlines() to avoid extra newline (\n) in scalar context + - Session: Do not set SIG{CHLD} handler twice + - Match on 'armv7l' as well as 'arm' for prctl detection + 0.28 2020-09-30T11:51:40Z - Avoid executing "blocking stop" code when process has already terminated by Martchus diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/MANIFEST new/Mojo-IOLoop-ReadWriteProcess-0.32/MANIFEST --- old/Mojo-IOLoop-ReadWriteProcess-0.28/MANIFEST 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/MANIFEST 2021-12-09 19:04:50.000000000 +0100 @@ -4,7 +4,6 @@ META.json README.md builder/custom.pm -circle.yml codecov.yml cpanfile lib/Mojo/IOLoop/ReadWriteProcess.pm diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/META.json new/Mojo-IOLoop-ReadWriteProcess-0.32/META.json --- old/Mojo-IOLoop-ReadWriteProcess-0.28/META.json 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/META.json 2021-12-09 19:04:50.000000000 +0100 @@ -4,7 +4,7 @@ "Ettore Di Giacinto <edigiaci...@suse.com>" ], "dynamic_config" : 0, - "generated_by" : "Minilla/v3.1.10", + "generated_by" : "Minilla/v3.1.12", "license" : [ "perl_5" ], @@ -34,29 +34,33 @@ }, "develop" : { "requires" : { + "Devel::Cover" : "0", + "Devel::Cover::Report::Codecovbash" : "0", "Test::CPAN::Meta" : "0", "Test::MinimumVersion::Fast" : "0.04", "Test::PAUSE::Permissions" : "0.07", "Test::Pod" : "1.41", + "Test::Pod::Coverage" : "0", "Test::Spellunker" : "v0.2.7" } }, "runtime" : { "requires" : { "IPC::SharedMem" : "0", - "Mojolicious" : "7.24" + "Mojolicious" : "0" } }, "test" : { "requires" : { - "Test::More" : "0.98" + "Test::Exception" : "0", + "Test::More" : "0" } } }, "provides" : { "Mojo::IOLoop::ReadWriteProcess" : { "file" : "lib/Mojo/IOLoop/ReadWriteProcess.pm", - "version" : "0.28" + "version" : "0.32" }, "Mojo::IOLoop::ReadWriteProcess::CGroup" : { "file" : "lib/Mojo/IOLoop/ReadWriteProcess/CGroup.pm" @@ -140,25 +144,29 @@ "release_status" : "stable", "resources" : { "bugtracker" : { - "web" : "https://github.com/mudler/Mojo-IOLoop-ReadWriteProcess/issues" + "web" : "https://github.com/openSUSE/Mojo-IOLoop-ReadWriteProcess/issues" }, - "homepage" : "https://github.com/mudler/Mojo-IOLoop-ReadWriteProcess", + "homepage" : "https://github.com/openSUSE/Mojo-IOLoop-ReadWriteProcess", "repository" : { - "url" : "git://github.com/mudler/Mojo-IOLoop-ReadWriteProcess.git", - "web" : "https://github.com/mudler/Mojo-IOLoop-ReadWriteProcess" + "url" : "git://github.com/openSUSE/Mojo-IOLoop-ReadWriteProcess.git", + "web" : "https://github.com/openSUSE/Mojo-IOLoop-ReadWriteProcess" } }, - "version" : "0.28", + "version" : "0.32", "x_contributors" : [ + "Adam Williamson <awill...@redhat.com>", "Clemens Famulla-Conrad <cfamullacon...@suse.de>", "Ettore Di Giacinto <mud...@gentoo.org>", "Ettore Di Giacinto <mud...@users.noreply.github.com>", "Marius Kittler <mkitt...@suse.de>", "Mohammad S Anwar <mohammad.an...@yahoo.com>", "Oliver Kurz <ok...@suse.de>", + "Santiago Zarate <229240+foursixn...@users.noreply.github.com>", "Santiago Zarate <santiago+git...@zarate.co>", "Santiago Zarate <santi...@zarate.co>", - "Sebastian Riedel <s...@cpan.org>" + "Sebastian Riedel <s...@cpan.org>", + "cfconrad <40127946+cfcon...@users.noreply.github.com>" ], + "x_serialization_backend" : "JSON::PP version 4.06", "x_static_install" : 0 } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/META.yml new/Mojo-IOLoop-ReadWriteProcess-0.32/META.yml --- old/Mojo-IOLoop-ReadWriteProcess-0.28/META.yml 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/META.yml 2021-12-09 19:04:50.000000000 +0100 @@ -3,12 +3,13 @@ author: - 'Ettore Di Giacinto <edigiaci...@suse.com>' build_requires: - Test::More: '0.98' + Test::Exception: '0' + Test::More: '0' configure_requires: Module::Build: '0.4005' perl: '5.016' dynamic_config: 0 -generated_by: 'Minilla/v3.1.10, CPAN::Meta::Converter version 2.143240' +generated_by: 'Minilla/v3.1.12, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html @@ -27,7 +28,7 @@ provides: Mojo::IOLoop::ReadWriteProcess: file: lib/Mojo/IOLoop/ReadWriteProcess.pm - version: '0.28' + version: '0.32' Mojo::IOLoop::ReadWriteProcess::CGroup: file: lib/Mojo/IOLoop/ReadWriteProcess/CGroup.pm Mojo::IOLoop::ReadWriteProcess::CGroup::v1: @@ -82,20 +83,24 @@ file: lib/Mojo/IOLoop/ReadWriteProcess/Shared/Semaphore.pm requires: IPC::SharedMem: '0' - Mojolicious: '7.24' + Mojolicious: '0' resources: - bugtracker: https://github.com/mudler/Mojo-IOLoop-ReadWriteProcess/issues - homepage: https://github.com/mudler/Mojo-IOLoop-ReadWriteProcess - repository: git://github.com/mudler/Mojo-IOLoop-ReadWriteProcess.git -version: '0.28' + bugtracker: https://github.com/openSUSE/Mojo-IOLoop-ReadWriteProcess/issues + homepage: https://github.com/openSUSE/Mojo-IOLoop-ReadWriteProcess + repository: git://github.com/openSUSE/Mojo-IOLoop-ReadWriteProcess.git +version: '0.32' x_contributors: + - 'Adam Williamson <awill...@redhat.com>' - 'Clemens Famulla-Conrad <cfamullacon...@suse.de>' - 'Ettore Di Giacinto <mud...@gentoo.org>' - 'Ettore Di Giacinto <mud...@users.noreply.github.com>' - 'Marius Kittler <mkitt...@suse.de>' - 'Mohammad S Anwar <mohammad.an...@yahoo.com>' - 'Oliver Kurz <ok...@suse.de>' + - 'Santiago Zarate <229240+foursixn...@users.noreply.github.com>' - 'Santiago Zarate <santiago+git...@zarate.co>' - 'Santiago Zarate <santi...@zarate.co>' - 'Sebastian Riedel <s...@cpan.org>' + - 'cfconrad <40127946+cfcon...@users.noreply.github.com>' +x_serialization_backend: 'CPAN::Meta::YAML version 0.018' x_static_install: 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/README.md new/Mojo-IOLoop-ReadWriteProcess-0.32/README.md --- old/Mojo-IOLoop-ReadWriteProcess-0.28/README.md 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/README.md 2021-12-09 19:04:50.000000000 +0100 @@ -1,4 +1,4 @@ -[](https://travis-ci.org/mudler/Mojo-IOLoop-ReadWriteProcess) [](https://codecov.io/github/mudler/Mojo-IOLoop-ReadWriteProcess?branch=master) +[](https://codecov.io/github/openSUSE/Mojo-IOLoop-ReadWriteProcess?branch=master) [](https://github.com/openSUSE/Mojo-IOLoop-ReadWriteProcess/actions) # NAME Mojo::IOLoop::ReadWriteProcess - Execute external programs or internal code blocks as separate process. @@ -21,7 +21,7 @@ my $output = process( sub { print "Hello\n" } )->start()->wait_stop->getline; # Handles seamelessy also external processes: - my $process = process(execute=> '/path/to/bin' )->args(qw(foo bar baz)); + my $process = process(execute=> '/path/to/bin' )->args([qw(foo bar baz)]); $process->start(); my $line_output = $process->getline(); my $pid = $process->pid(); @@ -174,7 +174,7 @@ # The process will print "Hello User" -Array or arrayref of options to pass by to the external binary or the code block. +Arguments pass to the external binary or the code block. Use arrayref to pass many. ## blocking\_stop diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/circle.yml new/Mojo-IOLoop-ReadWriteProcess-0.32/circle.yml --- old/Mojo-IOLoop-ReadWriteProcess-0.28/circle.yml 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/circle.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,24 +0,0 @@ -version: 2.1 -orbs: - perl: circleci/perl@1.0.0 -workflows: - main: - jobs: - - perl/build: - codecov: true - save-to-artifacts: true - save-to-workspace: true - - perl/test-linux: - matrix: - parameters: - perl-version: - - '5.16' - - '5.18' - - '5.20' - - '5.22' - - '5.24' - - '5.26' - - '5.28' - - '5.30' - requires: - - perl/build \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/cpanfile new/Mojo-IOLoop-ReadWriteProcess-0.32/cpanfile --- old/Mojo-IOLoop-ReadWriteProcess-0.28/cpanfile 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/cpanfile 2021-12-09 19:04:50.000000000 +0100 @@ -1,4 +1,4 @@ -requires 'Mojolicious', '7.24'; +requires 'Mojolicious'; requires 'IPC::SharedMem'; on configure => sub { @@ -7,5 +7,12 @@ }; on test => sub { - requires 'Test::More', '0.98'; + requires 'Test::More'; + requires 'Test::Exception'; }; +on develop => sub { + requires 'Devel::Cover::Report::Codecovbash'; + requires 'Devel::Cover'; + requires 'Test::Pod::Coverage'; + requires 'Test::Pod'; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/lib/Mojo/IOLoop/ReadWriteProcess/Queue.pm new/Mojo-IOLoop-ReadWriteProcess-0.32/lib/Mojo/IOLoop/ReadWriteProcess/Queue.pm --- old/Mojo-IOLoop-ReadWriteProcess-0.28/lib/Mojo/IOLoop/ReadWriteProcess/Queue.pm 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/lib/Mojo/IOLoop/ReadWriteProcess/Queue.pm 2021-12-09 19:04:50.000000000 +0100 @@ -28,6 +28,7 @@ $self->queue->maximum_processes + $self->pool->maximum_processes); until ($self->exhausted) { sleep .5; + $self->session->consume_collected_info; $self->session->_protect( sub { $self->pool->each( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/lib/Mojo/IOLoop/ReadWriteProcess/Session.pm new/Mojo-IOLoop-ReadWriteProcess-0.32/lib/Mojo/IOLoop/ReadWriteProcess/Session.pm --- old/Mojo-IOLoop-ReadWriteProcess-0.28/lib/Mojo/IOLoop/ReadWriteProcess/Session.pm 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/lib/Mojo/IOLoop/ReadWriteProcess/Session.pm 2021-12-09 19:04:50.000000000 +0100 @@ -21,7 +21,9 @@ has collect_status => 1; has orphans => sub { {} }; has process_table => sub { {} }; +has collected_info => sub { [] }; has 'handler'; +has emit_from_sigchld => 1; my $singleton; @@ -43,6 +45,7 @@ } sub enable { + return if $singleton->handler(); $singleton->handler($SIG{CHLD}); $singleton->_protect( sub { @@ -51,8 +54,9 @@ $singleton->emit('SIG_CHLD'); return unless $singleton->collect_status; while ((my $pid = waitpid(-1, WNOHANG)) > 0) { - $singleton->collect($pid => $? => $!); + $singleton->add_collected_info($pid, $?, $!); } + $singleton->consume_collected_info() if ($singleton->emit_from_sigchld()); } }); } @@ -65,7 +69,7 @@ } sub collect { - my ($errno, $status, $pid) = (pop, pop, pop); + my ($self, $pid, $status, $errno) = @_; if ($singleton->resolve($pid)) { $singleton->_collect($pid => $status => $errno); $singleton->emit(collected => $singleton->resolve($pid)); @@ -79,6 +83,17 @@ return $singleton; } +sub consume_collected_info { + while(my $i = shift @{$singleton->collected_info}) { + $singleton->collect(@$i) + } +} + +sub add_collected_info { + shift; + push @{$singleton->collected_info}, [@_]; +} + # Use as $pid => Mojo::IOLoop::ReadWriteProcess sub register { my ($process, $pid) = (pop, pop); @@ -120,7 +135,7 @@ $singleton->all->grep(sub { $_->pid eq $pid })->size == 1; } -sub reset { @{+shift}{qw(events orphans process_table)} = ({}, {}, {}) } +sub reset { @{+shift}{qw(events orphans process_table collected_info handler emit_from_sigchld)} = ({}, {}, {}, [], undef, 1) } # XXX: This should be replaced by PR_GET_CHILD_SUBREAPER sub disable_subreaper { @@ -155,7 +170,7 @@ : ($machine eq "ppc" || $machine eq "ppc64le") ? 171 : $machine eq "ia64" ? 1170 : $machine eq "alpha" ? 348 - : $machine eq "arm" ? 0x900000 + 172 + : ($machine eq "arm" || $machine eq "armv7l") ? 0x900000 + 172 : $machine eq "avr32" ? 148 : $machine eq "mips" ? 4000 + 192 : $machine eq "mips64" ? 5000 + 153 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/lib/Mojo/IOLoop/ReadWriteProcess.pm new/Mojo-IOLoop-ReadWriteProcess-0.32/lib/Mojo/IOLoop/ReadWriteProcess.pm --- old/Mojo-IOLoop-ReadWriteProcess-0.28/lib/Mojo/IOLoop/ReadWriteProcess.pm 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/lib/Mojo/IOLoop/ReadWriteProcess.pm 2021-12-09 19:04:50.000000000 +0100 @@ -1,10 +1,10 @@ package Mojo::IOLoop::ReadWriteProcess; -our $VERSION = '0.28'; +our $VERSION = '0.32'; use Mojo::Base 'Mojo::EventEmitter'; use Mojo::File 'path'; -use Mojo::Util qw(b64_decode b64_encode); +use Mojo::Util qw(b64_decode b64_encode scope_guard); use Mojo::IOLoop::Stream; use Mojo::IOLoop::ReadWriteProcess::Exception; @@ -43,13 +43,12 @@ has [ qw(execute code process_id pidfile return_status), qw(channel_in channel_out write_stream read_stream error_stream), - qw(_internal_err _internal_return _status) + qw(_internal_err _internal_return _status args) ]; has max_kill_attempts => 5; has kill_whole_group => 0; -has args => sub { [] }; has error => sub { Mojo::Collection->new }; has ioloop => sub { Mojo::IOLoop->singleton }; @@ -121,7 +120,7 @@ my ($self, @args) = @_; $self->_diag('Execute: ' . (join ', ', map { "'$_'" } @args)) if DEBUG; - $self->session->enable; + $self->on(collect_status => \&_open_collect_status); my ($wtr, $rdr, $err); $err = gensym; @@ -131,7 +130,6 @@ $self->process_id($pid); # Defered collect of return status and removal of pidfile - $self->on(collect_status => \&_open_collect_status); return $self unless $self->set_pipes(); @@ -150,6 +148,7 @@ my ($self, $pid) = @_; $pid //= $self->pid; + $self->session->consume_collected_info; $self->session->_protect( sub { local $?; @@ -221,6 +220,7 @@ # Separated handles that could be used for internal comunication. my ($channel_in, $channel_out); + if ($self->set_pipes) { $input_pipe = IO::Pipe->new() or $self->_new_err('Failed creating input pipe'); @@ -337,8 +337,6 @@ } $self->process_id($pid); - $self->session->enable; - return $self unless $self->set_pipes(); $self->read_stream($output_pipe->reader) if $output_pipe; @@ -398,7 +396,11 @@ sub restart { $_[0]->is_running ? $_[0]->stop->start : $_[0]->start; } -sub is_running { $_[0]->process_id ? kill 0 => $_[0]->process_id : 0; } +sub is_running { + my ($self) = shift; + $self->session->consume_collected_info; + $self->process_id ? kill 0 => $self->process_id : 0; +} sub write_pidfile { my ($self, $pidfile) = @_; @@ -424,7 +426,7 @@ sub _getlines { return unless IO::Select->new($_[0])->can_read(10); - wantarray ? shift->getlines : join '\n', @{[shift->getlines]}; + wantarray ? shift->getlines : join '', @{[shift->getlines]}; } # Write to the controlled-process STDIN @@ -465,7 +467,7 @@ die "Nothing to do" unless !!$self->execute || !!$self->code; my @args - = $self->args + = defined($self->args) ? ref($self->args) eq "ARRAY" ? @{$self->args} : $self->args @@ -473,18 +475,27 @@ $self->session->enable_subreaper if $self->subreaper; $self->_status(undef); + $self->session->enable; - if ($self->code) { - $self->_fork($self->code, @args); - } - elsif ($self->execute) { - $self->_open($self->execute, @args); - } + { + my $old_emit_from_sigchld = $self->session->emit_from_sigchld; + $self->session->emit_from_sigchld(0); + my $scope_guard = scope_guard sub { + $self->session->emit_from_sigchld($old_emit_from_sigchld); + $self->session->consume_collected_info if ($old_emit_from_sigchld); + }; - $self->write_pidfile; - $self->emit('start'); - $self->session->register($self->pid() => $self); + if ($self->code) { + $self->_fork($self->code, @args); + } + elsif ($self->execute) { + $self->_open($self->execute, @args); + } + $self->write_pidfile; + $self->emit('start'); + $self->session->register($self->pid() => $self); + } return $self; } @@ -645,7 +656,7 @@ my $output = process( sub { print "Hello\n" } )->start()->wait_stop->getline; # Handles seamelessy also external processes: - my $process = process(execute=> '/path/to/bin' )->args(qw(foo bar baz)); + my $process = process(execute=> '/path/to/bin' )->args([qw(foo bar baz)]); $process->start(); my $line_output = $process->getline(); my $pid = $process->pid(); @@ -798,7 +809,7 @@ # The process will print "Hello User" -Array or arrayref of options to pass by to the external binary or the code block. +Arguments pass to the external binary or the code block. Use arrayref to pass many. =head2 blocking_stop diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/minil.toml new/Mojo-IOLoop-ReadWriteProcess-0.32/minil.toml --- old/Mojo-IOLoop-ReadWriteProcess-0.28/minil.toml 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/minil.toml 2021-12-09 19:04:50.000000000 +0100 @@ -1,6 +1,9 @@ name = "Mojo-IOLoop-ReadWriteProcess" -badges = ["travis", "codecov"] +badges = ["codecov", "github-actions/linux"] module_maker="ModuleBuild" [build] build_class = "builder::custom" + +[Metadata.resources] +repository = "https://github.com/openSUSE/Mojo-IOLoop-ReadWriteProcess" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/t/01_run.t new/Mojo-IOLoop-ReadWriteProcess-0.32/t/01_run.t --- old/Mojo-IOLoop-ReadWriteProcess-0.28/t/01_run.t 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/t/01_run.t 2021-12-09 19:04:50.000000000 +0100 @@ -3,13 +3,16 @@ use warnings; use strict; use Test::More; +use Test::Exception; use POSIX; use FindBin; +use IO::Select; use Mojo::File qw(tempfile path); use lib ("$FindBin::Bin/lib", "../lib", "lib"); +use Mojo::IOLoop::ReadWriteProcess qw(process); +use Mojo::IOLoop::ReadWriteProcess::Test::Utils qw(attempt); subtest process => sub { - use Mojo::IOLoop::ReadWriteProcess; my $c = Mojo::IOLoop::ReadWriteProcess->new(); @@ -26,7 +29,6 @@ }; subtest 'process basic functions' => sub { - use Mojo::IOLoop::ReadWriteProcess; my $p = Mojo::IOLoop::ReadWriteProcess->new(); eval { @@ -66,7 +68,6 @@ }; subtest 'process is_running()' => sub { - use Mojo::IOLoop::ReadWriteProcess; my @output; pipe(PARENT, CHILD); @@ -139,7 +140,6 @@ plan skip_all => "You do not seem to have $test_script_sigtrap. The script is required to run the test" unless -e $test_script_sigtrap; - use Mojo::IOLoop::ReadWriteProcess; my $p = Mojo::IOLoop::ReadWriteProcess->new( sleeptime_during_kill => 0.1, execute => $test_script @@ -301,9 +301,13 @@ $p->stop(); }; +subtest 'process(execute =>"/usr/bin/true")' => sub { + plan skip_all => "Missing '/usr/bin/true'" unless -e '/usr/bin/true'; + + is(process(execute => '/usr/bin/true')->quirkiness(1)->start()->wait_stop()->exit_status(), 0, 'Simple exec of "/usr/bin/true" return 0'); +}; + subtest 'process code()' => sub { - use Mojo::IOLoop::ReadWriteProcess; - use IO::Select; my $p = Mojo::IOLoop::ReadWriteProcess->new( kill_sleeptime => 0.01, sleeptime_during_kill => 0.01, @@ -540,4 +544,48 @@ 'setting MOJO_PROCESS_DEBUG to 1 enables debug mode when executing external process'; }; +subtest 'process_args' => sub { + my $code = sub { + shift; + print $_.$/ for(@_); + }; + + my $p = Mojo::IOLoop::ReadWriteProcess->new($code, args => '0' )->start->wait_stop(); + is($p->read_all_stdout(), "0$/", '1) False scalar value was given as args.'); + + $p = Mojo::IOLoop::ReadWriteProcess->new($code)->args('0')->start->wait_stop(); + is($p->read_all_stdout(), "0$/", '2) False scalar value was given as args.'); + + $p = Mojo::IOLoop::ReadWriteProcess->new($code, args => [(0..3)] )->start->wait_stop(); + is($p->read_all_stdout(), "0$/1$/2$/3$/", '1) Args given as arrayref.'); + + $p = Mojo::IOLoop::ReadWriteProcess->new($code)->args([(0..3)])->start->wait_stop(); + is($p->read_all_stdout(), "0$/1$/2$/3$/", '2) Args given as arrayref.'); +}; + +subtest 'process in process' => sub { + my $p = process(sub { + is( process(execute => '/usr/bin/true')->quirkiness(1)->start()->wait_stop()->exit_status(), 0, 'process(execute) from process(code) -- retval check true'); + is( process(execute => '/usr/bin/false')->quirkiness(1)->start()->wait_stop()->exit_status(), 1, 'process(execute) from process(code) -- retval check false'); + is( process(sub { print 'sub-sub-process'})->start()->wait_stop()->read_all_stdout, 'sub-sub-process', 'process(code) works from process(code)'); + print 'DONE'; + })->start()->wait_stop(); + + is ($p->read_all_stdout(), 'DONE', "Use ReadWriteProcess inside of ReadWriteProcess(code=>'')"); +}; + +subtest 'execute exeption handling' => sub { + throws_ok { + process(execute => '/I/do/not/exist')->start()->wait_stop()->exit_status(); + } qr%/I/do/not/exist%, 'Execute throw exception, if executable does not exists'; + + my $p = process(execute => 'sleep 0.2')->start(); + attempt { + attempts => 20, + condition => sub { defined($p->exit_status)}, + }; + is ($p->is_running(), 0, 'Process not running'); + is ($p->exit_status(), 0, 'Exit status is 0'); +}; + done_testing; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/t/04_queues.t new/Mojo-IOLoop-ReadWriteProcess-0.32/t/04_queues.t --- old/Mojo-IOLoop-ReadWriteProcess-0.28/t/04_queues.t 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/t/04_queues.t 2021-12-09 19:04:50.000000000 +0100 @@ -5,6 +5,7 @@ use Test::More; use POSIX; use FindBin; +use Time::HiRes 'sleep'; use Mojo::File qw(tempfile path); use lib ("$FindBin::Bin/lib", "../lib", "lib"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/t/06_events.t new/Mojo-IOLoop-ReadWriteProcess-0.32/t/06_events.t --- old/Mojo-IOLoop-ReadWriteProcess-0.28/t/06_events.t 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/t/06_events.t 2021-12-09 19:04:50.000000000 +0100 @@ -97,5 +97,82 @@ is(Mojo::IOLoop::ReadWriteProcess::Session->singleton->all->size, 1); }; +subtest collect_from_signal_handler => sub { + my $p = process(execute => '/usr/bin/true'); + my $collected = 0; + my $orphan = 0; + my $sig_chld = 0; + $p->session->reset(); + $p->session->collect_status(1); # needed, because previous test set it to 0 + $p->session->on(SIG_CHLD => sub { $sig_chld++}); + $p->session->on(collected => sub { $collected++ }); + $p->session->on(collected_orphan => sub { $orphan++ }); + $p->start(); + + attempt { + attempts => 10, + condition => sub { $sig_chld > 0 && $collected > 0}, + }; + + is($sig_chld, 1, "Event for SIG_CHILD was emitted"); + is($collected, 1, "Event collected apear without doing active wait()"); + is($orphan, 0, "No orphans where collected"); + + $p->wait_stop(); + is($collected, 1, "No more collect events emitted"); + is($orphan, 0, "No more orphans events emitted"); + is($p->exit_status, 0 , '/usr/bin/true exited with 0'); + + exec ('/usr/bin/true') if (fork() == 0); + + attempt { + attempts => 10, + condition => sub { $sig_chld > 1 && $orphan > 0}, + }; + + is($sig_chld, 2, "Event for SIG_CHILD was emitted"); + is($collected, 1, "No more collect events emitted (2)"); + is($orphan, 1, "Collect one orphan"); +}; + +subtest emit_from_sigchld_off => sub { + my $p = process(execute => '/usr/bin/true'); + my $collected = 0; + my $orphan = 0; + my $sig_chld = 0; + $p->session->reset(); + $p->session->collect_status(1); + $p->session->emit_from_sigchld(0); + $p->session->on(SIG_CHLD => sub { $sig_chld++}); + $p->session->on(collected => sub { $collected++ }); + $p->session->on(collected_orphan => sub { $orphan++ }); + $p->start(); + + attempt { + attempts => 10, + condition => sub { $sig_chld > 0}, + }; + is($sig_chld, 1, "Event for SIG_CHILD was emitted"); + is($collected, 0, "Event collected didn't appear from sighandler"); + is($orphan, 0, "No orphans where collected"); + + $p->wait_stop(); + is($collected, 1, "No more collect events emitted"); + is($orphan, 0, "No more orphans events emitted"); + is($p->exit_status, 0 , '/usr/bin/true exited with 0'); + + exec ('/usr/bin/true') if (fork() == 0); + attempt { + attempts => 10, + condition => sub { $sig_chld > 1}, + }; + is($collected, 1, "No more collect events emitted (2)"); + is($orphan, 0, "collect_orphan didn't appear from sighandler"); + + $p->session->consume_collected_info(); + is($sig_chld, 2, "Event for SIG_CHILD was emitted"); + is($collected, 1, "No more collect events emitted (3)"); + is($orphan, 1, "Collect one orphan"); +}; done_testing(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojo-IOLoop-ReadWriteProcess-0.28/t/lib/Mojo/IOLoop/ReadWriteProcess/Test/Utils.pm new/Mojo-IOLoop-ReadWriteProcess-0.32/t/lib/Mojo/IOLoop/ReadWriteProcess/Test/Utils.pm --- old/Mojo-IOLoop-ReadWriteProcess-0.28/t/lib/Mojo/IOLoop/ReadWriteProcess/Test/Utils.pm 2020-09-30 13:53:44.000000000 +0200 +++ new/Mojo-IOLoop-ReadWriteProcess-0.32/t/lib/Mojo/IOLoop/ReadWriteProcess/Test/Utils.pm 2021-12-09 19:04:50.000000000 +0100 @@ -1,7 +1,7 @@ package Mojo::IOLoop::ReadWriteProcess::Test::Utils; our @EXPORT_OK = qw(attempt); - +use Time::HiRes qw(sleep); use Exporter 'import'; use constant DEBUG => $ENV{MOJO_PROCESS_DEBUG}; @@ -9,10 +9,11 @@ my $attempts = 0; my ($total_attempts, $condition, $cb, $or) = ref $_[0] eq 'HASH' ? (@{$_[0]}{qw(attempts condition cb or)}) : @_; + $cb //= sub {1}; until ($condition->() || $attempts >= $total_attempts) { warn "Attempt $attempts" if DEBUG; $cb->(); - sleep 1; + sleep .1; $attempts++; } $or->() if $or && !$condition->();