2008年8月28日星期四

POE 的job_server

最近练习写了一个socket程序,目的是实现linux命令和结果的传输,代码在这里可以下到:http://bbs.chinaunix.net/attachment.php?checkdownload=ok&aid=285654
后来cu的flw告诉说POE的job_server更为简单明了,于是看了看,简单的翻译了一下

一个简单的任务管理器,他允许多个客户端在服务器上同时运行任务,客户端的输入被送到服务端运行。

#!/usr/bin/perl
# http://poe.perl.org/?POE_Cookbook/Job_Server

use warnings;
use strict;
# Include POE, POE::Component::Server::TCP, and POE::Wheel::Run.
#从POE load如下对象
use POE qw(Component::Server::TCP Wheel::Run);
# The programs that are allowed to run, with their names.
# 下面这些是允许发送运行的程序
my %programs = (
    time   => "/bin/date",
    uptime => "/usr/bin/uptime",
    ls     => "/bin/ls /var/games/*",
    echo   => "/bin/cat -",
);
# Start a TCP server. The client will be presented with a list of
# valid commands. They can enter one command: that will execute, and
# its output will be sent back to the client. Then the server will
# close the connection.
# 打开一个tcp服务。客户端会看到一系列命令提示,此时键入一个命令,服务器便会执行
#这个命令,并将输出返回给客户端,之后服务器关闭连接。

POE::Component::Server::TCP->new(
    Alias => "job_server",
    Port  => 32080,
# Send the client a list of available commands when it connects.
# 连接时给客户端发送可用命令列表,这些状态都是内置的,我们可以状态设定回调函数
    ClientConnected => sub {
        $_[KERNEL]->yield("usage");
# yield函数在POE中使用在当前session唤起一个操作时,如果要将一个操作传递到令一个session,使用post
    },
    # Make sure the job is destroyed when the client exits.
    # 确保客户退出时销毁任务
    ClientDisconnected => sub {
        delete $_[HEAP]->{job};
    },

# Process client input. When no job is running, accept input and
# try to spawn a new one. While a job is running, however, pass
# the client's input to it.
#处理客户端的输入。当服务端没有运行任何任务时,客户端接收命令输入并产生一个新的任务,当有任务运行时,把客户端的输入传递过去。

    ClientInput => sub {
        my ( $heap, $input ) = @_[ HEAP, ARG0 ];
        #POE为内置了一系列参数,如:@_[KERNEL,HEAP,ARGO..$#,SESSION]
        #heap是用来存储一个session私有数据的地方
        if ( $heap->{job} ) {
            $heap->{job}->put($input);
            return;
        }
        my $program = $programs{$input};
        unless ( defined $program ) {
            $_[KERNEL]->yield("usage");
            return;
        }
        $heap->{job} = POE::Wheel::Run->new(
            Program      => $program,
            StdioFilter  => POE::Filter::Line->new(),
            StderrFilter => POE::Filter::Line->new(),
            StdoutEvent  => "got_job_stdout",
            StderrEvent  => "got_job_stderr",
            CloseEvent   => "got_job_close",
        );
        $heap->{client}->put( "Job " . $heap->{job}->PID . " started." );
    },

# Inline states are custom event handlers. These add handlers for
# job output, job status, and a convenient usage message.
# Inline状态是定制的事件处理器。在这里添加了任务输出,任务状态和方便的使用说明

    InlineStates => {
        got_job_stdout => sub {
            $_[HEAP]->{client}->put("out: $_[ARG0]");
        },
        got_job_stderr => sub {
            $_[HEAP]->{client}->put("ERR: $_[ARG0]");
        },
        got_job_close => sub {
            my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
            my $job = delete $heap->{job};
            $heap->{client}->put( "Job " . $job->PID . " stopped." );
        },
        usage => sub {
            my @commands = sort keys %programs;
            $_[HEAP]->{client}->put("Commands: @commands");
        },
    },
);

# Run the server until it's done.
$poe_kernel->run();

2008年8月22日星期五

sort by field

sub ps{
my @c = `ps aux`;
my $dis = shift @c;
@c = map { $_->[0] } #whole line
sort {
$a->[1] <=> $b->[1] #by memory
}
map { chomp; [$_,(split)[3] }
`ps aux`
}


google到的一个技巧,这样可以通过在str中的某个字段排序

2008年8月15日星期五

system中的命令执行顺序

都说system会等待函数返回,
但使用
system 'wget arg';
system 'wget arg1';
发现如果wget后台了,system不会等到wget完事之后再执行第二个

可以 system("comand1;command2"),将顺序执行的任务交给shell去做