GithubHelp home page GithubHelp logo

mojolicious-plugin-process's Introduction

NAME

Mojolicious::Plugin::Process - execute a non-blocking command

SYNOPSIS

# Mojolicious
sub stratup {
    my $self = shift;
    $self->plugin('Process');
    ...;
}

# Mojolicious::Lite
plugin 'Process';

# in controller
get '/job' => sub {
    my $c      = shift;
    my $job_id = MyApp->create_id( $c->req->params->to_hash );
    $c->stash( id => $job_id );
    $c->render('accept');

    if ($job_id) {

        # async execution of time-consuming process
        $c->process(
            command => [ 'job-command', 'id', $job_id ],
            stdout  => {
                close => sub {
                    my ($stream) = @_;
                    app->log->info( sprintf( '[%s] end job', $stream->pid ) );
                },
            },
            stderr => {
                read => sub {
                    my ( $stream, $chunk ) = @_;
                    chomp $chunk;
                    app->log->err( sprintf( '[%d] %s', $stream->pid, $chunk ) );
                },
            },
            timeout => 0,
        );
    }
};

DESCRIPTION

Mojolicious::Plugin::Process is a plugin for Mojolicious apps to execute a non-blocking command.

METHODS

Mojolicious::Plugin::Process inherits all methods from Mojolicious::Plugin.

HELPERS

Mojolicious::Plugin::Process contains a helper: process.

process

my ( $pid, $stdin ) = $self->process(
    command => [ 'job-command', 'id', $job_id ],
    stdout => {
        read => sub {
            my ( $stream, $chunk ) = @_;
            chomp $chunk;
            app->log->info( sprintf( '[%s] %s', $stream->pid, $chunk ) );
        },
        close => sub {
            my ($stream) = @_;
            app->log->info( sprintf( '[%s] end process', $stream->pid ) );
        },
    },
    timeout => 0,
);

ARGUMENTS

process supports the following arguments

  • command: ArrayRef

    command. this is requried argument.

      command => [ 'echo', 'foo' ]
    
  • stdout: HashRef, stderr: HashRef

    can emit the following Mojo::IOLoop::Stream events.

    close, error, read, timeout

    in handler, $stream is a Mojo::IOLoop::Stream::Process Ojbect.

    Mojo::IOLoop::Stream::Process has the following attributes.

    ioloop_id, pid, command

      stdout => {
          read => sub {
              my ($stream, $chunk) = @_;
              chomp $chunk;
              app->log->info( sprintf('[%s] %s', $stream->pid, $chunk ) );
          },
          close => sub {
              my ($stream) = @_;
              app->log->info( sprintf('[%s] end process', $stream->pid ) );
          },
      }
    
  • timeout: Scalar

    Mojo::IOLoop::Stream timeout attribute.

      timeout => 300
    

AUTHOR

hayajo [email protected]

SEE ALSO

Mojolicious, Mojo::IOLoop::Stream

LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

mojolicious-plugin-process's People

Contributors

hayajo avatar hiroaki avatar stefb69 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

stefb69 hiroaki

mojolicious-plugin-process's Issues

Process-plugin creates zombie processes

The plugin works very well to the point the newly fork()ed child process has run its course and is about to exit. As the classic IPC-model in *nixes goes: the child process will turn into a zombie until calling parent will call wait().

That's exactly what happenes here. Plugin-code doesn't have the wait()-call anywhere.

The fix is to add a simple:

waitpid($pid, WNOHANG);

Where $pid is the PID returned by a $self->process() call. It is not necessary to write code to handle the CHLD-signal, Perl does that. Mojolicious doesn't touch the signal handler and when queried for current value, it returns DEFAULT.

Example run:

for round in {1..500}; do curl http://localhost:8888/; done

Compare the results, asking for number of zombie processes found:

ps ax | fgrep defunct | wc -l

Without waitpid()-call, result will be 501 (one for the fgrep). With waitpid()-call, result will be 1.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.