Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

The Monastery Gates

( #131=superdoc: print w/ replies, xml ) Need Help??

Donations gladly accepted

If you're new here please read PerlMonks FAQ
and Create a new user.

New Questions
Using Perl to automate GDB
3 direct replies — Read more / Contribute
by eloc
on Jul 28, 2014 at 19:46
    Monks, I humbly come before seeking your great wisdom. I essentially want to use Perl to send input commands to GDB, read the output GDB supplies from these commands, and based on that output send more commands to GDB. I believe open2() or open3() may be of use to me. Is this possible? If so could you show me a simple example? However, I am new to Perl, and would deeply appreciate any examples or advice you can provide.
Error with Net::SSLeay
1 direct reply — Read more / Contribute
by grektokomus
on Jul 28, 2014 at 16:38

    Hello Monks,

    I'm working on a simple script to retrieve JSON from an HTTPS web service. The code is being developed on a Windows 2008 server with Active Perl. The script reports an error on compilation, but then successfully retrieves the desired JSON from the Server. I've put substantial effort into eliminating the error and now seek assistance. Here is the declaration and the error:

    #!/usr/bin/perl -w use strict; #use diagnostics; use JSON -support_by_pp; use LWP 6.04; use LWP::UserAgent; use LWP::Protocol::https; use Net::SSLeay 1.63; use IO::Socket::SSL 1.997;
    Use of uninitialized value in subroutine entry at blib\lib\Net\SSLeay.pm (autosplit into blib\lib\auto\Net\SSLeay\randomize.al) line 912.

    Based on a few similar problems found on the internet, I have verified my LWP modules. I have updated to the latest SSLeay Module (which required force install with ppm). I have also installed OpenSSL 1.0.1h from slproweb.com (although when I verify using https://gist.github.com/dolmen/10096474, it confirms 1.0.1g) .

    I would greatly appreciate guidance to resolve this issue.

Visual Perl/Tk???
5 direct replies — Read more / Contribute
by Anonymous Monk
on Jul 28, 2014 at 13:51

    I am relatively new to Perl, I have used it on and off for a number of years, but never did anything very complicated. I am attempting to create an application for my own use that requires a GUI. I started writing native Perl/Tk, but am becoming a tad overwhelmed, especially with the Geometry managers, I came from an environment where we had tools to create the GUI. I have found and attempted to use several, but most of them require almost as much understanding of Perl/Tk as writing it natively. The only two tools that I have found that seem to do what I want is visual Camel and Eclipse SWT. Camel is unacceptable because it doesn't support very much, and Eclipse SWT appears to generate only Java code. Does anyone know of a free tool that has the functionality of Eclipse SWT, but will generate Perl/tk code? If Eclipse has this functionality, I could not find it. Documentation for most of these type products leave much to be desired. Any help in this direction would be appreciated.

Code Interpretation
6 direct replies — Read more / Contribute
by Perl_Ally
on Jul 28, 2014 at 11:32

    I'm hoping somebody can help me interpret what's going on in the following line of code:

     my @refs = @allrefs[ sort {$a <=> $b} values %uni_refs ];

    As far as I understand,  sort {$a <=> $b} values $uni_refs will sort $uni_refs by its values, numerically descending. Is this a correct interpretation?

    Assuming I'm correct so far, what does it then mean to have @allrefs outside of the square brackets containing the sort?

    Help greatly appreciated.

Linear Report with Devel-NYTProf
1 direct reply — Read more / Contribute
by McA
on Jul 28, 2014 at 08:49

    Hi all,

    I couldn't find an answer to the follwing problem, so I hope that someone of you has some pointers.

    I have a script which iterates over an array and does some functionality with every entry. The log shows that the performance per entry degrades very fast. With Devel-NYTProf I was able to identify the portion of code wasting most of the time. The problem was solved after some refactoring. What I couldn't identify was the fact that the performance degraded over time (in the solution before).

    My question now is: Is there a way to see the profiling data written by Devel::NYTProf in a not aggregated but linear way, where I could see at which part of the program the timings get worse?

    Regards
    McA

Find the row with shortest string for a given input in a csv file.
2 direct replies — Read more / Contribute
by Anonymous Monk
on Jul 28, 2014 at 08:06
    Hi all, So I have a csv file which looks like this:
    A, texttexttext, col3, col4, B, textt, col3, col4, A, text, col3, col4, B, texttex, col3, col4,
    Im concerned with column 1 and 2 only. So as you can see, in row 1 there are two unique ids only -A & B. So for each of the unique ids I want to save the rows which have shortest string in column two. So for above input the output would look like this:
    B, textt, col3, col4, A, text, col3, col4,
Tk::BrowseEntry set function -solved
2 direct replies — Read more / Contribute
by glenn
on Jul 25, 2014 at 11:40

    Hi monks. So because I love pain I want to know if anyone else has found such a solution to this bug lack of functionality. The BrowseEntry which provides a drop down has 3 functions: insert, delete, and get. I want a fourth 'set', rather than defining yet another global var as I already pass the obj to insert/delete I would love to be able to '->set(0)' to set the current value to index 0 of the list. Any suggestions or pointing in the correct direction would be appreciated. Thank you for your time.

Storing part of a regex in a variable
2 direct replies — Read more / Contribute
by jonneve
on Jul 25, 2014 at 11:37
    Hello all, I'm writing a rather complex script for converting C++ code to Pascal. A number of patterns or sub-pattern occur rather often, and therefore, I'm trying to put them into variables for later use. Here are my variables :
    $braces = qr/(?<braces>\{ ([^\{\}] | (?&braces))*? \} )/x; $brackets = qr/(?<brackets>\( ([^\(\)] | (?&brackets))*? \))/x; $identifier = qr/(?<identifier> \w+($brackets)?( \s*(\.|->)(?&identifi +er))?)/;
    The $brackets and $braces variables work as I expected, but the $identifier variable doesn't work right, for example :
    #This works $meth_impl =~ s/((?<identifier> \w+($brackets)?( \s*(\.|->)(?&identifi +er))?)) \s* \. \s* Trim\(\)/Trim($1)/xg; #This doesn't match anything: $meth_impl =~ s/($identifier) \s* \. \s* Trim\(\)/Trim($1)/xg;
    As you can see in the example above, I'm using the $brackets variable in both cases, and it works nicely. Could the problem be that my $identifier variable itself includes the $brackets variable? Do I need to eval it or something to force it to interpolate it correctly? Thanks in advance, Jonathan Neve
Understanding Inline::C to call vendor libraries
2 direct replies — Read more / Contribute
by murrayn
on Jul 25, 2014 at 02:31
    I have installed and successfully tested Inline::C with a simple "Hello World" and vowel counter (from the Inline::C Cookbook) so I'm reasonably happy that the installation is correct. I now want to invoke a vendor's C written API from Perl. The vendor's sample C code includes the line: #define SHLIBNAME “dptcpiphi.dll” My Perl code includes the following in order to access (I pray) the functions which I expect to be contained in dptcpiphi.dll:
    use Inline C => Config => AUTO_WRAP => ENABLE; use Inline C => Config => LIBS => '-L"C:\Program Files\Common Files\Pr +oduct\4.1\dptcpiphi.dll" -ldptcpip';
    The full Perl script is short:
    #!/usr/bin/perl -w use Inline C => Config => AUTO_WRAP => ENABLE; use Inline C => Config => LIBS => '-L"C:\Program Files\Common Files\Pr +oduct\4.1\dptcpiphi.dll" -ldptcpip'; use Inline C => DATA ; use strict; my $DPbuff = "statusbuffer"; my $status = MyGetCtrlStatus('0x14','localhost','1703',$DPbuff); print "$status\n"; __END__ __C__ int MyGetCtrlStatus(char ShiftCmd, char pHostName, char uPortNum, char + pCtrlStatus) { char JobInfo; int status = DPGetCtrlStatus(ShiftCmd, pHostName, uPortNum, pCtrlS +tatus); printf ("Running...\n"); return pHostName; }
    The gcc compile step appears to complete successfully but when it comes time to link the object libraries together it fails:
    Test_pl_5261.o:Test_pl_5261.c:(.text+0x27): undefined reference to `DP +GetCtrlStatus' collect2: ld returned 1 exit status dmake.exe: Error code 129, while making 'blib\arch\auto\Test_pl_5261\ +Test_pl_5261.dll'
    (I know the code isn't going to work at present but I can fix that as long as I can get Inline::C to link the vendor libraries into my Perl script.) Have I completely misinterpreted the purpose and capabilities of Include::C or simply made a mess of using the tool?
Running perl scripts in parallel
3 direct replies — Read more / Contribute
by perl_help26
on Jul 23, 2014 at 10:48
    Hello ! I have two perl scripts : perlscript1.pl and perlscript2.pl that are supposed to run forever in parallel. Is it possible to call these scripts from a third perl script? i.e.
    perlscript3.pl ---------------------------- system('perl -w perlscript1.pl); system('perl -w perlscript2.pl);
Firefox/Javascript/Perl CGI argument passing issue
4 direct replies — Read more / Contribute
by beckmanel
on Jul 22, 2014 at 10:40

    I'm using CGI::Application::Dispatch on the Perl backend

    Data is sent from Javascript:

    88 var _factories = [ 89 function() { return new XMLHttpRequest(); }, 90 function() { return new ActiveXObject("Msxml2.XMLHTTP"); } +, 91 function() { return new ActiveXObject("Microsoft.XMLHTTP") +; } 92 ]; 93 94 var _factory = null; 95 96 function newRequest() { 97 if (_factory != null) return _factory(); 98 99 for(var i = 0; i < _factories.length; i++) { 100 try { 101 var factory = _factories[i]; 102 var request = factory(); 103 if (request != null) { 104 _factory = factory; 105 return request; 106 } 107 } 108 catch(e) { 109 continue; 110 } 111 } 112 _factory = function() { 113 throw new Error("XMLHttpRequest not supported"); 114 } 115 _factory(); 116 } 1233 var http_request; 1234 http_request = newRequest(); 1252 var query = "ip=" + document.getElementById('ip').value; 1253 http_request.open('POST', "/index.pl/get_neigh_display", t +rue); 1254 http_request.send(query); 1255 return false;

    But when I do the same action from the same web page, but different browsers, I get parameters in a different form through Perl CGI (see below). My code has been working with the IE form, can I do anything to make the Firefox output form similar ?

    THANKS Much in advance.

    The below was generated in the target Perl procedure by:

    print STDERR "QUERY: ", Dumper($self->query), "\n";

    FIREFOX 15202 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] QUERY: + $VAR1 = bless( {, referer: http://56.207.201.210:8083/ 15203 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] + '.parameters' => [, referer: http://56.207.201.210:8083/ 15204 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] + 'POSTDATA', referer: http://56.207.201. +210:8083/ 15205 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] + ],, referer: http://56.207.201.210:8083/ 15206 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] + '.charset' => 'ISO-8859-1',, referer: http://56.207.201.21 +0:8083/ 15207 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] + 'POSTDATA' => [, referer: http://56.207.201.210:8083/ 15208 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] + 'ip=56.97.243.16', referer: http://56.207. +201.210:8083/ 15209 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] + ],, referer: http://56.207.201.210:8083/ 15210 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] + '.fieldnames' => {},, referer: http://56.207.201.210:8083/ 15211 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] + 'escape' => 1, referer: http://56.207.201.210:8083/ 15212 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] + }, 'CGI' );, referer: http://56.207.201.210:8083/ 15213 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] , refe +rer: http://56.207.201.210:8083/ 15214 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] [Tue J +ul 22 08:55:55 2014] index.pl: Use of uninitialized value in pattern +match (m//) at /var/www/smartncm_test_ie11/lib/OpenNCMApp/EntryPoint. +pm line 896., referer: http://56.207.201.210:8083/ 15215 [Tue Jul 22 08:55:55 2014] [error] [client 56.80.2.131] [Tue J +ul 22 08:55:55 2014] index.pl: Use of uninitialized value in pattern +match (m//) at /var/www/smartncm_test_ie11/lib/OpenNCMApp/EntryPoint. +pm line 897., referer: http://56.207.201.210:8083/ IE 15332 [Tue Jul 22 08:58:58 2014] [error] [client 56.80.2.131] QUERY: + $VAR1 = bless( {, referer: http://56.207.201.210:8083/# 15333 [Tue Jul 22 08:58:58 2014] [error] [client 56.80.2.131] + '.parameters' => [, referer: http://56.207.201.210:8083/# 15334 [Tue Jul 22 08:58:58 2014] [error] [client 56.80.2.131] + 'ip', referer: http://56.207.201.210:80 +83/# 15335 [Tue Jul 22 08:58:58 2014] [error] [client 56.80.2.131] + ],, referer: http://56.207.201.210:8083/# 15336 [Tue Jul 22 08:58:58 2014] [error] [client 56.80.2.131] + '.charset' => 'ISO-8859-1',, referer: http://56.207.201.21 +0:8083/# 15337 [Tue Jul 22 08:58:58 2014] [error] [client 56.80.2.131] + 'ip' => [, referer: http://56.207.201.210:8083/# 15338 [Tue Jul 22 08:58:58 2014] [error] [client 56.80.2.131] + '56.97.243.16', referer: http://56.207.201.210:8 +083/# 15339 [Tue Jul 22 08:58:58 2014] [error] [client 56.80.2.131] + ],, referer: http://56.207.201.210:8083/# 15340 [Tue Jul 22 08:58:58 2014] [error] [client 56.80.2.131] + '.fieldnames' => {},, referer: http://56.207.201.210:8083/ +# 15341 [Tue Jul 22 08:58:58 2014] [error] [client 56.80.2.131] + 'escape' => 1, referer: http://56.207.201.210:8083/# 15342 [Tue Jul 22 08:58:58 2014] [error] [client 56.80.2.131] + }, 'CGI' );, referer: http://56.207.201.210:8083/# 15343 [Tue Jul 22 08:58:58 2014] [error] [client 56.80.2.131] , refe +rer: http://56.207.201.210:8083/#
print package's symble table
4 direct replies — Read more / Contribute
by vinoth.ree
on Jul 22, 2014 at 04:06

    Hi Monks,

    I was doing somthing wrong, pls help me on this.

    I was trying to print the symble table of a package of mine.below is my package code

    package Vinoth; use strict; use warnings; use Data::Dumper; our $VERSION=1.0; sub printSimbleTable{ my $package = shift; print "I am in printSimbleTable of : $package\n"; print Dumper \%$packge::; #Not working print Dumper \%Vinoth::; # Works #print Dumper \%{$packge}::; #Not working # foreach my $varName (sort keys %$package::) # { # print "$varName\n"; # local *typeglob = %{$package}::{$varName}; # print "$$varName\n" if ($typeglob); # } } 1;

    I tried to use this package in a perl script and calling a function in this module to print the package's symble table. Below is the script file

    use strict; use warnings; use Vinoth; &Vinoth::printSimbleTable( 'Vinoth' );

    As you can see this line print Dumper \%$packge::; #Not working the $package hash my module name 'Vinoth', but its not printing the symble table with the Dumper, when I replace it with the my module name explicity, it works. how to use $package variable here and make it work ?

    Reference:

    Packages and Symbol Tables

    A package's namespace is a symbol table. The name of your package is stored in a hash named after your package with two colons appended to it. If you name a package BushWhack, its symbol table name is %BushWhack::. Packages are represented as %main:: or %:: in the symbol table by default. Since we're dealing with a hash, each key must have a value. Because keys are identifiers, values are the corresponding typeglob values; globs are pretty efficient because they do the symbol table lookups at compile-time. In other words, *BushWhack represents the value of %BushWhack::--see the following:

    local *low_flyer = *BushWhack::variable; # compile time local *low_flyer = *BushWhack::{"variable"}; # run time

    You can look up all the keys and variables of a package with this example. You may use undef() on these to clear their memory, and they will be reported as undefined. You shouldn't undefine anything here unless you don't plan to load these packages again. Because the memory has already been filled, it saves time when you load them if you leave them defined:1

    foreach $symbol_name (sort keys %BushWhack::) { local *local_sym = $BushWhack::{$symbol_name}; print "\$$symbol_name is defined\n" if($local_sym); print "\@$symbol_name is defined\n" if(@local_sym); print "\%$symbol_name is defined\n" if(%sym); }


    All is well
New Meditations
RFC: Proc::Governor
3 direct replies — Read more / Contribute
by tye
on Jul 28, 2014 at 03:12

    Here is the documentation for a little module I threw together after one of our services did a denial-of-service attack against another of our services. The math for this simple trick works out very neatly.

    I plan to upload this to CPAN very soon. Please let me know what you think.

    NAME

    Proc::Governor - Automatically prevent over-consumption of resources.

    SYNOPSIS

    use Proc::Governor(); my $gov = Proc::Governor->new(); while( ... ) { $gov->breathe(); ... # Use resources } while( ... ) { my $res = $gov->work( sub { ... # Use Service } ); ... }

    DESCRIPTION

    If you want to do a batch of processing as fast as possible, then you should probably also worry about overwhelming some resource and causing problems for other tasks that must share that resource. Fortunately, there is a simple trick that allows one to perform a batch of processing as fast as possible while automatically backing off resource consumption when most any involved resource starts to become a bottleneck (or even before it has become much of a bottleneck).

    The simple trick is to pause between steps for a duration equal to how long the prior step took to complete. The one minor down-side to this is that a single strand of execution can only go about 1/2 maximum speed. But if you have 2 or more strands (processes or threads), then throughput is not limited by this simple "universal governor" trick.

    It is also easy to slightly modify this trick so that, no matter how many strands you have working, they together (without any coordination or communication between the strands) will never consume more than, say, 60% of any resource (on average).

    A typical pattern for batch processing is a client sending a series of requests to a server over a network. But the universal governor trick also works in lots of other situations such as with 1 or more strands where each is doing a series of calculations and you don't want the collection of strands to use more than X% of the system's CPU.

    Note that the universal governor does not work well for resources that remain consumed while a process is sleep()ing, such as your process using too much memory.

    Proc::Governor provides lots of simple ways to incorporate this trick into your code so that you don't have to worry about your code becoming a "denial-of-service attack", which also frees you to split your processing among many strands of execution in order to get it done as fast as possible.

    METHODS

    new()

    my $gov = Proc::Governor->new( { working => 0, minSeconds => 0.01, maxPercent => 100, unsafe => 0, } );

    new() constructs a new Proc::Governor object for tracking how much time has recently been spent potentially consuming resources and how much time has recently been spent not consuming resources.

    new() takes a single, optional argument of a reference to a hash of options. The following option names are currently supported:

    working

    If given a true value, then the time spent immediately after the call to new() is counted as "working" (consuming resources). By default, the time spent immediately after the call to new() is counted as "not working" (not consuming).

    minSeconds

    minSeconds specifies the shortest duration for which a pause should be done. If a pause is requested but the calculated pause duration is shorter than the number of seconds specified for minSeconds, then no pause happens (and that calculated duration is effectively added to the next pause duration).

    The default for minSeconds is 0.01.

    maxPercent

    maxPercent indicates how much of any particular resource the collection of strands should be allowed to consume. The default is 100 (for 100%, or all of any resource, but avoid building up a backlog by trying to over-consuming any resource).

    Note that percentages are not simply additive. Having 3 groups of clients where each is set to not consume more than 75% of the same service's resources is the same as having just 1 group. The 3 groups together will not consume more than 75% of the service's resources in total.

    Say you have a group of clients, H, all set to not consume more than 50% of some service's resources and you have another group of clients, Q, all set to not consume more than 25% of that same service's resources. Both H and Q together will not add up to consuming more than 50% of the service's resources.

    If Q is managing to consume 20% of the service's resources when H starts running, then H won't be able to consume more than 30% of the service's resources without (slightly) impacting performance to the point that Q starts consuming less than 20%.

    H Q Total 50% 0% 50% 40% 10% 50% 30% 20% 50% 25% 25% 50%

    unsafe

    You can actually specify a maxPercent value larger than 100, perhaps because you have measured overhead that isn't easily accounted for by the client. But doing so risks overloading a resource (your measured overhead could end up being a much smaller percentage of the request time when the service is near capacity).

    So specifying a maxPercent of more than 100 is fatal unless you also specify a true value for unsafe.

    beginWork()

    $gov->beginWork( $breathe );

    Calling beginWork() means that the time spent immediately after the call is counted as "working" (consuming resources). Such time adds to how long the next pause will be.

    If $breathe is a true value, then beginWork() may put the strand to sleep for an appropriate duration.

    endWork()

    $gov->endWork( $breathe );

    Calling endWork() means that the time spent immediately after the call is counted as "not working" (not consuming resources). Such time subtracts from how long the next pause will be.

    If $breathe is a true value, then endWork() may put the strand to sleep for an appropriate duration.

    work()

    $gov->work( sub { ... # Consume resources }, $which );

    work() is a convenient shortcut that is roughly equivalent to:

    $gov->beginWork( $before ); ... # Consume resources $gov->endWork( $after );

    The value of $which can be:

    0 No pause will happen. 1 A pause may happen before the sub reference is called. 2 A pause may happen after the sub reference is called. 3 A pause may happen before and/or after the sub is called.

    If $which is not given or is undefined, then a value of 1 is used.

    You can actually get a return value through work():

    my @a = $gov->work( sub { ...; get_list() }, $which ); my $s = $gov->work( sub { ...; get_item() }, $which );

    Note that scalar or list (or void) context is preserved.

    Currently, if your code throws an exception, then endWork() does not get called. This is the same as would happen with the "equivalent" code shown above.

    breathe()

    $gov->breathe( $begin );

    Calling breathe() requests that the current process/thread pause for an appropriate duration.

    Each of the following:

    $gov->breathe(); # or $gov->breathe( 1 );

    is actually equivalent to:

    $gov->beginWork( 1 );

    While

    $gov->breathe( 0 );

    will just pause but will not change whether $gov is counting time as "working" or as "not working".

    pulse()

    $gov->pulse( $count, $begin );

    pulse() is very much like breathe() except that it is optimized for being called many times before enough "working" time has accumulated to justify doing a pause. The meaning of $begin is the same as with breathe().

    So, if you are making requests of a very fast service or are doing work in small chunks, then you can call pulse() directly in your loop and just pass it a value specifying approximiately how many calls to pulse() should be made before one of those calls does the work of calculating how long of a pause is called for.

    For example, a request to our Redis service typically takes a bit under 1ms. So code to perform a large number of such requests back-to-back might be written like:

    my $gov = Proc::Governor->new( { maxPercent => 70, working => 1, } ); my $redis = Redis->new(server=>...); while( ... ) { $gov->pulse( 20 ); $redis->...; }

    That is like calling breathe() every 20th time through the loop and is only the slightest bit less efficient (in run time) than if you had made the extra effort to write:

    ... my $count = 0; while( ... ) { if( 20 < ++$count ) { $gov->breathe(); $count = 0; } ...

    CROSS-OBJECT INTERACTIONS

    A single process (or thread) can simultaneously use more than one Proc::Governor object. For example, each process (of a group) that makes a series of requests to a service and does significant local processing of the data from each request might want to both prevent overwhelming the service and prevent overwhelming local resources (such as CPU).

    So you could have two Proc::Governor objects. One throttles use of local resources ($g_cpu below). The other throttles use of service resources ($g_db below).

    my $g_cpu = Proc::Governor->new( { maxPercent => 80 } ); my $g_db = Proc::Governor->new( { maxPercent => 30 } ); $g_db->beginWork(); my $db = DBI->connect( ... ); # DB work my $rows = $db->selectall_arrayref( ... ); $g_db->endWork(); for my $row ( @$rows ) { my $upd = $g_cpu->work( sub { process_row( $row ); # Local work } ); $g_db->work( sub { $db->update_row( $upd ); # DB work } ); }

    The above code assumes that the local resources required for making requests of the database service are relatively low. And realizes that doing local computations do not use database resources.

    If you set maxPercent to 100 for both Governors and each process spent about the same amount of time waiting for a response from the database as it spent performing local computations, then there might be no need for any pauses.

    Note that only time spent doing "DB work" adds to how long of a pause might be performed by the $g_db Governor. And only time spent doing "Local work" adds to how long of a pause might be performed by the $g_cpu Governor.

    Any pauses executed by either Governor get subtracted from the duration of any pauses of any Governor objects. So the $g_db Governor executing a pause also counts as a pause for the $g_cpu Governor (and thus makes the next pause that it performs either shorter or later or just not needed).

    Time spent inside of Proc::Governor methods may also be subtracted from future pause durations. But the code pays more attention to keeping such overhead small than to providing highly accurate accounting of the overhead and trying to subtract such from every Governor object.

    WHEN TO PAUSE

    Say you have a service that is a layer in front of some other service. You want to ensure that your service can't become a denial-of-service attack against the other service. But you want to prevent a Governor pause from impacting clients of your service when possible.

    You could implement such as follows:

    sub handle_request { my( $req ) = @_; our $Gov ||= Proc::Governor->new(); my $res = $Gov->work( sub { forward_request( $req ); }, 0 ); # Don't pause here. give_response( $res ); $Gov->breathe( 0 ); # Pause here; still idle. }

    (Well, so long as your service architecture supports returning a complete response before the request handler subroutine has returned.)

    If the other service is not near capacity, then the added pauses have no impact (other than perhaps preventing the number of active strands for your service from dropping lower). Be sure your service has an appropriate cap on how many strands it is allowed to keep active (as always).

    TO-DO

    A future version should have support for asynchronous processing. The shape of that interface is already sketched out, but the initial release was not delayed by the work to implement such.

    - tye        

Speeds vs functionality
5 direct replies — Read more / Contribute
by Tux
on Jul 27, 2014 at 12:48

    So my main question, also to myself, is "How much speed are you willing to sacrifice for a new feature?".

    Really. Lets assume you have a neat module that deals with your data, and it deals with it pretty well and reliable, but extending it with new features - some of them asked for by others - is getting harder and harder.

    We now have git, and making a branch is easy, so you can implements the most requested new feature, or the one that most appeals to you and when you are done and all old tests and new tests have passed, you notice a speed drop.

    What considerations do you make to decide whether to release the module with the new neat new feature and mention the slowdown (specified) or do you revert the change and note in the docs that the new feature would cause to big a slowdown.


    Enjoy, Have FUN! H.Merijn
New Cool Uses for Perl
Install missing modules with Module::Extract::Install's cpanm-missing/cpanm-missing-deep
No replies — Read more | Post response
by frozenwithjoy
on Jul 24, 2014 at 12:07

    The other day I got a new laptop and tried to run a couple scripts on it. I quickly grew tired of the tedious cycle of 'Module::X not found' errors/installing Module::X. I decided to make a tool to improve the situation.

    The result, Module::Extract::Install, can be used to analyze perl scripts and modules to identify and install their dependencies in an automated, pain-free manner. You can use this module's methods to write your own script (e.g., to pipe missing modules to your favorite installer) or take advantage of the included command-line tools cpanm-missing (checks a list of Perl files) and cpanm-missing-deep (checks all the Perl files within a directory).

    Feel free to give me last minute comments/suggestions before I put it on CPAN (currently it is only available through GitHub). Thanks!

New Monk Discussion
Meeting & conference announcements
1 direct reply — Read more / Contribute
by davies
on Jul 26, 2014 at 13:14

    I cannot find any guidelines for announcing Perl related events on this site. I have seen some events announced with requests for talks here, but not others. I am asking now because this year's London Perl Workshop has just been announced, but it is a question that has exercised my mind when other events have come up, such as the London PM tech meet two days ago (Thursday).

    Do such guidelines exist? If not, what should the guidelines contain? The simplest guideline of all is "Don't", but as I said above, it's one I have frequently seen broken. Do people want to know about major conferences only, lesser ones like the tech meet, routine pub events, emergency pub events? Where notices include publicity blurb about sponsors, should this be repeated or edited out?

    For any London mongers reading this, I happily volunteer to post notices about London events here, once I know I'm not doing the wrong thing. If guidelines exist or are created that permit such postings, I also volunteer to put a copy of the LPW 2014 notice in Perl news, unless someone else would prefer to do it.

    Regards,

    John Davies

Log In?
Username:
Password:

What's my password?
Create A New User
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2014-07-29 06:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (211 votes), past polls