1

I wrote a simple webserver which should continuously handle simultaneous requests. But, even after detaching the threads it doesn't handle simultaneous requests. Can someone help?

Webserver.pl

use HTTP::Daemon;
use threads;

my $webServer;
my $package_map = {"test"  => "test"};
my $d = HTTP::Daemon->new(LocalAddr => $ARGV[0],
                          LocalPort => 80,
                          Listen => 20) || die;

print "Web Server started!\n";
print "Server Address: ", $d->sockhost(), "\n";
print "Server Port: ", $d->sockport(), "\n";


while (my $c = $d->accept) {
    threads->create(\&process_req, $c)->detach();
}

sub process_req {
    my $c = shift;
    my $r = $c->get_request;
    if ($r) {
        if ($r->method eq "GET") {
            my $path = $r->url->path();
            my $service = $package_map->{$path};
            if ($service) {
                $response = $service->process_request($request);
            }
        }
    }
    $c->close;
    undef($c);
}

test.pm

sub process_request
{
    threads->create(\&testing)->detach();
    my $response = HTTP::Response -> new (200);
    $response -> header('Access-Control-Allow-Origin', '*');
    $response -> content("Success");
    return $response; 
}

sub testing
{
    my $command = 'echo "sleep 100" | ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 <dev_box>';
    if (system($command) != 0) {
        print "FAILED\n";
    }
}
Soumya dutta
  • 79
  • 1
  • 7
  • You should add some `print` statements so you see where the webserver hangs. HTTP::Daemon suggests a while loop for a connection: `while (my $r = $c->get_request) {` – Corion Sep 28 '18 at 09:10
  • It doesn't hang, but sleeps for 100 second & then start taking requests again. – Soumya dutta Sep 28 '18 at 09:23
  • I can't replicate your problem. When replace your submodule with `sleep 100`, and actually call `$c->send_response()`, I can connect at least three parallel HTTP requests, that each get handled after 100 seconds. I'll post the working code as a reply below. – Corion Sep 28 '18 at 12:11
  • What's the output of `perl -v | grep 'This is' ; perl -V:useithreads`? – ikegami Sep 28 '18 at 17:49

1 Answers1

1

Here is code based on your example that works for me on Windows. Maybe you can show us how/where it fails for you:

#!perl
use strict;
use warnings;
use HTTP::Daemon;
use threads;

my $webServer;
#my $package_map = {"test"  => "test"};
my $d = HTTP::Daemon->new(LocalAddr => $ARGV[0],
                          LocalPort => $ARGV[1] // 80,
                          Listen => 20) || die;

print "Web Server started!\n";
print "Server Address: ", $d->sockhost(), "\n";
print "Server Port: ", $d->sockport(), "\n";


while (my $c = $d->accept) {
    warn "New connection";
    threads->create(\&process_req, $c)->detach();
}

sub process_req {
    my $c = shift;
    while( my $r = $c->get_request ) {
        if ($r) {
            if ($r->method eq "GET") {
                my $path = $r->url->path();
                if (1) {
                    sleep 100;
                    $c->send_response( HTTP::Response->new(200, "OK", undef, "done\n") );
                }
            }
        }
    };
    $c->close;
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
Corion
  • 3,855
  • 1
  • 17
  • 27
  • When you create another thread inside process_req function, then multiple request doesn't work simultaneously. – Soumya dutta Sep 28 '18 at 13:37
  • Can you maybe edit either my example or your example to actually reproduce the problem, while still being in a single file? At least on Windows, I can't reproduce your problem with the code given. – Corion Sep 28 '18 at 14:51
  • 1
    [Works fine](https://pastebin.com/vyNcn9be) in Linux too. @Soumya dutta, Are you sure you have a threaded build of Perl? – ikegami Sep 28 '18 at 17:39