On Sat, Nov 16, 2013 at 8:14 PM, João Henriques <[email protected]> wrote: > > I'm building a module to be used on a server application that does some > heavy work on the background, and the best design I thought for > not blocking node's main event loop was creating a new thread and a new > event loop with libuv, keeping it referenced in the background until someone > needs it, > > > /************************************************** > * Module initialization > **************************************************/ > > uv_loop_t *second_threaded_loop; > > void create_loop(void *) > { > uv_run(second_threaded_loop, UV_RUN_DEFAULT); > } > > void init (Handle<Object> target) > { > NanScope(); > > uv_thread_t thread_loop; > uv_async_t async; > > second_threaded_loop = uv_loop_new(); > > // Reference the second loop so it keeps on idle > uv_async_init(second_threaded_loop, &async, NULL); > > uv_thread_create(&thread_loop, create_loop, NULL); > > // .... > } > > /************************************************** > * Then, a random function running on > * the main loop does > **************************************************/ > > NAN_METHOD(Foo::doHeavyOperation) > { > // ... > > uv_work_t* req = new uv_work_t; > > random_context_struct *ctx = new random_context_struct; > // ctx->handle is a Handle<Object> > ctx->handle = Persistent<Object>::New(args.This()); > > req->data = /* random context */; > > uv_queue_work(second_threaded_loop, req, startHeavyOpeation, EmitMessage); > > // .... > > NanReturnUndefined(); > } > > /************************************************** > * After startHeavyOpeation ends, Emit Message is called > * Where it supossly should emit an event > * informing that the task finished > **************************************************/ > > void EmitMessage(uv_work_t *req, int status) > { > random_context_struct *ctx = (random_context_struct*)req->data; > > Local<Value> argv[1] = { NanSymbol("parsed") }; > > TryCatch tc; > > MakeCallback(ctx->handle, "done", 1, argv); > > if (tc.HasCaught()) > printf("Error occured"); > } > > > > Now, if I run this task on the main event loop the operation succeeds and > the event is triggered, > but in the second loop the application prematurely ends, without any > explicit error being thrown, or being caught. > > A second loop to me seems the best idea, because blocking in the main event > loop is not be acceptable as the server > will be receiving new connections from other users. Creating a thread for > each request would not be acceptable too, > as the overhead would be unmanageable. A second event loop on a child thread > seems a reasonably approach but emitting seems not to be possible.
V8 as it's used in node.js is not thread safe. You cannot call V8 functions from another thread.* Do you need a separate event loop? The uv_queue_work() function runs the work callback in a separate thread and invokes the done callback on the original thread (i.e. the main thread.) * V8 can be entered from different threads only if you use appropriate mutual exclusion with v8::Locker and v8::Unlocker objects. That won't help in your case because your worker thread would block the main thread if it somehow acquired the Locker. -- -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en --- You received this message because you are subscribed to the Google Groups "nodejs" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
