Seeking event loop concurrent solution to challenge problem

View: New views
3 Messages — Rating Filter:   Alert me  

Seeking event loop concurrent solution to challenge problem

by ihab.awad :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi folks,

The CommonJS group seeks to build a "common" (i.e., not just Web
pages) platform of JavaScript. In this thread, we asked ourselves what
to do about concurrency:

http://groups.google.com/group/commonjs/browse_thread/thread/fa20fc6a3649b3a

A lot of us are fans of shared-nothing event loop concurrency, so we
thought about using HTML5's "workers" as our starting point. However,
it seems that using these requires a bunch of boilerplate, some of
which may be automated, and some of which may not. I'd love to see
someone code the solution in E, say, and we could backtrack from
there.

Problem: A multi threaded Web server that serves up a hit count for a
single page.

Kris Zyp's shared memory solution, from the email thread, is:

var hits = 0;
var lock = new (require("concurrency")).Lock(); // This just loads a module
function incrementAndGetHits(){
   lock.lock();
   hits++;
   lock.unlock();
   return hits;
}
exports.app = function(env) { // Exported function that worker threads run
   return {
       status:200,
       headers:{"content-type":"text/plain"},
       body: "This page has been hit " + incrementAndGetHits() + " times";
   };
}

Given that E was essentially built for shared-nothing event loop
concurrency, what does it look like in E?

Ihab

--
Ihab A.B. Awad, Palo Alto, CA
_______________________________________________
e-lang mailing list
e-lang@...
http://www.eros-os.org/mailman/listinfo/e-lang

Re: Seeking event loop concurrent solution to challenge problem

by Kevin Reid-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sep 24, 2009, at 0:27, ihab.awad@... wrote:

> A lot of us are fans of shared-nothing event loop concurrency, so we
> thought about using HTML5's "workers" as our starting point. However,
> it seems that using these requires a bunch of boilerplate, some of
> which may be automated, and some of which may not. I'd love to see
> someone code the solution in E, say, and we could backtrack from
> there.

Well, there are two levels of "event loop concurrency" to me, so I  
think it's best to be a bit more specific:

1. Multiple tasks being performed within a single event loop: they are  
interleaved but not parallel.

2. Multiple event loops in seaparate threads -- "communicating event  
loops" -- which pass messages.

Since you mention "multi threaded" I assume you want the latter.

> Problem: A multi threaded Web server that serves up a hit count for a
> single page.
>
> Kris Zyp's shared memory solution, from the email thread, is:
>
> var hits = 0;
> var lock = new (require("concurrency")).Lock(); // This just loads a  
> module
> function incrementAndGetHits(){
>   lock.lock();
>   hits++;
>   lock.unlock();
>   return hits;
> }
> exports.app = function(env) { // Exported function that worker  
> threads run
>   return {
>       status:200,
>       headers:{"content-type":"text/plain"},
>       body: "This page has been hit " + incrementAndGetHits() + "  
> times";
>   };
> }
>
> Given that E was essentially built for shared-nothing event loop
> concurrency, what does it look like in E?

OK, so I see that this has nothing for e.g. accepting incoming  
connections. We assume the thread pool (vat pool) exists and something  
distributes requests among them.

Now, the absolute most straightforward solution would just be to  
translate that code above, and strip out the locking. As a plain  
function, 'app' just becomes a far reference when passed to the worker  
vats, so it is safe and functions as intended. But I assume that we  
should consider the 'app' function to be expensive, i.e. it should be  
run in multiple threads and only incrementAndGetHits is shared.

Then, the primary practical question is how the app function gets  
instantiated in the worker threads.

var hits := 0

def incrementAndGetHits() {
   hits += 1
   return hits
}

