Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re^6: Help designing a threaded service

by Tommy (Chaplain)
on Jan 26, 2014 at 20:08 UTC ( #1072141=note: print w/replies, xml ) Need Help??


in reply to Re^5: Help designing a threaded service
in thread Help designing a threaded service

You wanna do thing the st hard way; have fun.......

It's actually out of a desire to avoid doing things the stupid way that I posted my question to the Monastery in the first place. An abundance of problems have been pointed out by several people -- problems that are already solved by existing "wheels" on the CPAN that I'd almost certainly be better off to not reinvent.

So my "sane" options are singular: to extend a given stable wheel (Net::Server?) via some sort of data/state sharing mechanism so that when any given listener is presented with a task ID, that it is able to retrieve the output of that task beginning from the last time it was polled. Designing and implementing that will be my biggest challenge. I still want to avoid using a database for this, but may have to fall back on that option.

As for the stupidity, the overhead of constantly polling the service every N seconds is a necessary evil that I see no way to avoid. The aces up my sleeve are that it's not going to have to expand beyond ~20 concurrent users for the foreseeable future, and it's on a very, very fast LAN. I've already personally seen Net::Server scale well past that kind of load on lesser networks.

I appreciate your insight BrowserUk, and that of all others who have joined in on the conversation.

 

Tommy
A mistake can be valuable or costly, depending on how faithfully you pursue correction
  • Comment on Re^6: Help designing a threaded service

Replies are listed 'Best First'.
Re^7: Help designing a threaded service
by BrowserUk (Patriarch) on Jan 26, 2014 at 20:50 UTC
    So my "sane" options are singular: to extend a given stable wheel (Net::Server?) via some sort of data/state sharing mechanism so that when any given listener is presented with a task ID, that it is able to retrieve the output of that task beginning from the last time it was polled.

    Problem is, you've bought into the fallacy that the behemoth that is Net::Server is going to solve some high proportion of your problem. It won't.

    The very essence of your project is the problem of routing multiple discrete client connects back to the sources of their data. Handling the connects (the only bit that Net::Server will do for you) is the easy part. Plumbing the appropriate clients to their appropriate data sources is a plumbing problem that Net::Server has no solution to. And using a forking solution for that means you are going to be forced into a multiplexing nightmare.

    Which is just silly when -- by your own statement -- you only need ~20 clients, which takes just 36MB for 21 threads:

    perl -Mthreads=stack_size,4096 -MIO::Socket -E"async{ IO::Socket::INET +->new( 'localhost:' . 12300 + threads->tid ); sleep }->detach for 1 . +. 20; sleep"

    A bit more for some shared memory and all your routing problems become trivial.

    C'est la vie :)


    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.

      Your response is exactly why I want to go with threading: because I can solve all my hard problems via shared memory vars, easily reconnecting a request to it's output stream. But I have to face some unhappy facts: I don't know enough about threading to know what's necessary to keep the thread memory consumption from ballooning out of control. I also don't know how to handle corner cases that I've yet to identify with the creation of a highly-available multi-threaded network service. And finally I don't yet know gracefully kill off threads that get "stuck" without resorting to a SIGKILL (which isn't exactly a showstopper, but the other issues are).

      The multi-threaded IRC chat bot code that was shared earlier in this discussion is too bare-boned to inspire confidence that extending it could handle the problems I've outlined above. If I venture down this path, I'd need a map and a guide. And frankly the latter and more essential of the two is hard to come by in *nix land where forking is king and threading has a bad reputation for, from what I can tell, all stupid reasons.

      Tommy
      A mistake can be valuable or costly, depending on how faithfully you pursue correction
        But I have to face some unhappy facts: I don't know enough about threading ...

        But you do know enough about multiplexing processes via pipes or unix-domain sockets; or attaching shared memory segments in order to solve those problems?

        With regard to the potential barriers you perceive to a threaded solution:

        1. what's necessary to keep the thread memory consumption from ballooning out of control

          Why do you think this would happen?

          There are two ways memory consumption grows out of control:

          • You program the server to spawn lots of threads.

            So don't do that. Re-use existing ones.

          • You allow queues to grow unconstrained.

            So, don't do that. Constrain them.

        2. how to handle corner cases that I've yet to identify with the creation of a highly-available multi-threaded network service.

          I don't know how to handle unidentified problems either.

          But generally, if and when a problem is identified, it usually has an obvious and simple solution.

        3. I don't yet know gracefully kill off threads that get "stuck" without resorting to a SIGKILL

          There is no such thing as a "graceful kill".

          Needing to kill a thread (rather than either asking it to die or allowing it to come to a 'natural death') is a really bad design technique. One of absolutely last resort when all other options fail. Design properly and it should never be necessary.

          With a server, the primary problem is one of ensuring that you never enter a read state to a socket unless there is data available.

          Under windows, where Perl doesn't provide access to the appropriate low-level IO routines to allow reads to be interrupted, that pretty much forces a polling (select or IO::Select) server design. That's a pain because it means implementing line or block buffering yourself; but it's not terribly hard. And if you strictly limit your select groups to just one or two handles per thread, each thread can still deal with just one client and its remote proxy thus avoiding the need to put all your pipes through a single central loop.

          Under *nix, I've been told that read & readline are interruptible using alarm, so you should be able to avoid polling whilst still retaining the guarantee that if a client goes away, you won't leave a thread stuck. (But I don't have the experience to back that up, nor the environment to test it.)

        But, it's your project and your call. You have to decide which set of skills are going to be easiest for you to acquire; which probably comes down to which route to your goal you will get most support in pursuing.

        From my perspective, the most daunting part of your task is the webserver/AJAX client bits, of which I have little to no knowledge, and for which I am not set up nor have any desire to be so.


        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.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2022-11-28 17:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?