So, after reading a little about non-blocking code, does...
response.write(thisWillTakeALongTime());
...block the process? If so, do we need to pass the response into pretty much every slow function call we make, and have that function handle the response?
Thanks for helping to clarify!
Yes, it will block the event loop. And passing the response object into the slow function won't help, no matter where you call the slow function you will be blocking the event loop.
As to how to fix it, we will need more information.
What is making your slow function slow? Are you performing large calculations?
Are you doing sync versions of file/database calls?
It depends on what you mean by process. The web server has already finished serving the page at this point you js will execute however the request is synchronous so the javascript will continue to devote its in your function until it returns regardless even if take years. (hopefully by this point the browser will detect your script is taking too long and give you the opportunity to kill it). Even still you suffer the embarrassment of the user having to kill your javascript functionality and them not being able to use the page.
So how do you solve the problem. The time when this gets particular important is when your js is making the problem because at the point a whole host of things of things can go wrong. Imagine that your user is on the other side of the earth. the network latency could make your js painfully slow. when using ajax its preferable to use Asynchronous requests which get around this. I personally recommend using jquery as it makes async ajax calls really easy and the documentation on the side is quite straight forward. The other thing I recommend is making the return output small. It made be better to return json output and build the needed html from that.
Related
I am getting my hands on node.js and its NPM valuable service. I tried installing this package and, by reading the documentation, it says that to generate a short id, this code needed:
shortId.generate();
that means that to use the ID, I would need something like this.
var id = shortId.generate();
res.end(id);
I hope I am not making a mistake here, but I thought the correct way to do things asynchronously was to use callbacks? And do something like:
shortId.generate(function(val){
res.end(val);
});
Can anyone please help me clarifying this problem? Thanks in advance.
Yes, the code in your example is synchronous. Node.JS has strength from it's asynchronous code, but not absolutely everything is asynchronous.
Mostly, the asynchronous code is usful for blocking IO.
As you could see from that module source code it does not perform any i/o at all while generating the id.
Callbacks in node are used when i/o takes place, so the program does not wait until the operation is performed, giving a function to be called when the i/o finishes.
The shortId.generate function is blocking, so it doesn't provide a callback for the result.
This makes sense in this case, because the unique ID generation isn't a heavy operation. If it was, you could adjust the code to enable a callback methodology.
Callbacks are definitely common though! For example, your web application wants to save an object to the server. You could be non-blocking here by adding a callback to the save function, so you could return a response sooner than the object has been written to disk/cache.
I recommend reading art of node for some great examples of blocking vs. non-blocking. :)
I know the title sounds like a dupe of a dozen other questions, and it may well be. However, I've read those dozen questions, and Googled around for awhile, and found nothing that answers these questions to my satisfaction.
This might be because nobody has answered it properly, in which case you should vote me up.
This might be because I'm dumb and didn't understand the other answers (much more likely), in which case you should vote me down.
Context:
I know that IO operations in Node.js are detected and made to run asynchronously by default. My question is about non-IO operations that still might block/run for a long time.
Say I have a function blockingfunction with a for loop that does addition or whatnot (pure CPU cycles, no IO), and a lot of it. It takes a minute or more to run.
Say I want this function to run whenever someone makes a certain request to my server.
Question:
Obviously, if I explicitly invoke this loop at the outer level in my code, everything will block until it completes.
Most suggestions I've read suggest pushing it off into the future by starting all of my other handlers/servers etc. first, and deferring invocation of the function via process.nextTick or setTimeout(blockingfunction, 0).
But won't blockingfunction1 then just block on the next spin around the execution loop? I may be wrong, but it seems like doing that would start all of my other stuff without blocking the app, but then the first time someone made the request that results in blockingfunction being called, everything would block for as long as it took to complete.
Does putting blockingfunction inside a setTimeout or process.nextTick call somehow make it coexist with future operations without blocking them?
If not, is there a way to make blockingfunction do that without rewriting it?
How do others handle this problem? A lot of the answers I've seen are to the tune of "just trust your CPU-intensive things to be fast, they will be", but this doesn't satisfy.
Absent threading (where I can be guaranteed that the execution of blockingfunction will be interleaved with the execution of whatever else is going on), should I re-write CPU-intensive/time consuming loops to use process.nextTick to perform a fixed, guaranteed-fast number of iterations per tick?
Yes, you are correct. If you defer your function until the next tick, it will just block in that tick rather than the current one.
Unfortunately, there is no magic here that solves this for you. While it is possible to fire up that function in another process, it might not be worth the hassle, depending on what you're doing.
I recommend re-writing your function in such a way that work happens for a bit, and then continues on the next tick. Node ticks are very efficient... you could call them every iteration of a decent sized loop if needed, without a whole ton of overhead. Of course, you would have to profile it in your code to see what the impact is.
Yes, a blocking function will keep blocking even if you run it process.nextTick.
Some options:
If it truly takes a while, then perhaps it should be spun out to a queue where you can have a dedicated worker process handle it.
1a. Node.js has a child-process flavor specifically for forking other node.js files with a built in communication channel. So e.g. you can create one (or several) thread that handles these requests in order, then responds and hits the callback. See: http://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options
You can break up the blockingFunction into chunks that run in a loop. Have it call every X iterations with process.nextTick to make way for other events to be handled.
I'm quite sure with this, but just to have your opinion:
Is it somehow possible to perform operations in the background with Javascript if web workers are not available?
Is there perhaps a way to "misuse" the asynchronous setTimeout() function or some other mechanisms?
My goal is to read things from the localStorage, do a few transformations and send them via Ajax.
Thanks.
You can't run operation in background, but you can split it in small chunks, and run each next part with setTimeout. As result browser will have time to render changes and will be responsive to normal actions, while your long process will be executed as well
function iteration(){
do_some_small_amount_of_work();
if (!not_finished)
scheduler.setTimeout(iteration, 1);
}
There is not really multithreading in Javascript, but you can run code asynchronously using setTimeout(code, 0). This queues the function for execution.
Without using web workers, what you've suggested (using setTimeout) is the only way to do it, and of course it's not really "background" at all at that point. Note that you'll need to keep the processing quite short each time you fire the "background" code, because it's not really background code at all; while your code is running, the page will be fairly unresponsive (the degree to which it's unresponsive will vary by browser, but certainly any JavaScript code on the page will have to wait for your function call to finish).
No, there is no way to do anything in the background in Javascript. It's strictly single threaded.
You can use setTimeout or setInterval to do the work in the foreground, but just a small part of it each time. That way the interface is still reasonably responsive as it handles events between your bursts of work.
I need to make asynchronous HTTP call to my server in order to receive XML response.
After I get the response I will call a [previously specified] function if it is success or some other function if it's an error.
So what I thought about in the first place was coroutines. Unfortunately, after I make the http.get call I cannot yield, as it will wait for the whole thing to finish. I know I can use separate functions to read the response, however I have to wait at least for the first bytes of data in order for this function to be triggered which would allow me to yield. Anyway, for what I wan to do using coroutines doesn't look like the way to go.
Then I've tried calling a C function from lua, creating separate thread to get the XML and then call a function in Lua, however this doesn't work because of lua_state changing after a new thread is created. Before the thread is created I can see 3 parameters on the stack, and after creation of the new thread [I am passing lua_State as the argument] it has only one. Anyway, from what I understand lua_State will be closed once the original cfunction call is finished, so I won't be able to call back.
Since I'm just starting with lua and I'm even less familiar with lua to c bindings I can only hope I'm making some stupid mistakes and it will be easy to solve. For now however I'm stuck with no idea on how to progress further.
The story behind this issue:
I'm porting my game from Cocos2D objective C framework to Cocos2d-X C++ framework. I want to use Lua bindings as I think I will fail to port it to C++. Anyway I want to do it in Lua.
So I've got a scene where someone accesses a list of inventory they have in the game. If the response is immediate they will basically see a window opened with list of inventory. However, if it takes a tad bit longer to get the data [connection issues, sever overload... whatever] screen will fade out and some animation indicating data transfer will be shown on screen. At least this is how it works on the objc version of the game and I want the same thing.
Is there something I have missed during my research, is it possible to do it?
BTW I have seen Lua socket asynchronous calls and it doesn't help me because it still waits for the beginning of the transfer before it will start another one.
Something like Luvit ?
Luvit is an attempt to do something crazy by taking nodeJS's awesome
architecture and dependencies and seeing how it fits in the Lua
language.
This project is still under heavy development, but it's showing
promise. In initial benchmarking with a hello world server, this is
between 2 and 4 times faster than nodeJS.
I was able to do it using https://github.com/Neopallium/lua-llthreads
This seems to work fine on both iOS and Android platforms.
Redis is very fast. For most part on my machine it is as fast as say native Javascript statements or function calls in node.js. It is easy/painless to write regular Javascript code in node.js because no callbacks are needed. I don't see why it should not be that easy to get/set key/value data in Redis using node.js.
Assuming node.js and Redis are on the same machine, are there any npm libraries out there that allow interacting with Redis on node.js using blocking calls? I know this has to be a C/C++ library interfacing with V8.
I suppose you want to ensure all your redis insert operations have been performed. To achieve that, you can use the MULTI commands to insert keys or perform other operations.
The https://github.com/mranney/node_redis module queues up the commands pushed in multi object, and executes them accordingly.
That way you only require one callback, at the end of exec call.
This seems like a common bear-trap for developers who are trying to get used to Node's evented programming model.
What happens is this: you run into a situation where the async/callback pattern isn't a good fit, you figure what you need is some way of doing blocking code, you ask Google/StackExchange about blocking in Node, and all you get is admonishment on how bad blocking is.
They're right - blocking, ("wait for the result of this before doing anything else"), isn't something you should try to do in Node. But what I think is more helpful is to realize that 99.9% of the time, you're not really looking for a way to do blocking, you're just looking for a way to make your app, "wait for the result of this before going on to do that," which is not exactly the same thing.
Try looking into the idea of "flow control" in Node rather than "blocking" for some design patterns that could be a clearer fit for what you're trying to do. Here's a list of libraries to check out:
https://github.com/joyent/node/wiki/modules#wiki-async-flow
I'm new to Node too, but I'm really digging Async: https://github.com/caolan/async
Blocking code creates a MASSIVE bottleneck.
If you use blocking code your server will become INCREDIBLY slow.
Remember, node is single threaded. So any blocking code, will block node for every connected client.
Your own benchmarking shows it's fast enough for one client. Have you benchmarked it with a 1000 clients? If you try this you will see why blocking code is bad
Whilst Redis is quick it is not instantaneous ... this is why you must use a callback if you want to continue execution ensuring your values are there.
The only way I think you could (and am not suggesting you do) achieve this use a callback with a variable that is the predicate for leaving a timer.