EMDIS-ECS

 view release on metacpan or  search on metacpan

script/ecs_chk_com  view on Meta::CPAN

# check communication status with each node
sub chk_com
{
    my $err;
    my @node_ids = ();
    if(!$ECS_NODE_TBL->lock()) {  # lock node_tbl
        log_error("chk_com(): unable to lock node_tbl: " .
                  $ECS_NODE_TBL->ERROR);
        return;
    }
    else {
        @node_ids = $ECS_NODE_TBL->keys;
        if($ECS_NODE_TBL->ERROR) {
            log_error("chk_com(): unable to retrieve node_tbl keys: ",
                      $ECS_NODE_TBL->ERROR);
            @node_ids = ();
        }
    }
    $ECS_NODE_TBL->unlock();

    # check each node
    for my $node_id (@node_ids)
    {
        # don't check comm status with self
        next if $node_id eq $ECS_CFG->THIS_NODE;

        # lock node_tbl
        if(!$ECS_NODE_TBL->lock())
        {
            log_error("chk_com(): unable to lock node_tbl: " .
                      $ECS_NODE_TBL->ERROR);
            next;
        }

        my $node = $ECS_NODE_TBL->read($node_id);
        # don't try to process if node not found
        if(not ref $node)
        {
            log_error("chk_com(): unable to retrieve node $node_id status.");
            $ECS_NODE_TBL->unlock();
            next;
        }
        # is node marked as disabled?
        if((exists $node->{node_disabled}) and
            $node->{node_disabled} =~ /^\s*(yes|true)\s*$/i)
        {
            log_info("chk_com(): skipping node $node_id " .
                "(node_disabled=$node->{node_disabled}).");
            $ECS_NODE_TBL->unlock();
            next;
        }
        my $current_time = time;
        my $last_out = $node->{last_out};
        my $last_in = $node->{last_in};

        # check time since last communication sent to node
        if(($current_time - $last_out) > $t_chk_min)
        {
            print "$DEBUG_LABEL sending READY message to node $node_id\n"
                if $ECS_CFG->ECS_DEBUG > 0;
            # send "I am alive" meta-message
            $err = send_ecs_message($node_id, '',
                "msg_type=READY\n",
                ((exists $node->{in_seq}) &&
                    ((!exists $node->{ready_num_disabled}) ||
                     not is_yes($node->{ready_num_disabled}))
                    ? "last_recv_num=" . $node->{in_seq}
                    : "") . "\n",
                ((exists $node->{out_seq}) &&
                    ((!exists $node->{ready_num_disabled}) ||
                     not is_yes($node->{ready_num_disabled}))
                    ? "last_sent_num=" . $node->{out_seq}
                    : "") . "\n",
                ((exists $node->{doc_in_seq}) &&
                    ((!exists $node->{ready_num_disabled}) ||
                     not is_yes($node->{ready_num_disabled}))
                    ? "last_recv_doc=" . $node->{doc_in_seq}
                    : "") . "\n",
                ((exists $node->{doc_out_seq}) &&
                    ((!exists $node->{ready_num_disabled}) ||
                     not is_yes($node->{ready_num_disabled}))
                    ? "last_sent_doc=" . $node->{doc_out_seq}
                    : "") . "\n",
                "# Hello Partner, I am alive.\n");
            if($err)
            {
                log_error("chk_com(): unable to send READY meta-message " .
                          "to node $node_id: $err");
            }
            else
            {
                log_info( "READY to $node_id sent.\n" );
                $node->{last_out} = $current_time;
            }
        }

        # check time since last communication received from node
        if(($current_time - $last_in) > ($t_chk_com + $ECS_CFG->T_ADM_DELAY))
        {
            if(($current_time - $node->{last_in_adm}) > $ECS_CFG->T_ADM_REMIND)
            {
                # notify local administrator when comm lost
                # (after "remind" period has elapsed)
                log_info(
                    "ECS communication loss detected: $node_id\n",
                    "Nothing received from $node_id node since " .
                        format_datetime($last_in) . "\n" .
                    "(Is the ecs_scan_mail daemon still running?)\n");
                $node->{last_in_adm} = $current_time
                    unless $err;
            }
        }
        else
        {
            $node->{last_in_adm} = 0;  # reset "remind" timer
        }

        # periodically send MSG_ACK if node has in_seq_ack < in_seq
        if((exists $node->{in_seq}) and ((!exists $node->{in_seq_ack}) or
            ($node->{in_seq_ack} < $node->{in_seq})))
        {
            print "$DEBUG_LABEL sending MSG_ACK message ($node->{in_seq}) " .
                "to node $node_id\n"
                if $ECS_CFG->ECS_DEBUG > 0;
            # send MSG_ACK meta-message
            $err = send_ecs_message($node_id, '', 
                "msg_type=MSG_ACK\n",
                "seq_num=$node->{in_seq}\n",
                "# Acknowledged\n");
            if($err)
            {
                log_error(
                    "Unable to send MSG_ACK $node_id:$node->{in_seq}:\n",
                    $err);
            }
            else
            {
                log_info( "MSG_ACK $node_id:$node->{in_seq} sent.\n" );
                $node->{in_seq_ack} = $node->{in_seq};
            }
        }

        # update node status
        $ECS_NODE_TBL->write($node_id,$node);



( run in 1.377 second using v1.01-cache-2.11-cpan-39bf76dae61 )