Hi,

I'm writing a new module and I'm seeking for a good name for it.

My current choice is

  Event::ExecFlow

and so I'm writing to this list to discuss my plans of namespace 
polution ;)

I try to explain what the module does. At first: I factored this module
out of dvd::rip, a Perl Gtk2 GUI for copying DVD's. It's a frontend for
transcode and various other video related command line tools. And that's
where Event::ExecFlow comes into place.

It offers a high level API to declare jobs, which mainly execute 
external commands, parse their output to get progress information, 
triggers actions when the command has been finished and so on. Such jobs
can be chained together to fulfill rather complex tasks which consists 
of a bunch of jobs.

The whole I/O is asynchronous resp. the execution flow is event-driven,
that's why I think Event::ExecFlow is a proper name. I'm planning to use
AnyEvent to abstract from specific mainloop implementations (Event, Glib
etc.).

Just a short SYNOPSIS to see how it works:

  my $job = Event::ExecFlow::Job::Group->new (
    jobs => [
      Event::ExecFow::Job::Command->new (
        name            => "transcode",
        title           => "Transcoding DVD title to OGG",
        command         => "transcode -i /dev/dvd ...",
        fetch_output    => 1,
        progress_max    => 4711, # number of frames
        progress_parser => sub {
          my ($job, $buffer) = @_;
          $job->set_progress_cnt($1) if $buffer =~ /\[\d+-(\d+)\]/;
          #-- or simply write this:
          #--   progress_parser => qr/\[\d+-(\d+)\]/,
        },
      ),
      Event::ExecFow::Job::Code->new (
        title         => "Do some checks",
        code          => sub {
          my ($job) = @_;
          my $transcode = $job->get_group->get_job_by_name("transcode");
          if ( $transcode->get_output !~ /.../ ) {
            $job->set_error_message("XY check failed");
          }
          #-- this could be done easier as a post_callback added to
          #-- the "transcode" job above, but it's nevertheless a good
          #-- example for the 'Code' job type and shows how jobs can
          #-- interfere with each other.
        },
      ),
      Event::ExecFow::Job::Command->new (
        title         => "Muxing OGG file",
        command       => "ogmmerge ...",
        no_progress   => 1,
      ),
    ],
  );

  #-- this inherits from Event::ExecFlow::Frontend
  my $frontend = Video::DVDRip::GUI::ExecFlow->new(...);
  $frontend->start_job($job);

You can recursively define arbitrary complex job structures by putting 
Groups into Groups. There are some more features like pre- and 
post-callbacks which can do additional checks and even manipulate the 
job plan at runtime, e.g. depending on the state of previously executed
jobs. As well Event::ExecFlow offers a unique interface for progress 
compution, error handling, warning messages, logging and stuff.

The $frontend object is application specific and must implement the 
Event::ExecFlow::Frontend interface (which is pretty small, currently 
seven very simple methods). $frontend receives events/method calls to do
progress updates on the UI. This way you can specify job execution plans
independently from the UI, which may be implemented using Gtk2, Tk, Qt 
or a simple text interface or whatever.

Any comments are welcome.

Regards,

Joern

-- 
LINUX - Linux Is Not gnU linuX

Attachment: pgppd9G3ILwRG.pgp
Description: PGP signature

Reply via email to