cpan-authors / IPC-Run

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

select_loop() does not end #167

Closed bokutin closed 1 year ago

bokutin commented 1 year ago

Hello.

When daemon is invoked, it behaves differently with and without pipe.

The bottom one terminates immediately.

run [ "perl", "-E", "if (fork) { say 'parent exit' } else { say 'daemon start'; sleep 1 while 1; say 'daemon exit' }" ];

The bottom one does not terminate forever.

run [ "perl", "-E", "if (fork) { say 'parent exit' } else { say 'daemon start'; sleep 1 while 1; say 'daemon exit' }" ], '>', \my $out;

The following line is the reason why reap_nb is not called and the defunct process is not collected. https://github.com/toddr/IPC-Run/blob/a4980740c3efbd5eae3f59489fc43ba1ca12ab8d/lib/IPC/Run.pm#L3392

Is this behavior the specification?

I actually noticed this difference in behavior in the code below.

run [qw(/usr/local/etc/rc.d/postgresql restart)], 
    '>',  sub { print $_[0] =~ s/^/\t/mgr },
    '2>', sub { warn $_[0] =~ s/^/\t/mgr };

"/usr/local/etc/rc.d/postgresql restart" is roughly equivalent to "/usr/local/bin/pg_ctl -D /var/db/postgres/data12 restart". (This is a FreeBSD environment)

I guess the daemon side should do close STDOUT and close STDERR, but pg_ctl doesn't seem to close.

I would appreciate a reply, even if it is brief.

Thanks.

nmisch commented 1 year ago

Is this behavior the specification?

It's consistent with the documentation:

  run Run takes a harness or harness specification and runs it, pumping all
      input to the child(ren), closing the input pipes when no more input is
      available, collecting all output that arrives, until the pipes
      delivering output are closed, then waiting for the children to exit and
      reaping their result codes.

In your nonterminating example, IPC::Run is waiting on that "until the pipes delivering output are closed" condition.

I guess the daemon side should do close STDOUT and close STDERR, but pg_ctl doesn't seem to close.

Can you use its --log option for that?

bokutin commented 1 year ago

Thanks for the reply!

I see, so this behavior is consistent with the documentation. Sorry I didn't read it carefully.

I tried a few things.

# perl -E 'use IPC::Run; IPC::Run::run [qw(su -l postgres -c), "exec /usr/local/bin/pg_ctl -D /var/db/postgres/data12 restart"]'
waiting for server to shut down.... done
server stopped
waiting for server to start....2022-11-07 15:55:06.864 JST [86414] LOG:  starting PostgreSQL 12.12 on amd64-portbld-freebsd12.3, compiled by FreeBSD clang version 10.0.1 (git@github.com:llvm/llvm-project.git llvmorg-10.0.1-0-gef32c611aa2), 64-bit
2022-11-07 15:55:06.864 JST [86414] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2022-11-07 15:55:06.864 JST [86414] LOG:  listening on IPv4 address "192.168.13.114", port 5432
2022-11-07 15:55:06.864 JST [86414] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2022-11-07 15:55:06.880 JST [86414] LOG:  redirecting log output to logging collector process
2022-11-07 15:55:06.880 JST [86414] HINT:  Future log output will appear in directory "log".
 done
server started
# (completed successfully)
# perl -E 'use IPC::Run; IPC::Run::run [qw(su -l postgres -c), "exec /usr/local/bin/pg_ctl -D /var/db/postgres/data12 restart"], ">", sub { print @_ }'
waiting for server to shut down.... done
server stopped
waiting for server to start....2022-11-07 15:58:10.634 JST [88905] LOG:  starting PostgreSQL 12.12 on amd64-portbld-freebsd12.3, compiled by FreeBSD clang version 10.0.1 (git@github.com:llvm/llvm-project.git llvmorg-10.0.1-0-gef32c611aa2), 64-bit
2022-11-07 15:58:10.634 JST [88905] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2022-11-07 15:58:10.634 JST [88905] LOG:  listening on IPv4 address "192.168.13.114", port 5432
2022-11-07 15:58:10.634 JST [88905] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2022-11-07 15:58:10.650 JST [88905] LOG:  redirecting log output to logging collector process
2022-11-07 15:58:10.650 JST [88905] HINT:  Future log output will appear in directory "log".
 done
server started
^C
# (No end. Ctrl+C to exit.)
# perl -E 'use IPC::Run; IPC::Run::run [qw(su -l postgres -c), "exec /usr/local/bin/pg_ctl -D /var/db/postgres/data12 --log=/tmp/pg_ctl.log restart"], ">", sub { print @_ }'
waiting for server to shut down.... done
server stopped
waiting for server to start.... done
server started
# cat /tmp/pg_ctl.log 
2022-11-07 16:00:20.211 JST [89719] LOG:  starting PostgreSQL 12.12 on amd64-portbld-freebsd12.3, compiled by FreeBSD clang version 10.0.1 (git@github.com:llvm/llvm-project.git llvmorg-10.0.1-0-gef32c611aa2), 64-bit
2022-11-07 16:00:20.211 JST [89719] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2022-11-07 16:00:20.211 JST [89719] LOG:  listening on IPv4 address "192.168.13.114", port 5432
2022-11-07 16:00:20.211 JST [89719] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2022-11-07 16:00:20.228 JST [89719] LOG:  redirecting log output to logging collector process
2022-11-07 16:00:20.228 JST [89719] HINT:  Future log output will appear in directory "log".
#
# perl -E 'use IPC::Run; IPC::Run::run [qw(su -l postgres -c), "exec /usr/local/bin/pg_ctl -D /var/db/postgres/data12 --log=/dev/stdout restart"], ">", sub { print @_ }'    
waiting for server to shut down.... done
server stopped
waiting for server to start....2022-11-07 16:01:39.485 JST [91503] LOG:  starting PostgreSQL 12.12 on amd64-portbld-freebsd12.3, compiled by FreeBSD clang version 10.0.1 (git@github.com:llvm/llvm-project.git llvmorg-10.0.1-0-gef32c611aa2), 64-bit
2022-11-07 16:01:39.485 JST [91503] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2022-11-07 16:01:39.485 JST [91503] LOG:  listening on IPv4 address "192.168.13.114", port 5432
2022-11-07 16:01:39.485 JST [91503] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2022-11-07 16:01:39.501 JST [91503] LOG:  redirecting log output to logging collector process
2022-11-07 16:01:39.501 JST [91503] HINT:  Future log output will appear in directory "log".
 done
server started
^C
# (No end. Ctrl+C to exit.)