Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Converting a big perl script which is called over and over to a module ?

Reply
Thread Tools

Converting a big perl script which is called over and over to a module ?

 
 
OdedDV
Guest
Posts: n/a
 
      06-04-2005
Hello all,

I have a rather long Perl script (which is Tk based). The script needs to
run another instance per user request. It is currently done using `system
myscript param1 param2 param3 &`. This works great in terms of
functionality, but the issue is that myscript gets "compiled/interpreted"
over and over whenever a new instance is required. This is a waste of time,
especially on some of our slow Solaris machines.

I wanted to convert myscript to a module, such that I can write another
short script which will use this module to launch the first instance.
It means that the module itself would have a function which launches another
instance.

The issue I'm facing is regarding the global variables I have in the script.
Naturally every instance should have its own copy of the parameters. It
means I can no longer have these as global parameters in the module, as this
implies that they are shared across all instances created. Trying to move
them to the "main" function I export from the module is no good, as I have
dozens of other functions in this module which need to access those
used-to-be "global" parameters.

Can someone please share with me some ideas / point me to relevant
documentation for the simplest way for me to achieve what I need ?
Maybe there's another solution (not using a module) ?

Thanks in advance,
Oded


 
Reply With Quote
 
 
 
 
Tad McClellan
Guest
Posts: n/a
 
      06-04-2005
OdedDV <(E-Mail Removed)> wrote:

> I have a rather long Perl script (which is Tk based). The script needs to
> run another instance per user request. It is currently done using `system
> myscript param1 param2 param3 &`. This works great in terms of
> functionality, but the issue is that myscript gets "compiled/interpreted"
> over and over whenever a new instance is required. This is a waste of time,
> especially on some of our slow Solaris machines.
>
> I wanted to convert myscript to a module, such that I can write another
> short script which will use this module to launch the first instance.
> It means that the module itself would have a function which launches another
> instance.



How will the module launch the new instance?

Using system()?

If so, then making it into a module does not solve your problem.

There will be a compile phase for each instance anyway.


> The issue I'm facing is regarding the global variables I have in the script.



I think the issue you're facing is an incomplete mental model of how
processes work, leading to an "XY problem".

If I understand your problem correctly, then module vs. monolithic
does not address your problem.

I think you want fork/exec instead.


> Naturally every instance should have its own copy of the parameters.



And if you launch it with system, whether in main or in a module,
they _will_ get their own (command line) parameters.


> Can someone please share with me some ideas / point me to relevant
> documentation for the simplest way for me to achieve what I need ?
> Maybe there's another solution (not using a module) ?



perldoc -q background

How do I start a process in the background?

perldoc -f fork
perldoc -f exec


--
Tad McClellan SGML consulting
http://www.velocityreviews.com/forums/(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
 
 
 
OdedDV
Guest
Posts: n/a
 
      06-04-2005

"Tad McClellan" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> How will the module launch the new instance?
>
> Using system()?


Nope, sorry if I wasn't clear enough. The idea is to convert the system
call to a function call.
Thus I'm calling code which was already "compiled/interpreted".
Am I saying something stupid ? Maybe it's not possible ?!

Is it possible to have some instances of the same function at the same time
?
Maybe I do need to fork/exec, but then again, I want to make sure I don't
ask Perl to recompile/reinterpret the code.

Can this be done ?

Thanks,
Oded


 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      06-04-2005
OdedDV <(E-Mail Removed)> wrote:

> Maybe I do need to fork/exec,



Right.


> but then again, I want to make sure I don't
> ask Perl to recompile/



Since you added that, I'm quite sure that you don't yet have an
accurate mental model of how processes work.

fork() makes a clone of the current process, with the instruction
counter at the same place in each process.

The cloning includes the memory image to be run, so the compilation
has already been done and is not repeated.


