The URL is on an internal LAN for a company whose name
I cannot use. The site gets up to a few hundred hits
per second supporting a telephone call center database.
My company was asked to develop a web
front end onto a TB data warehouse. The existing system
(carefully crafted in C) was so slow people couldn't
get their work done (e.g., 45-minute query times). We
re-did the back end and slapped an interface on it using
mod_perl.
The first time the users saw it they asked for a "Stop"
button like the existing system had so they could abort
long-running queries. Then we went over where to put it
with me running queries. They gave up on the idea because
the data was returned too fast for them to hit a button.
Through 4+ weeks of User Acceptance Testing ("UAT") they
asked for a few dozen changes in the reports. Few of them
took loger than 20 minutes to implement. In several cases
they got annoyed that the company email took longer to
deliver the fix notice than make the change.
Using Perl we were also able to handle the database
manglement software for tablespace and table creation,
web site auth. and reporting code and most of the ETL
process management code in one language. That also
saved us quite a bit of work.
Wednesday, August 8, 2007
Internal Call Center Database
The mod_perl

mod_perl is the marriage of Apache and Perl
mod_perl brings together two of the most powerful and mature technologies available to the web professional today.mp2 is mod_perl for the 2.x.x branch of the Apache HTTPD Server.
mp1 is mod_perl for the 1.3 branch of the Apache HTTPD Server.
mp2 is fully compatible with httpd 2.0.x , and supports most of the 2.2.x feature set.
mod_perl's future plans are to keep on supporting httpd as it evolves - that has always been the goal, and will always be so.
Simply install mod_perl and you have the full power of the Apache Web Server at your fingertips:
Accelerate your existing dynamic contentThe standard Apache::Registry module can provide 100x speedups for your existing CGI scripts and reduce the load on your server at the same time. A few changes to the web server's config is all that is required to run your existing CGI scripts at lightning speed. more »
Easily create custom modules that become part of ApacheWith mod_perl writing custom modules to extend and enhance Apache is a snap. Content handlers can be written in just a few lines of code and can be quickly integrated with existing modules specifically designed for use with mod_perl, or with modules freely available from the CPAN. more »
Gain access to all request stagesmod_perl is not only about super fast content generation. With mod_perl all phases of the request cycle can be accessed and controlled. No other web acceleration product gives you this much control.
Imagine the flexibility of rewriting URLs using Perl! Rewrite URLs based on the content of a directory structure, settings stored in a relational database, or the phase of the moon.
Write custom authentication and authorization modules to integrate with existing user databases or take advantage of the well-supported CPAN modules to extend the abilities of Apache. You can even create custom logging tailored to your site's specific needs. more »
Configure Apache with PerlPerl can be used right in your httpd.conf file. Everything from virtual hosts to authentication settings can be configured via Perl. URL translation logic can be written with Perl for your complex or dynamic URL rewriting needs. Settings can be adjusted on a per-request basis and values passed from code in httpd.conf to your content generation modules. You can even generate complete HTTP output from the httpd.conf configuration file. more »
Install Third-party modulesThird-party modules give you application functionality such as sessions, passwords and database integration.
Application FrameworksThere are many high-level packages built on top of the mod_perl infrastructure to help you develop scalable and easily managed dynamic sites. All are well supported and maintain a loyal group of users.
You can select from a number of templating systems or application frameworks for use with mod_perl. See the mod_perl Products section for more information.
Apache 2.X supportWith mod_perl you can take advantage of the features of Apache 2.0. For example, custom protocol handlers can be written in Perl.
Apache 2.0 is fully supported.
Most of Apache 2.2 is supported, and work toward full support is underway.
Active Support Communitymod_perl has all the support anyone could ask for.
Response time to questions posted on any of the mod_perl related lists is often measured in minutes. And with such a large installed base there's often someone that knows the answer to your specific question. In addition, a wealth of well maintained documentation is available online through this web site. For off-line, spend your time with excellent books about mod_perl. There's nothing like curling up in bed with a good book. Or someone that's read one.
Everyday Perl 6
While many of the changes in Perl 6 make it easier for people new to programming or coming from other programming languages to understand the language, none of the changes were made solely on those grounds. If your favorite part of Perl 5 syntax is that it uses an arrow for method dispatch on objects, don't be dismayed that Perl 6 uses a dot instead. The designers carefully considered each syntactic change to ensure that Perl 6 still has the Perlish nature and that the change was an overall improvement. Some Perl programmers delight in the syntactic differences of the language, but some of those differences aren't that important when compared to the big picture of Perl's culture (which includes the language, CPAN, and the community of programmers).
Sigil Invariance
One of the fundamental changes is that whenever you refer to individual elements of an aggregate (an array or hash), rather than changing the sigil to denote the type of thing you get back, the sigil remains the same.
For example, in both Perl 5 and Perl 6 you can create and initialize aggregates:
my @array = (1,3,5,12,37,42);
my %hash = ( alpha => 4, beta => 6 ); How you access the individual elements of those aggregates looks just a little different:
# Perl 6 # Perl 5
my $third = @array[2]; my $third = $array[2];
my $beta = %hash{'beta'}; my $beta = $hash{'beta'}; Long-time Perl 5 programmers might wonder how slices work in Perl 6. The answer is: the same way as in Perl 5.
my @odds = @array[1,3,5]; # array slice
my @bets = %hash{'alpha','beta'}; # hash slice The only difference is that in Perl 5 the hash slice would have started with a @ sigil.
New Brackets
In these hash examples, it's awkward quoting the indexes into the hash. Perl 5 allows a syntactic shortcut where $hash{word} works as if you had written $hash{'word'}. A problem with that is that it can cause confusion when your word happens to be the name of a subroutine and you really want Perl to execute that subroutine.
In Perl 6, a syntactic shortcut for accessing hash elements takes advantage of a name change of the "quote word" operator:
# Perl 6 # Perl 5
my @array = ; my @array = qw(foo bar baz);
my %hash = ; my %hash = qw(a b c d e f g h);
my $queue = %hash; my $queue = $hash{'q'};
my @vows = %hash; my @vows = @hash{qw(c a g e)};
my $foo = "This is";
my $bar = "the end";
my @blah = << $foo $bar >>; # ('This','is','the','end');
Note that the interpolation happens before the "quote word" aspect of this operator.
my @items = ;
say "Send @items[] to test@foo.com";
# Send names addresses email to test@foo.com
You can also interpolate more things into your double-quoted strings:
say "Send me $person.name()"; # results of a method call
say "2 + 2 = { 2+2 }"; # any bit of perl code
Better Code Through Destruction
Perl's garbage collector counts references. When the count reaches zero (which means that no one has a reference), Perl reclaims the entity. The approach is simple and effective. However, circular references (when object A has a reference to object B, and object B has a reference to object A) present a problem. Even if nothing else in the program has a reference to either A or B, the reference count can never reach zero. Objects A and B do not get destroyed. If the code creates them again and again (perhaps in a loop), you get a memory leak. The amount of memory allocated by the program increases without a sensible reason and can never decrease. This effect may be acceptable for simple run-and-exit scripts, but it's not acceptable for programs running 24x365, such as in a mod_perl or FastCGI environment or as standalone servers.
Circular references are sometimes too useful to avoid. A common example is a tree-like data structure. To navigate both directions--from root to leaves and vice versa--a parent node has a list of children and a child node has a reference to its parent. Here are the circular references. Many CPAN modules implement their data models this way, including HTML::Tree, XML::DOM, and Text::PDF::File. All these modules provide a method to release the memory. The client application must call the method when it no longer needs an object. However, the requirement of an explicit call is not very appealing and can result in unsafe code:
Making Perl Reusable with Modules

