develooper Front page | perl.ithreads | Postings from May 2003

Anyone tried to create multitreaded HTTP daemon using SOAP::Lite?

From:
Maxim Maltchevski
Date:
May 9, 2003 09:11
Subject:
Anyone tried to create multitreaded HTTP daemon using SOAP::Lite?
Message ID:
DOEGLNKAPNOKCOLOIOHCAEDACAAA.maxim.maltchevski@surveysite.com
Hi everyone:
I'm writing a simple HTTP daemon using SOAP::Lite. I would like to handle
each client request in its own thread to improve the response time. I'm
working with the Active State Perl 5.8.0, build 806 on a Win2K Pro machine.
The following code blocks in the $conn->get_request() call until it times
out (sub process_request). If I uncomment "sleep 1" line in the parent loop,
then the threads are created and executed one after another as expected but
this, of course, defeats the whole purpose of using threads. I can't share
my $conn variable which holds the current client connection object: I'm
getting "Can't share GLOBS yet" error message. At the same time even when
the code works with "sleep 1", the threads don't seem to be able to close
the connection they inherited from the parent process. The code in "else"
block (not using threads) works just fine. I'm probably doing something
wrong with the threads. Does anyone know about any sample code I could look
at implementing the threads to handle the client connections?

Any help is greatly appreciated.
Thank you,
Maxim


package SoapDataDaemon;

# inherit this
use SOAP::Transport::HTTP;
@SoapDataDaemon::ISA = qw( SOAP::Transport::HTTP::Daemon );

# pragmas
use strict;
use warnings;

# multi-threaded version
use threads;
use threads::shared;

# version
our $VERSION = 1.000;

# Extension Modules
use Data::Dumper;
$Data::Dumper::Indent = 3;
use Log::Log4perl qw(:easy);

sub handle
{
    my $self = shift;
    my %args = @_;

    # get the args
    my $use_threads = $args{'use_threads'} || 0;

    # get the logger
    my $log = get_logger();

    # which way are we going?
    if ($use_threads) {

        # run threads

        if ($log->is_debug()) {
            $log->debug("Using threads...");
        }

        # it's a copy of $self normally
        my $daemon = $self->new();

        # listening for connections
        my $connection = 0;
        while (my $conn = $daemon->accept) {

            # increment the counter
            $connection++;

            if ($log->is_debug()) {
                $log->debug("Main loop accepted connection $connection: ",
sub{Dumper($conn)});
            }

            # this will go in its own thread
            my $thread = threads->create(\&process_request, $daemon, $conn);
            $thread->detach();

            if ($log->is_debug()) {
                $log->debug("Main loop connection $connection after thtread:
", sub{Dumper($conn)});
            }

            #sleep 1;

        } # while accept

    } else {

        if ($log->is_debug()) {
            $log->debug("NOT Using threads...");
        }

        # it's a copy of $self normally
        my $daemon = $self->new();

        # listening for connections
        while (my $conn = $daemon->accept) {

            # get and process request
            while (my $r = $conn->get_request) {
                # handle request here
                $daemon->request($r);
                $daemon->SOAP::Transport::HTTP::Server::handle();
                $conn->send_response($daemon->response);
            } # while get_request

            $conn->close();
            undef $conn;

        } # while accept

    } # endif use_threads

} # handle

=head2 B<process_request()>

Process each request in its own thread

=cut

sub process_request
{
    my $daemon = shift;
    my $conn   = shift;

    my $log = get_logger();
    if ($log->is_debug()) {
        $log->debug("Thread: ", threads->tid(), " Conn: ",
sub{Dumper($conn)});
    }

    if ($log->is_debug()) {
        $log->debug("Thread: ", threads->tid(), " Host: ",
$conn->peerhost(), " Port: ", $conn->peerport());
    }

    # get and process request
    while (my $r = $conn->get_request) {

        if ($log->is_debug()) {
            $log->debug("Thread: ", threads->tid()," Processing request");
        }

        # handle request here
        $daemon->request($r);
        $daemon->SOAP::Transport::HTTP::Server::handle();
        $conn->send_response($daemon->response);

    } # while get_request

    $conn->close();
    undef $conn;

    if ($log->is_debug()) {
        $log->debug("Thread: ", threads->tid()," Connection closed.");
    }

} # process_request




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About