--
Tad McClellan SGML consulting
(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
xhoster@gmail.com
Guest
Posts: n/a
 
      06-05-2005
"OdedDV" <(E-Mail Removed)> wrote:
> Hello all,
>
> I have a rather long Perl script (which is Tk based). The script needs
> to run another instance per user request. It is currently done using
> `system myscript param1 param2 param3 &`. This works great in terms of
> functionality, but the issue is that myscript gets "compiled/interpreted"
> over and over whenever a new instance is required. This is a waste of
> time, especially on some of our slow Solaris machines.


Get faster machines.

> I wanted to convert myscript to a module, such that I can write another
> short script which will use this module to launch the first instance.
> It means that the module itself would have a function which launches
> another instance.
>
> The issue I'm facing is regarding the global variables I have in the
> script. Naturally every instance should have its own copy of the
> parameters. It means I can no longer have these as global parameters in
> the module, as this implies that they are shared across all instances
> created. Trying to move them to the "main" function I export from the
> module is no good, as I have dozens of other functions in this module
> which need to access those used-to-be "global" parameters.


Then you have to pass those variables to those dozens of functions.
Or pack all those different variables into one hash and pass that
to the functions.

> Can someone please share with me some ideas / point me to relevant
> documentation for the simplest way for me to achieve what I need ?


In my experience in doing this, all that I can say is "Sucks to be you."
I know of no easy way to pull off this conversion. You might be able to
hack something up by "local"izing all the package variables everytime you
start the main function. But I'd probably just roll up my sleeves and get
to work turning everything into lexicals (with a good search and replace
function, it isn't all *that* much work), rather than messing around with
local. But first I'd try to convince the guys with the purse-strings that
it would be cheaper to buy new machines to run the old, bad code than it
would be to re-do the code. (And then in the future us lexicals from the
start.)

> Maybe there's another solution (not using a module) ?


If you find one, please let me know.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
 
Reply With Quote
 
xhoster@gmail.com
Guest
Posts: n/a
 
      06-05-2005
"OdedDV" <(E-Mail Removed)> wrote:
> "Tad McClellan" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > How will the module launch the new instance?
> >
> > Using system()?

>
> Nope, sorry if I wasn't clear enough. The idea is to convert the system
> call to a function call.


I thought that was clear in the original, but then I noticed that in the
original you ended your "system" command with a "&". If you just change it
into a plain function call, then it will by synchronous, unlike "system"
with "&". Is that OK with you?


> Thus I'm calling code which was already "compiled/interpreted".
> Am I saying something stupid ? Maybe it's not possible ?!


Now that I think about it, I think that it is possible.

> Is it possible to have some instances of the same function at the same
> time ?


Don't know what that means.

> Maybe I do need to fork/exec, but then again, I want to make sure I don't
> ask Perl to recompile/reinterpret the code.


A fork doesn't ask Perl to recompile the code

So what you want to do is have the parent process include the module, so
the module gets compiled only once, at parent start up. The parent process
has itself compiled, and also has the "bad" module compiled (bad because it
uses globals in an unsafe way). But as long as the parent never does
anything with that module other than compile it, then the all the globals
in that module are "clean" in the parent process.

Now, some functionality in the module needs to be used. The parent process
forks, and then the child process invokes code from the module. The child
dirties up it's copy of the unsafe globals, but as long as the child never
creates children itself, this isn't a problem. The parent process's
version of the bad module is still clean, so the next time the parent forks
that child also gets a clean version.

Still, I'd work on cleaning up the bad module.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
 
Reply With Quote
 
John Smith
Guest
Posts: n/a
 
      06-05-2005
"OdedDV" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>
> "Tad McClellan" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> How will the module launch the new instance?
>>
>> Using system()?

>
> Nope, sorry if I wasn't clear enough. The idea is to convert the system
> call to a function call.
> Thus I'm calling code which was already "compiled/interpreted".
> Am I saying something stupid ? Maybe it's not possible ?!
>
> Is it possible to have some instances of the same function at the same
> time ?
> Maybe I do need to fork/exec, but then again, I want to make sure I don't
> ask Perl to recompile/reinterpret the code.
>
> Can this be done ?
>
> Thanks,
> Oded


How is the "mother prosess" that calls system() today being called itself?

Is it at CGI-script? (handles only one request and then dies)
A mod_perl httpd process? (probably handles more than one request)

What I'm really asking is: Are the mother process being startet once each
request or not?
If it are, you probably woudn't get much better performance by converting
the child
to a module. It could even be worse if the child doesn't get called each
time.

To turn a .pl into a .pm I think you have two alternatives:

Both includes finding all global variables in the .pl

Alt. 1
For the object oriented alternative, let the .pl globals become
instance variables. Most likely keys in an blessed instance hash.
This requires knowledge of writing object oriented perl.

Alt. 2
For the non-object oriented alternative. Declare all globals in
the .pl as my $var1; my %hash2; my @arr3; and so on in the
top of your .pm. And then write a: sub clean_up { undef $var1;
undef %hash2; undef @arr3; ... } ...and so on. Call Module::clean_up
each time first thing where the old system() call was.



 
Reply With Quote
 
OdedDV
Guest
Posts: n/a
 
      06-05-2005
Thanks for all who tried to explain. It looks like the issue is a little
bit more complicated.
Thanks for your patience, I will try to explain it better to answer the
questions I was asked:

Situation today:

I have a large Perl/Tk script called "myscript".
It is launched from the command line with arguments "arg1 arg2 arg3".
When executed, Perl fires up and "compiles" the code.

The code itself has an option (upon user request at a button click) to
launch ANOTHER instance of "myscript". It can be with the exact same
arguments (arg1 arg2 arg3) or with different values for these three
arguments.
Currently the NEW instance is launched using a background system call
(system "myscript .... &").
Of course more instances can be created whenever a user asks to (either from
the "original" instance or from new instances).
It is important that each instance is completely independent of the other
instances. When it is closed/killed - it should NOT affect any of the other
instances.

I would like to improve the performance of "myscript" such that new
instances created will NOT require Perl recompilation.

Can it be done ?

Thanks,
Oded


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
GIDS 2009 .Net:: Save Big, Win Big, Learn Big: Act Before Dec 29 2008 Shaguf ASP .Net 0 12-26-2008 09:29 AM
GIDS 2009 .Net:: Save Big, Win Big, Learn Big: Act Before Dec 29 2008 Shaguf ASP .Net Web Controls 0 12-26-2008 06:11 AM
GIDS 2009 Java:: Save Big, Win Big, Learn Big: Act Before Dec 29 2008 Shaguf Python 0 12-24-2008 07:35 AM
GIDS 2009 Java:: Save Big, Win Big, Learn Big: Act Before Dec 29 2008 Shaguf Ruby 0 12-24-2008 05:07 AM
Perl Help - Windows Perl script accessing a Unix perl Script dpackwood Perl 3 09-30-2003 02:56 AM



Advertisments