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

[email protected] ("Maxim Maltchevski")
Newsgroups perl.ithreads
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.