On Tue, May 29, 2012 at 5:22 PM, Jorge <jo...@jorgechamorro.com> wrote:
> FYI: setImmediate === nextTick and identical to a setTimeout(f,0) without > the clamping. > > Not at all. In the current libuv event loop there are 4 parts to a cycle (libuv guys correct me if I get this wrong) nextTickGeneration - nextTickGeneration - TimerEvents - IOEvents So if I register a nextTick in a timer callback, the I/O events will get executed first. If I execute one in an I/O event, it's generation will happen next. If I set another nextTick in that first generation, it will get executed right away, but if I set yet another in that second generation, it will get delayed till after both timers and I/O events. I can't think of a single use case this is ideal for. It's a hack and a compromise. We can do better by having two APIs that do what they intend to do. The proposal for nextTick would look like AnyTimerOrIOEvent - flushAllNextTicks Thus any nextTick I schedule will get run before the next real event. This includes all nextTicks registered from other nextTicks. setTimeout simply starts a timer and when it expires it gets put in the event queue as a timer event. setImmediate would put the function in the queue with the rest of the real events, but at the end. nextTick != setTimeout 0 != setImmediate > On May 29, 2012, at 10:45 PM, Isaac Schlueter wrote: > > > Computationally expensive stuff should be done in a child process, or > > a uv_work_t thread in an addon. nextTick is a bad fit for this. > > setTimeout(fn, 0) is not quite as bad, but it is slower. > > > > We can look into adding a setImmediate function for 0.9 that matches > > the semantics of the web browser. The intent of setImmediate is to be > > used for cases like this, and it should be pretty easy to implement. > > > > On Tue, May 29, 2012 at 1:31 PM, Mikeal Rogers <mikeal.rog...@gmail.com> > wrote: > >> I have never seen nextTick recommended for breaking up computationally > >> expensive tasks, this is what cluster and child_process are for. > >> > >> Also, setTimeout(cb,0) is very efficient in node and does not suffer the > >> penalties we are familiar with from the browser. It's actually a better > fit > >> for this use case than nextTick(). > >> > >> -Mikeal > >> > >> > >> On May 29, 2012, at May 29, 201212:23 PM, Bruno Jouhier wrote: > >> > >> +1 > >> > >> nextTick is the efficient way to yield to another "thread of processing" > >> (thread between quotes of course) when performing an expensive > computation. > >> So it is the antidote to starvation and thus a very useful call. > >> > >> If you change its behavior, you should at least provide a replacement > call > >> which will be at least as efficient (unlike setTimeout(cb, 0)). And > then why > >> not keep nextTick as is and introduce another call with a different name > >> (like afterTick as someone suggested) if you really need one. > >> > >> > >> On Tuesday, May 29, 2012 2:43:20 AM UTC+2, phidelta wrote: > >>> > >>> I think that the current semantics have value. I use nextTick when I > >>> want to ensure that io can happen between the invocation and the > >>> ticked call. As well as to work with a new call stack. > >>> > >>> For example when I emit an event whose lister also emits an event and > >>> so on, I create a potentially long chain of stuff that can happen > >>> within a tick. So when I emit from within a listener I usually > >>> nextTick the emit to allow io in between. > >>> > >>> So if you change nextTick to really mean "at the end of this tick", at > >>> least we will want a function like reallyNextTick that keeps the > >>> current behavior. Of course I would need to do a search replace over a > >>> lot of code, but I could live with that. > >>> > >>> > >>> On May 26, 7:50 pm, Isaac Schlueter <i...@izs.me> wrote: > >>>> How would you feel about changing the semantics of process.nextTick > >>>> such that the nextTick queue is *always* cleared after every v8 > >>>> invocation, guaranteeing that a nextTick occurs before any IO can > >>>> happen? > >>>> > >>>> This would imply that you can starve the event loop by doing nextTick. > >>>> So, for example, the timeout would never fire in this code: > >>>> > >>>> setTimeout(function () { > >>>> console.log('timeout')}) > >>>> > >>>> process.nextTick(function f () { > >>>> process.nextTick(f) > >>>> > >>>> }) > >>>> > >>>> Reasoning: > >>>> > >>>> We have some cases in node where we use a nextTick to give the user a > >>>> chance to add event handlers before taking some action. However, > >>>> because we do not execute nextTick immediately (since that would > >>>> starve the event loop) you have very rare situations where IO can > >>>> happen in that window. > >>>> > >>>> Also, the steps that we go through to prevent nextTick starvation, and > >>>> yet try to always have nextTick be as fast as possible, results in > >>>> unnecessarily convoluted logic. > >>>> > >>>> This isn't going to change for v0.8, but if no one has a use-case > >>>> where it's known to break, we can try it early in v0.9. > >> > >> > >