DX Infrastructure Management

 View Only

SDK Perl - Experimentation chapter 1 

Apr 20, 2018 05:25 PM

Hi,

 

Recently I want to write a series of articles around the subject " How could be the SDK Perl " if we do " .. Something ". The goal is to bring an idea to life (something that answer real production cases that i met). I will provide real background code ( so everything will work for real ! ). 

 

I will start this series with Timer ! 

 

There is a lot of API that are not used (Sometimes people do not even know that they exist). Maybe because there are not very well documented haha (  )

 

For example the SDK_Perl expose a timer API that is not documented on the original SDK Perl documentation page (you have to open API.pm file).

 

By the way this API is documented on my own SDK Perl documentation (with a  nice example in bonus) :

Perl-SDK/timer.md at master · UIM-Community/Perl-SDK · GitHub 

 

That Definitively not a precision timer API (Dont build a round robin with this  ).

 

Let's get started

Why do we even build Nimbus object ? Because it will make our life simpler and will let us exploit the high level force of the language (and the Perl VM).

 

Open Session.pm and and you will understand what I mean by "simpler". Sometimes it may be less visible (like telling the VM when we destroy our object we need to remove some memory allocation on the lower level).

 

Let me introduce Nimbus::Timer API

package Nimbus::Timer;

# Use Nimbus dependencies
use Nimbus::API;

# Global vars
my $VERSION = '1.00';

#
# DESC: Nimbus::Timer constructor
#
sub new {
    my $class = shift;
    my $intervalMs = shift || 0;
    my $start = shift || 0;

    my $self = bless({
        _intervalMs => $intervalMs,
        _delta => 0,
        _timer => nimTimerCreate()
    }, ref($class) || $class);
    $self->start() if $start == 1;

    return $self;
}

#
# DESC: Start the timer
#
sub start {
    my ($self) = @_;

    nimTimerStart($self->{_timer});
    return $self;
}

#
# DESC: stop the timer
#
sub stop {
    my ($self) = @_;

    nimTimerStop($self->{_timer});
    return $self;
}

#
# DESC: reset the timer
#
sub reset {
    my $self = shift;
    my $start = shift || 0;

    $self->stop();
    $self->{_delta} = 0;
    nimTimerFree($self->{_timer});
    $self->{_timer} = nimTimerCreate();
    $self->start() if $start == 1;

    return $self;
}

#
# DESC: return difference in millisecond
#
sub diff {
    my ($self) = @_;
    return 0 if not defined($self->{_timer});

    return nimTimerDiff($self->{_timer});
}

#
# DESC: return difference in second
#
sub diffSec {
    my ($self) = @_;
    return 0 if not defined($self->{_timer});

    return nimTimerDiffSec($self->{_timer});
}

#
# DESC: Walk internal timer
#
sub walk {
    my ($self, $timeMs) = @_;
    return 0 if not defined($timeMs);
    return 1 if $self->{_intervalMs} == 0;

    $self->{_delta} = $self->{_delta} + $timeMs;
    return 0 if $self->{_delta} < $self->{_intervalMs};

    $self->reset;
    return 1;
}

#
# DESC: Free memory allocation when the perlObject is destroyed
#
sub DESTROY {
    my ($self) = @_;

    nimTimerFree($self->{_timer});
}

1;

 

Why ?

 

Because object (or prototype) make our life simpler : 

  • One variable with everything (no need to call random globals methods).
  • Capable to return itself (so we can inline multiple call).
  • We can build new useful method around original methods ( like reset ).

 

No need to call nimTimerFree ourself (the garbage collector will do it for us). Or when you call something like

my $timer = Nimbus::Timer->new->start;
# Do job here...
undef $timer; # Tell the GC to get timer
# low-level timer memory allocation should be cleaned

 

Real example

 

My walk and reset method is an answer to something i already do with the native timer API on my Perl probes (to trigger Alarm, QoS or even some threads).

snmp_ipsla/nokia_ipsla.pl at master · UIM-Community/snmp_ipsla · GitHub (No joke..  Look here  )

 

But it request multiple lines of code to achieve a simple job... But if we use my Nimbus::Timer implementation it become much more simple to build something coherent ! 

 

Take a look at this little perl probe (with a timeout configured to 1,000 ms).

# Use Nimbus dependencie(s)
use lib "/opt/nimsoft/perllib/";
use lib "/opt/nimsoft/perl/";
use Nimbus::API;
use Nimbus::Session;
use Nimbus::Timer;

# Login to Nimbus (because i run this on a terminal)
nimLogin("administrator", "password");

# Create timer here! (with interval checkup to 3,000ms)
my $timer = Nimbus::Timer->new(3000)->start;

# Set probe interval to 1,000ms
my $probeInterval = 1000;

sub timeout {
    print STDOUT "timeout (1 sec)!\n";

    # Walk timer with 1,000ms
    if ($timer->walk($probeInterval)) {
        print STDOUT "3 sec...";
    }
}
sub restart {}

my $sess = Nimbus::Session->new("timer-probe");
$sess->setInfo ("1.0", "");

if ($sess->server (NIMPORT_ANY,\&timeout,\&restart)==0) {
    # dispatch and set timeout interval to 1,000ms
    $sess->dispatch($probeInterval);
}

 

When the timer walk is true, it will reset itself (No need to build some random bullshit algorithm to match our need... It work well with almost nothing).

 

Like i said it can be used to run Alarms, QoS or even a thread that will do a periodic task (perfect for a deamon probe).

 

Timer match very well with the most common use cases in production.

 

Thanks

 

This first article is done. Thanks for reading me, hope it will help some of you ! 

 

Best Regards,

Thomas

Statistics
0 Favorited
3 Views
0 Files
0 Shares
0 Downloads

Tags and Keywords

Comments

May 02, 2018 10:54 AM

Thank you Thomas !  Exactly what we hope our champions will bring to the community. Fantastic! 

Apr 21, 2018 08:14 AM

Thanks Thomas. Your work on the Perl SDK for UIM is impressive! Keep it up!

Related Entries and Links

No Related Resource entered.