Changeset 11406

Show
Ignore:
Timestamp:
05/11/08 22:59:27 (5 years ago)
Author:
topia
Message:

* 動作フローの見直し。主に error から warn and try next への変更。
* hooks->{before_connect} を追加(したけど未テスト)。

  • 特定のaddr/port/type をみて skip したり、書き換えたりできるはず。

* bind_addr をコネクション毎にオーバーライドできるように(同じく未テスト)。
* callback の optional genre として skip を追加した。
* ドキュメントをちょっと書き直した。

  • 重要なのは callback の 'error' genre は接続の試行が終わるというところ。
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lang/perl/tiarra/trunk/main/Tiarra/Socket/Connect.pm

    r11203 r11406  
    1616utils->define_attr_accessor(0, qw(domain host addr port callback), 
    1717                            qw(bind_addr prefer timeout), 
    18                             qw(retry_int retry_count try_count)); 
     18                            qw(retry_int retry_count try_count), 
     19                            qw(hooks)); 
    1920utils->define_attr_enum_accessor('domain', 'eq', 
    2021                                 qw(tcp unix)); 
     
    2930#           my ($genre, $connector, $msg_or_sock, $errno) = @_; 
    3031#           if ($genre eq 'warn') { 
    31 #               # $msg_or_sock: msg 
    32 #               # maybe don't have $errno 
     32#               # warnings 
     33#               #   $msg_or_sock: msg 
    3334#               warn $msg_or_sock; 
    3435#           } elsif ($genre eq 'error') { 
    35 #               # $msg_or_sock: msg 
    36 #               # maybe has $errno 
     36#               # error: error detected and connect attempt aborted. 
     37#               #        if you need, re-initialize connect. 
     38#               #   $msg_or_sock: msg 
    3739#               die $msg_or_sock; 
    3840#           } elsif ($genre eq 'sock') { 
    39 #               # $msg_or_sock: sock 
    40 #               # maybe don't have $errno 
     41#               # connection successful. return socket. 
     42#               #   $msg_or_sock: sock 
    4143#               attach($connector->current_addr, $connector->current_port, 
    4244#                      $msg_or_sock); 
    4345#           # optional genre 
     46#           } elsif ($genre eq 'skip') { 
     47#               # skipped by hook closure 
     48#               #   $msg_or_sock: msg 
     49#               warn $msg_or_sock; 
    4450#           } elsif ($genre eq 'interrupt') { 
    45 #               # $msg_or_sock: undef 
    46 #               # maybe don't have $errno 
     51#               # connection interrupted by user 
     52#               #   $msg_or_sock: undef 
    4753#               die 'interrupted'; 
    4854#           } elsif ($genre eq 'timeout') { 
    49 #               # $msg_or_sock: undef 
    50 #               # maybe don't have $errno 
     55#               # connection interrupted by timer 
     56#               #   $msg_or_sock: undef 
    5157#               die 'timeout'; 
    5258#           } 
     
    6167#                  array ref, default ipv6, ipv4], 
    6268#       domain => 'tcp', # default 
     69#       hooks => { 
     70#           before_connect => { 
     71#               my ($stage, $connecting) = @_; 
     72#               # hook before connection attempt 
     73#               #   $stage: 'before_connect' 
     74#               #   $connecting: { # be able to modify this hash. 
     75#               #       addr => $addr, port => $port, 
     76#               #       type => 'ipv4' or 'ipv6', 
     77#               #       bind_addr => undef or set connection-local bind_addr, 
     78#               #   } 
     79#               if ( /* not_want_to_connect */ ) { 
     80#                   die 'skip this connection'; 
     81#               } 
     82#           } 
     83#       } 
    6384#       ); 
    6485#   $connector->interrupt; 
     
    80101    map { 
    81102        $this->$_($opts{$_}); 
    82     } qw(host addr port callback bind_addr timeout retry_int retry_count); 
     103    } qw(host addr port callback bind_addr timeout retry_int retry_count hooks); 
    83104 
    84105    if (!defined $this->callback) { 
     
    200221 
    201222    if (!Tiarra::OptionalModules->ipv6) { 
    202         $this->_error( 
     223        $this->_warn( 
    203224            qq{Host $this->{host} seems to be an IPv6 address, }. 
    204225                qq{but IPv6 support is not enabled. }. 
    205226                    qq{Use IPv4 or install Socket6 or IO::Socket::INET6 if possible.\n}); 
     227        $this->_connect_try_next; 
     228        return; 
    206229    } 
    207230 
     
    212235    my ($this, $package, $addr, %additional) = @_; 
    213236 
     237    eval { 
     238        $this->_call_hooks('before_connect', $this->{connecting}); 
     239    }; if ($@) { 
     240        $this->_call_skip($@); 
     241        $this->_connect_try_next; 
     242        return; 
     243    } 
     244    if (defined $this->{hooks}->{before_connect}) { 
     245        #eval { $this->{hooks}->{before_connect}->('before_connect', ) } 
     246    } 
    214247    if (!eval("require $package")) { 
    215         $this->_connect_error("Couldn\'t require socket package: $package"); 
     248        $this->_connect_warn("Couldn\'t require socket package: $package"); 
     249        $this->_connect_try_next; 
    216250        return; 
    217251    } 
     252    my $bind_addr = $this->current_bind_addr; 
    218253    my $sock = $package->new( 
    219254        %additional, 
    220         (defined $this->{bind_addr} ? 
    221              (LocalAddr => $this->{bind_addr}) : ()), 
     255        (defined $bind_addr ? 
     256             (LocalAddr => $bind_addr) : ()), 
    222257        Timeout => undef, 
    223258        Proto => 'tcp'); 
     
    273308                qq{but Unix Domain Socket support is not enabled. }. 
    274309                    qq{Use other protocol if possible.\n}); 
     310        return; 
    275311    } 
    276312 
     
    335371} 
    336372 
     373sub current_bind_addr { 
     374    my $this = shift; 
     375 
     376    utils->get_first_defined( 
     377        $this->{connecting}->{bind_addr}, 
     378        $this->bind_addr); 
     379} 
     380 
    337381sub current_type { 
    338382    my $this = shift; 
     
    360404 
    361405    $this->callback->('sock', $this, $this->sock); 
     406} 
     407 
     408sub _call_skip { 
     409    # this address/port skipped; but continue trying 
     410    my ($this, $str, $errno) = @_; 
     411 
     412    $this->callback->('skip', $this, 
     413                      "skip connection attempt to ".$this->destination.$str, 
     414                      $errno); 
     415} 
     416 
     417sub _call_hooks { 
     418    # method may died by callback. 
     419    # please cover with eval, if you need. 
     420    my $this = shift; 
     421    my $genre = shift; 
     422 
     423    if (defined $this->{hooks}->{$genre}) { 
     424        $this->{hooks}->{$genre}->($genre, @_); 
     425    } 
    362426} 
    363427