Perl software development can occur at several levels. When first developing the idea for an application, a Perl developer may start with a short program to flesh out the necessary algorithms. After that, the next step might be to create a package to support object-oriented development. The final work is often to create a Perl module for the package to make the logic available to all parts of the application. Andy Sylvester explores this topic with a simple mathematical function.
Creating a Perl Subroutine
I am working on ideas for implementing some mathematical concepts for a method of composing music. The ideas come from the work of Joseph Schillinger. At the heart of the method is being able to generate patterns using mathematical operations and using those patterns in music composition. One of the basic operations described by Schillinger is creating a "resultant," or series of numbers, based on two integers (or "generators"). Figure 1 shows a diagram of how to create the resultant of the integers 5 and 3.
Figure 1. Creating the resultant of 5 and 3
Figure 1 shows two line patterns with units of 5 and units of 3. The lines continue until both lines come down (or "close") at the same time. The length of each line corresponds to the product of the two generators (5 x 3 = 15). If you draw dotted lines down from where each of the two generator lines change state, you can create a third line that changes state at each of the dotted line points. The lengths of the segments of the third line make up the resultant of the integers 5 and 3 (3, 2, 1, 3, 1, 2, 3).
Schillinger used graph paper to create resultants in his System of Musical Composition. However, another convenient way of creating a resultant is to calculate the modulus of a counter and then calculate a term in the resultant series based on the state of the counter. An algorithm to create the terms in a resultant might resemble:
Read generators from command line
Determine total number of counts for resultant
(major_generator * minor_generator)
Initialize resultant counter = 0
For MyCounts from 1 to the total number of counts
Get the modulus of MyCounts to the major and minor generators
Increment the resultant counter
If either modulus = 0
Save the resultant counter to the resultant array
Re-initialize resultant counter = 0
End if
End for From this design, I wrote a short program using the Perl modulus operator (%):
#!/usr/bin/perl
#*******************************************************
#
# FILENAME: result01.pl
#
# USAGE: perl result01.pl major_generator minor_generator
#
# DESCRIPTION:
# This Perl script will generate a Schillinger resultant
# based on two integers for the major generator and minor
# generator.
#
# In normal usage, the user will input the two integers
# via the command line. The sequence of numbers representing
# the resultant will be sent to standard output (the console
# window).
#
# INPUTS:
# major_generator - First generator for the resultant, input
# as the first calling argument on the
# command line.
#
# minor_generator - Second generator for the resultant, input
# as the second calling argument on the
# command line.
#
# OUTPUTS:
# resultant - Sequence of numbers written to the console window
#
#**************************************************************
use strict;
use warnings;
my $major_generator = $ARGV[0];
my $minor_generator = $ARGV[1];
my $total_counts = $major_generator * $minor_generator;
my $result_counter = 0;
my $major_mod = 0;
my $minor_mod = 0;
my $i = 0;
my $j = 0;
my @resultant;
print "Generator Total = $total_counts\n";
while ($i < $total_counts) { $i++; $result_counter++; $major_mod = $i % $major_generator; $minor_mod = $i % $minor_generator; if (($major_mod == 0) || ($minor_mod == 0)) { push(@resultant, $result_counter); $result_counter = 0; } print "$i \n"; print "Modulus of $major_generator is $major_mod \n"; print "Modulus of $minor_generator is $minor_mod \n"; } print "\n"; print "The resultant is @resultant \n"; Run the program with 5 and 3 as the inputs (perl result01.pl 5 3):
Generator Total = 15
1
Modulus of 5 is 1
Modulus of 3 is 1
2
Modulus of 5 is 2
Modulus of 3 is 2
3
Modulus of 5 is 3
Modulus of 3 is 0
4
Modulus of 5 is 4
Modulus of 3 is 1
5
Modulus of 5 is 0
Modulus of 3 is 2
6
Modulus of 5 is 1
Modulus of 3 is 0
7
Modulus of 5 is 2
Modulus of 3 is 1
8
Modulus of 5 is 3
Modulus of 3 is 2
9
Modulus of 5 is 4
Modulus of 3 is 0
10
Modulus of 5 is 0
Modulus of 3 is 1
11
Modulus of 5 is 1
Modulus of 3 is 2
12
Modulus of 5 is 2
Modulus of 3 is 0
13
Modulus of 5 is 3
Modulus of 3 is 1
14
Modulus of 5 is 4
Modulus of 3 is 2
15
Modulus of 5 is 0
Modulus of 3 is 0
The resultant is 3 2 1 3 1 2 3 This result matches the resultant terms as shown in the graph in Figure 1, so it looks like the program generates the correct output.
Linux: Mount a Windows file system from Linux