def app implements pbc { # pass-by-construction

   # Still a function object, just with extra methods

   to run() {
     when (def hitsNow := incrementAndGetHits <- ()) -> {
       return [
         "status" => 200,
         "headers" => ["Content-Type": "text/plain"],
         "body" => `This page has been hit $hitsNow times`,
       ]
     } catch p {
       # This will be executed if the above block has an unexpected
       # error OR if the cross-vat incrementAndGetHits request fails
       # somehow (e.g. origin vat died).
       traceln("Error in handling request: ", p)
       return [
         "status" => 500,
         "headers" => ["Content-Type": "text/plain"],
         "body" => `An oopsie happened!`,
       ]
     }
   }

   to __optUncall() {
     # __eval isn't actually implemented yet (MarkM: Why? What's the
     # holdup? Is it the unshadowable-names thing? If so, I think we can
     # drop it now that we're definitely going GBA), but my  
understanding
     # is that something like this is the plan.
     #
     # There are also slight differences in the meta-operations, but
     # this can still be done in E-as-it-is-now with slightly different
     # spelling and a helper function.

     return [__eval, "run", [meta.context(app).getSource(),
                             meta.getEnv(app),
                             false,
                             [].asMap()]]
   }
}

(With regard to the length of the above code, please note that it's  
mostly comments, fancy formatting, and an extra bit of error handling.)

This makes "app" a _mobile code object_ which is copied into any vat  
it is sent to. In any vat but its origin, incrementAndGetHits will be  
a far reference, so it is invoked with "<-" rather than ".".

Another way would be for the uncall method to specify "make an app  
worker function" by name to the receiving vat; this assumes that all  
the vats have access to the same library, which is probably true for a  
single web server system.

Either way, the key is that incrementAndGetHits is itself the event-
loop-spanning reference.

--
Kevin Reid                                  <http://switchb.org/kpreid/>




_______________________________________________
e-lang mailing list
e-lang@...
http://www.eros-os.org/mailman/listinfo/e-lang

Re: Seeking event loop concurrent solution to challenge problem

by Karp, Alan H :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

ihab wrote:
>
> A lot of us are fans of shared-nothing event loop concurrency, so we
> thought about using HTML5's "workers" as our starting point. However,
> it seems that using these requires a bunch of boilerplate, some of
> which may be automated, and some of which may not. I'd love to see
> someone code the solution in E, say, and we could backtrack from
> there.
>
Tyler has some JavaScript examples at http://waterken.sourceforge.net/#tour, such as the Bang Tutorial.

________________________
Alan Karp
Principal Scientist
Virus Safe Computing Initiative
Hewlett-Packard Laboratories
1501 Page Mill Road
Palo Alto, CA 94304
(650) 857-3967, fax (650) 857-7029
http://www.hpl.hp.com/personal/Alan_Karp


> -----Original Message-----
> From: e-lang-bounces@... [mailto:e-lang-bounces@...-
> os.org] On Behalf Of ihab.awad@...
> Sent: Wednesday, September 23, 2009 9:27 PM
> To: Discussion of E and other capability languages
> Cc: Kris Zyp
> Subject: [e-lang] Seeking event loop concurrent solution to challenge
> problem
>
> Hi folks,
>
> The CommonJS group seeks to build a "common" (i.e., not just Web
> pages) platform of JavaScript. In this thread, we asked ourselves what
> to do about concurrency:
>
> http://groups.google.com/group/commonjs/browse_thread/thread/fa20fc6a36
> 49b3a
>
> A lot of us are fans of shared-nothing event loop concurrency, so we
> thought about using HTML5's "workers" as our starting point. However,
> it seems that using these requires a bunch of boilerplate, some of
> which may be automated, and some of which may not. I'd love to see
> someone code the solution in E, say, and we could backtrack from
> there.
>
> Problem: A multi threaded Web server that serves up a hit count for a
> single page.
>
> Kris Zyp's shared memory solution, from the email thread, is:
>
> var hits = 0;
> var lock = new (require("concurrency")).Lock(); // This just loads a
> module
> function incrementAndGetHits(){
>    lock.lock();
>    hits++;
>    lock.unlock();
>    return hits;
> }
> exports.app = function(env) { // Exported function that worker threads
> run
>    return {
>        status:200,
>        headers:{"content-type":"text/plain"},
>        body: "This page has been hit " + incrementAndGetHits() + "
> times";
>    };
> }
>
> Given that E was essentially built for shared-nothing event loop
> concurrency, what does it look like in E?
>
> Ihab
>
> --
> Ihab A.B. Awad, Palo Alto, CA
> _______________________________________________
> e-lang mailing list
> e-lang@...
> http://www.eros-os.org/mailman/listinfo/e-lang
_______________________________________________
e-lang mailing list
e-lang@...
http://www.eros-os.org/mailman/listinfo/e-lang