On Mon, Oct 3, 2011 at 7:53 PM, Liam <networkimp...@gmail.com> wrote: > Your eio_custom evalInBackground procedure files the V8 isolate for > future use after constructing it, and if they're memory-intensive you > set a timer to destruct them.
> On Oct 3, 4:38 pm, Isaac Schlueter <i...@izs.me> wrote:
> > If you do this with a v8 isolate, it could be made safe. *However*, > > afaik the last time this was investigated, the cost of creating a new > > context was much too high to do on each request. In fact, that's the > > bulk of creating a new node process.
On Mon, Oct 3, 2011 at 7:36 PM, Isaac Schlueter <i...@izs.me> wrote: > Dean, even if you were to serialize the object, you also have to watch > out for functional side-effects.
> var x = 100 > function foo () { x = 10000 } > evalInBackground(foo, cb)
> while (x === 100) { > console.log("ok") > } > throw new Error("SPOOKY!!")
> Let's please not ruin node with parallel access to javascript objects.
I completely agree. That's why I said "no functions (or functions that are stringified and eval'd in the background context)". That eval in an isolated context means to dangling refs that could be used. Though I think isolates may already provide this guarantee so the serialization step may be unnecessary.
On Mon, Oct 3, 2011 at 7:38 PM, Isaac Schlueter <i...@izs.me> wrote: > Oh, forgot to add:
> If you do this with a v8 isolate, it could be made safe. *However*, > afaik the last time this was investigated, the cost of creating a new > context was much too high to do on each request. In fact, that's the > bulk of creating a new node process.
Yeah, that sounds about right. But at some point, if and when this changes, it'd be cool to be in a position to be able to slide this in completely transparently.
On Mon, Oct 3, 2011 at 8:39 PM, kowsik <kow...@gmail.com> wrote: > You might want to take a look at background pages in chrome (available > to chrome extensions):
> This allows you to have an isolate process running some code and > there's a socket.io kinda of connect/notify/read/write interface > from/to the parent process.
Badass. This may be just the kind of thing to use as a model...
The other optimization I forgot to mention -- that which is immutable is also, obviously, safe to share between isolates contexts. Which is nice.
The Fiibonacci sequence is obviously contrived, the recursive version
just more reductio ad absurdum. It is trivial to point out that a
queued event model, aka "asynchronous" i/o, will do poorly if multiple
compute intensive tasks are required simultaneously. That's why
software multi-tasking and true hardware multi-processing emerged
fairly early in operating system theory and practice to leverage the
power of the hardware interrupt into higher level queued notions such
as "processes" and "threads". The asynchronous model actually casts
back to the time before those system emerged and it still has an
interesting, if a somewhat niched, role. Everything old is new
again...
But there is a darker side that should not be dismissed so easily.
This asynchronous model is also known as "cooperative mufti-tasking"
for those old enough to remember Windows 3.x (never mind early OS/
360). This architecture is exquisitely sensitive to errors. If the
current activity ("call back''") is hung, the entire system is hung.
If it crashes or wanders off to oblivion, so does the entire system.
Node systems in production, when the time comes for real production,
will tend to be relatively fragile by nature.
I would also agree that the thought of Node programming for
"beginners" is kinda of amazing. The average person who still uses
<table> elements in browser programming is likely to be a bit
overwhelmed by the Scheme heritage of Node programming (mind you Node
is not the only use of Javascript heavy on functions and closures as
many of the modern packages do it).
OTH, having high level controls that spread Node programs out over
multiple tasks/threads/processes, or ultimately building that into
Node strikes me as perfectly reasonable use of modern hardware and
operating system, even VMs. That criticism of Node was totally bogus.
Another note in Node's favour, it is amazing light weight. On Windows
the executable is less than 5mb. Even assuming the vast bulk of that
is V-8 engine code, the sucker is light weight, and yes, fast. Nothing
else can create more light weight network communicating processes,
including the currently predominate use for web servers, quicker or
with less intensive overhead. Therein lies a potential paradigm shift
in network/cloud programming. Web servers may be the meat and potatoes
now but we may come to look back at that as quaint as the web itself
being seen primarily as a hypertexted collection of static content.
@Jorge, how valuable are these tasks if they can't doing anything but
vanilla Javascript -- i.e. there's no require() function? If that's
not valuable, then the way to go is building on child_process.fork()
If my familiarity with the V8 api was greater, I'd be prototyping
this, but I believe the C++ module would have to:
lock(?) task argument
queue task with eio_custom
in task:
retrieve a cached V8 isolate, or construct one
create new V8 context
create module object
create module.argument by copying locked argument
create module.result object (.exports?)
read, compile, run script
script modifies module.result
lock(?) module.result
destroy the context
place isolate in cache
set timer to destruct isolate instance (if necessary)
after task:
create callback result by copying locked result
perform callback
streaming results out of the task would be a future todo
On Oct 3, 4:00 pm, Jorge <jo...@jorgechamorro.com> wrote:
> If you do this with a v8 isolate, it could be made safe. *However*, > afaik the last time this was investigated, the cost of creating a new > context was much too high to do on each request. In fact, that's the > bulk of creating a new node process.
> On Mon, Oct 3, 2011 at 16:36, Isaac Schlueter <i...@izs.me> wrote: >> Dean, even if you were to serialize the object, you also have to watch >> out for functional side-effects.
>> var x = 100 >> function foo () { x = 10000 } >> evalInBackground(foo, cb)
>> while (x === 100) { >> console.log("ok") >> } >> throw new Error("SPOOKY!!")
>> Let's please not ruin node with parallel access to javascript objects.
>> On Mon, Oct 3, 2011 at 16:21, Dean Landolt <d...@deanlandolt.com> wrote:
>>> On Mon, Oct 3, 2011 at 7:00 PM, Jorge <jo...@jorgechamorro.com> wrote:
>>>> On 03/10/2011, at 23:12, Ryan Dahl wrote: >>>>> On Mon, Oct 3, 2011 at 2:00 PM, Liam <networkimp...@gmail.com> wrote: >>>>>> @Ry can you give a summary of the expected mechanism and API?
>>>>> It will be a supervisor process with worker processes. Ideally it will >>>>> be transparent:
>>>> The API I'd love to have to run cpu-bound tasks (a task = a javascript >>>> function + a javascript data object) in the background:
>>>> execInBackground(fibonacci, 50, cb); >>>> function cb (err, result) { /* called when done */ }
>>>> Is simply identical to that of node's background IO tasks.
>>> This is nice. Of course, on top of this it would be really nice to allow >>> the passing of specially-created objects that get poison-pilled after >>> passing (IIRC you suggested this months (years?) ago). That would allow the >>> single-process v8-isolates optimization case without exposing shared state, >>> but would still be a perfectly nice API for multi-process or even >>> multi-machine concurrency. >>> The only stipulation is that this special shared object is restricted or >>> trimmed to look identical to an otherwise-(de)serialized object -- meaning >>> no functions (or functions that are stringified and eval'd in the background >>> context), no natives, and nothing at all that isn't serializable. >>> This would annihilate the whole parallelism gambit once and for all, swiftly >>> and safely. Or we can keep using multi-process concurrency...that seems to >>> work pretty well too :)
> I would also agree that the thought of Node programming for > "beginners" is kinda of amazing. The average person who still uses
I think there's a confusion about what "less-than-expert" means. Being less than expert doesn't necessarily mean "newbie". People with a few years of experience can still be less-than-expert, but at the same time be familiar with concepts needed to write good enough apps in Node, that would do better than if the same person would write it in other languages. So equating the statement on Node homepage with "anyone could write scalable apps using Node" is not exactly fair. There are many, many nuances between the "100% idiot" and "less-than-expert".
-- Branko Vukelic bra...@brankovukelic.com bra...@herdhound.com
On Tue, Oct 4, 2011 at 1:31 AM, Liam <networkimp...@gmail.com> wrote: > @Jorge, how valuable are these tasks if they can't doing anything but > vanilla Javascript -- i.e. there's no require() function?
Who said that? It could have a require function, but it (obviously) wouldn't be able to share the module cache.
On Oct 4, 3:53 am, Dean Landolt <d...@deanlandolt.com> wrote:
> On Tue, Oct 4, 2011 at 1:31 AM, Liam <networkimp...@gmail.com> wrote:
> > @Jorge, how valuable are these tasks if they can't doing anything but
> > vanilla Javascript -- i.e. there's no require() function?
> Who said that? It could have a require function, but it (obviously) wouldn't
> be able to share the module cache.
Well, er... I assumed Node-core isn't thread-safe :-)
On 4 October 2011 06:07, Rob <rjduw...@gmail.com> wrote:
> This asynchronous model is also known as "cooperative mufti-tasking" > for those old enough to remember Windows 3.x (never mind early OS/ > 360). This architecture is exquisitely sensitive to errors. If the > current activity ("call back''") is hung, the entire system is hung.
On Tue, Oct 4, 2011 at 7:16 AM, Liam <networkimp...@gmail.com> wrote: > On Oct 4, 3:53 am, Dean Landolt <d...@deanlandolt.com> wrote: > > On Tue, Oct 4, 2011 at 1:31 AM, Liam <networkimp...@gmail.com> wrote: > > > @Jorge, how valuable are these tasks if they can't doing anything but > > > vanilla Javascript -- i.e. there's no require() function?
> > Who said that? It could have a require function, but it (obviously) > wouldn't > > be able to share the module cache.
> Well, er... I assumed Node-core isn't thread-safe :-)
Sure, any deficiencies there would have to be patched up before this kind of thing could be implemented on top of isolates. In the meantime it would obviously always use child processes. The point is this could be completely encapsulated, just another optimization that could happen that users need not concern themselves with.
On a single event loop this is true, however node exists as an event loop inside of a process. As such it can take advantage of the scheduler not making Node block the entire computer. While people seem to think that threads can alleviate this problem on the conceptual level, having a wait looped consumer thread will act in the same manner. Node.js is an event driven system that queues messages rather than allows a single callback to accidentally block the main loop (unless you do some infinite looping, blah blah), we can agree to that. An interesting side effect of encouraging out of band events is that we tend not to hang the main loop like the good old days with some io deadlock.
The larger problem is that people don't use modern debugging when it does lock and assume the process is just magical. Either way, when one thread is hung having the entire process wait on it is generally a reasonable idea since that thread may actually __do something__ related to your program. Since we do not have easily guaranteed threadlocal/callbackchainlocal memory generally the idea is going to be that any shared state is going to mean you want to restart the process (not all functions / events actually share state though and this is digressing).
However, if we architect our system to be made up of multiple smaller tools (processes) as generally is the case outside of windows and/or games, we can improve OS scheduling by guaranteeing native threading/preemption, keep our sanity by not sharing memory between purposes (semaphores for mutex sections are no longer a concern, though for internal memory resources may still exist), and even get the nice ability of having an external interface (yay for being able to talk to an application without needing to go compile up a binding! great for debugging :) ). For bonus points, have a debugger only break on one part of your program and see how the others respond.
Node has problems, I would argue as many as anything else. Programmers who think that these problems do not exist, and/or are not able to figure out the need to architect their software differently for different environments are not thinking hard enough. For every problem I have found, there is a solution generally in how I design a program (not a process). Node is hard, node is not a panacea, but node is a collection of many different ideas into a very precise and competitive tool that allows rapid development and performance. Don't forget this lil puppy is only 2 years old (and not even 1.0!).
We have had almost 2 decades with threaded preemption reigning inside of a process that is already being preempted, like everything else we are just seeing the tide go back and forth. It will go back and forth again.
> On Tue, Oct 4, 2011 at 7:16 AM, Liam <networkimp...@gmail.com> wrote: > On Oct 4, 3:53 am, Dean Landolt <d...@deanlandolt.com> wrote: > > On Tue, Oct 4, 2011 at 1:31 AM, Liam <networkimp...@gmail.com> wrote: > > > @Jorge, how valuable are these tasks if they can't doing anything but > > > vanilla Javascript -- i.e. there's no require() function?
> > Who said that? It could have a require function, but it (obviously) wouldn't > > be able to share the module cache.
> Well, er... I assumed Node-core isn't thread-safe :-)
> Sure, any deficiencies there would have to be patched up before this kind of thing could be implemented on top of isolates. In the meantime it would obviously always use child processes. The point is this could be completely encapsulated, just another optimization that could happen that users need not concern themselves with.
Fork an entire process to have a much more robust environment, at a
fairly high price. It's state includes all the process resource
protection mechanism of the scheduler: memory isolation, CPU
isolation, separate file management. The heavy weight process
historically stems from timesharing systems to protect one user from
anther's actions and faults (literally, as in core). Threads are light
weight processes that ride on top of OS processes and do not protect
each other from memory interference or corrupt i/o pool. But the price
for that protection is relatively high, which is why threading made a
major comeback in the 90s to serve the high concurrency requirements
of web and database servers. Ugly programming traded for efficiency.
Multi-threading may tolerate some misbehavior, like failing to halt on
a particular thread, that would be deadly to Node. I believe the
cancer article made a passing reference to CGI in comparison to the
threaded processing model. I also believe that Node still carries a
work in progress warning and caveat about using for major production.
There never is a clear dividing line.
On Oct 3, 9:33 pm, Mark Hahn <m...@boutiquing.com> wrote:
For those who sweat the limits of cooperative multiprocessing there is
interesting academic work out there.
Timed Games, a variant of Priced Time Automata, have been used (see
09/2011 CACM). I found this in Wenming Li's dissertation "Group EFF -
New Approach and and An Efficient Non-Preemptive Algorithm for Soft
Real-Time Systems" using Google search: "Real-time systems are also
distinguished based on their implementation. In preemptive systems,
tasks may be preempted by higher priority tasks, while non-preemptive
systems do not permit preemption. It is easier to design preemptive
scheduling algorithms for real-time systems. It is our contention,
however, that non-preemptive scheduling is more efficient,
particularly for soft real-time applications and applications designed
for multithreaded systems, than the preemptive approach since the non-
preemptive model reduces the overhead needed for switching among tasks
or threads."
Most web apps are soft real-time systems. It also raises consideration
of Node in embedded network oriented systems, albeit not "light
weight" ones but rather more of the embedded Linux class which
includes a great many consumer devices including the most popular
class of smart phones. Unlikely most practicing devs will go deep into
this stuff but for those who want to push the limits there is room to
take the academic material and use it in practical applications. And
Node does provide an incentive to try, perhaps even internally or as
middle ware.
On Oct 3, 3:02 pm, Ryan Dahl <r...@tinyclouds.org> wrote:
> > Doesn't this give more flexibility, e.g. the server process can
> > maintain a cache and hit it before task queuing
> > modify the task data stream before relaying it
> > queue arbitrary modules to workers
> We will also have a low-level API for managing the workers of course
> but not as you imagine it. The 99% use-case is symmetric load
> balancing. People will still complain about not being able to preempt
> work being done for single connections but this is not easily
> addressed with Node - nor is it that important - cooperative
> multitasking is perfectly valid within a single process.
It seems he's now trying a different approach to make his stupid point. This is no longer a Node vs. Other languages, this is Event-driven vs. Threading. I would recommend everyone to ignore..
> It seems he's now trying a different approach to make his stupid point. > This is no longer a Node vs. Other languages, this is Event-driven vs. > Threading. > I would recommend everyone to ignore..
> --- > Diogo R.
> On Sun, 2 Oct 2011 14:42:37 -0700, Tauren Mills wrote:
> It seems he's now trying a different approach to make his stupid point. > This is no longer a Node vs. Other languages, this is Event-driven vs. > Threading. > I would recommend everyone to ignore..
Thanks for the link -- the guy's effing hilarious. Not sure why you think we should ignore -- did you find any logical faults (aside from the obviously rhetorical aspects)? If so, where?
Given that the times are measured in milliseconds, we can define and . Ok I stop there. This line is so wrong. I think he should review what is a thread and what is concurency : thread != running at the same time.
On Wed, Oct 5, 2011 at 21:09, Thomas Love <toml...@gmail.com> wrote: > On 5 October 2011 20:49, Diogo Resende <drese...@thinkdigital.pt> wrote: > > Ted's response:
> > It seems he's now trying a different approach to make his stupid point. > > This is no longer a Node vs. Other languages, this is Event-driven vs. > > Threading. > > I would recommend everyone to ignore..
> Thanks for the link -- the guy's effing hilarious. Not sure why you > think we should ignore -- did you find any logical faults (aside from > the obviously rhetorical aspects)? If so, where?
Hu... In reality threads = running at the same time on a multicore architecture. This *is* what threads are here for...
I hope you wont respond him with such arguments cause you may make our case worse to him :p Le 5 oct. 2011 21:48, "Naouak" <tard...@gmail.com> a écrit :
> Given that the times are measured in milliseconds, we can define and . > Ok I stop there. This line is so wrong. I think he should review what is a > thread and what is concurency : thread != running at the same time.
>> > It seems he's now trying a different approach to make his stupid point. >> > This is no longer a Node vs. Other languages, this is Event-driven vs. >> > Threading. >> > I would recommend everyone to ignore..
>> Thanks for the link -- the guy's effing hilarious. Not sure why you >> think we should ignore -- did you find any logical faults (aside from >> the obviously rhetorical aspects)? If so, where?