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.
> >>
> >>
>
>

Reply via email to