Question: How can I mount a Windows file system from Linux?
Answer: To mount a Windows file system from Linux can be a challenging task.
To begin, you'll need to determine what kind of Windows file system you are trying to view. Most flavors of Linux come with appropriate drivers for the most common file system types.
Windows 3.x, 95, 98, 98SE, and ME usually use a MSDOS or a VFAT formatted partition. (VFAT is a replacement file system, which is more efficient than the older MSDOS one.)
Windows NT4, 2000, and XP generally use a more advanced file system called NTFS.
All of the RedHat releases of Linux ship with support for the MSDOS and VFAT file systems. The newer NTFS file system is a different story. Very few of the Linux distributors ship with out-of-the-box support. This is for a good reason. While there is quite a bit known and published about MSDOS and VFAT, Microsoft has kept the specifics for NTFS very quiet, so the implementations vary in stability and features.
Fortunately, there is a web site which maintains RPM packages with appropriate NTFS drivers for most recent versions of RedHat Linux. The site can be found at:
http://linux-ntfs.sourceforge.net/info/redhat.html
If you are attempting to mount an NTFS file system, you'll need to download the appropriate RPM for your system. If you are unsure of how to do this or are confused by the next step, I would recommend that you seek more advanced Linux help. All systems are different so it is difficult to provide exact help with these types of problems.
To continue, you'll need to have determined what type of file system you have. If it is an NTFS file system, you will also need to have downloaded the correct RPM package from the site above and installed it without error.
Now that you have the necessary driver support installed, you'll need to determine which partition holds the Windows file system you need access to. You may already know this from your installation procedures.
Linux uses a different convention than Windows for describing disk partitions. A typical example of a Linux partition would be:
/dev/sda2
This indicates that you installed windows on your SCSI disk on the second partition.
An IDE hard drive would look something like:
/dev/hda2
If you have more than one hard disk in your computer, the convention will be different. For example, for the first partition on the second SCSI hard disk would take the form:
/dev/sdb1
Hopefully by now, you've determined where you installed your Windows file system.
Next, assuming an NTFS file system, try mounting the partition by typing something like:
mount -t ntfs /dev/sda1 /mnt (Of course replacing the /dev/sda1 with your partition specifics.)
This command should complete without error. If you get an error, you may either not have the file system driver installed correctly or the partition you specified may be incorrect.
For VFAT or MSDOS partitions, change the -t flag in the mount command to "vfat" or "msdos".
Accessing disk partitions is a very dangerous task and should be done with great care. If you have any trouble with the commands or concepts above, please ask an advanced Linux user to take a look at your system.
Monday, August 6, 2007
There are various advantages of CGI:
- Simplicity. CGI provides a simple way of running programs on the server when a request is received and it is conceptually easy to understand the underlying process.
- Process Isolation. Since CGI applications run in separate processes, buggy applications will not crash the Web server or access the server's private internal state.
- Portability. CGI is an open standard. CGI is not tied to any particular (such as single- or multi-threaded) server architecture. CGIs are far more portable over other alternatives such as server extension APIs.
- Language Independency. CGI applications can be written in nearly any language.
- Support. CGI is a proven technology, and some form of CGI has been implemented on almost every Web server on a variety of platforms. There are many CGI scripts available for free for a variety of applications: as user-friendly front-ends to databases, search engines, scientific analysis tools, traditional inventory systems, gateways to network services such as gopher or whois.
- Evolvability. CGI is alive and well, and as pointed out in Webmaster's Domain: Is CGI Dead?, work towards CGI 1.2 specification is in progress.