Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re^7: How to maintain a persistent connection over sockets? (Amazing! Multi-tasking without multi-tasking!)

by BrowserUk (Pope)
on May 05, 2012 at 09:28 UTC ( #969030=note: print w/ replies, xml ) Need Help??


in reply to Re^6: How to maintain a persistent connection over sockets? (Amazing! Multi-tasking without multi-tasking!)
in thread How to maintain a persistent connection over sockets?

And it has to be. ... So by forcing all cache activity into one process, ... you force an orderly environment.

No it doesn't. You are confusing multi-tasking with multi-process.

You can multi-task within a single process, and a single thread, using a select loop. Though the apis are badly documented and so awkward to use that even those that consider themselves experts often use them wrongly. That combined with architectural straight-jacket it forces you into, mean I cannot recommend it. At least not on its own.

Equally, if you start a thread within your server to converse with each client, then you are still running in a single process, and can still enforce an orderly environment.

The upside is that your clients no longer have to disconnect after every communication in order to break out of the inner loop within the server and allow other clients to communicate. That is what you are doing now, and it is the source of your multi-client performance woes.

By way of example, this very simple (crude) threaded server can easily sustain concurrent conversations with 100 clients, and maintain an exchanges (client request/server reply) rate of close to 1000 exchanges per second to all of them:

#! perl -slw use strict; use threads; use IO::Socket; $\ = $/ = chr(13).chr(10); my $lsn = IO::Socket::INET->new( Reuse => 1, Listen => 1, LocalPort => + 12345 ) or die "Server failed to create listener: $^E"; print "Server listener created"; while( my $client = $lsn->accept ) { print "Server accepting client connection"; async { while( my $in = <$client> ) { chomp $in; ## printf "\rServer echoing client input: '%s'", $in; print $client $in; } print "Server shutting down"; shutdown $client, 2; close $client; }->detach; }

And here is a simple client:

#! perl -slw use strict; use Time::HiRes qw[ time ]; use IO::Socket; our $R //= 1; $\ = $/ = chr(13).chr(10); my $svr = IO::Socket::INET->new( "localhost:12345" ) or die "Client: First client connect failed $^E"; print "Client connected"; my $last = time; my $exchanges = 0; while( 1 ) { print {$svr} "Hello"x $R or die "$! / $^E"; chomp( my $in = <$svr> ); ++$exchanges; if( int(time()) > int($last) ) { printf "Rate: %.f exchanges/sec)\n", $exchanges / ( time() - $last ); $last = time; $exchanges = 0; } }

And runs showing typical exchanges rates for 1, 3, and 10 concurrent clients:

[10:18:14.83] C:\test>for /L %i in ( 1,1,1) do @start /B t-sockCC -R=1 [10:22:34.94] C:\test>Client connected Rate: 21485 exchanges/sec) Rate: 22023 exchanges/sec) Rate: 21923 exchanges/sec) ...

3 clients:

[10:22:38.82] C:\test>for /L %i in ( 1,1,3) do @start /B t-sockCC -R=1 [10:22:43.80] C:\test>Client connected Client connected Client connected Rate: 16958 exchanges/sec) Rate: 16606 exchanges/sec) Rate: 17124 exchanges/sec) Rate: 17962 exchanges/sec) Rate: 17832 exchanges/sec) Rate: 17982 exchanges/sec) Rate: 18066 exchanges/sec) Rate: 17963 exchanges/sec) Rate: 18069 exchanges/sec) Rate: 17956 exchanges/sec) Rate: 17953 exchanges/sec) Rate: 17917 exchanges/sec) ...

And 10 clients:

[10:22:47.85] C:\test>for /L %i in ( 1,1,10) do @start /B t-sockCC -R= +1 [10:22:54.26] C:\test>Client connected Client connected Client connected Client connected Client connected Client connected Client connected Client connected Client connected Client connected Rate: 5931 exchanges/sec) Rate: 5852 exchanges/sec) Rate: 6870 exchanges/sec) Rate: 5446 exchanges/sec) Rate: 6356 exchanges/sec) Rate: 6394 exchanges/sec) Rate: 6207 exchanges/sec) Rate: 6286 exchanges/sec) Rate: 6730 exchanges/sec) Rate: 5699 exchanges/sec) Rate: 6337 exchanges/sec) Rate: 6273 exchanges/sec) Rate: 6373 exchanges/sec) Rate: 6134 exchanges/sec) Rate: 6138 exchanges/sec) Rate: 6139 exchanges/sec) Rate: 6103 exchanges/sec) Rate: 6052 exchanges/sec) Rate: 6095 exchanges/sec) Rate: 6289 exchanges/sec) Rate: 6236 exchanges/sec) Rate: 6482 exchanges/sec) Rate: 6468 exchanges/sec) Rate: 6274 exchanges/sec) Rate: 6461 exchanges/sec) Rate: 6413 exchanges/sec) Rate: 6241 exchanges/sec) Rate: 6207 exchanges/sec) Rate: 6172 exchanges/sec) Rate: 6241 exchanges/sec) ...

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

The start of some sanity?


Comment on Re^7: How to maintain a persistent connection over sockets? (Amazing! Multi-tasking without multi-tasking!)
Select or Download Code
Re^8: How to maintain a persistent connection over sockets? (Amazing! Multi-tasking without multi-tasking!)
by flexvault (Parson) on May 05, 2012 at 09:55 UTC

    BrowserUk,

    W O W !

    Let me look at this for a while. Looks good!

    Thank you

    "Well done is better than well said." - Benjamin Franklin

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://969030]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (12)
As of 2014-09-22 20:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (200 votes), past polls