For the record, I know I have code that will break under this change, but I
didn't bother linking to it because it's so trivial for me to fix.  I do,
however have code that is broken under the current implementation that I
can't fix.

On Tue, May 29, 2012 at 5:05 PM, Mikeal Rogers <[email protected]>wrote:

>
>
>
>
> On May 29, 2012, at May 29, 20122:42 PM, Marco Rogers wrote:
>
> Mikeal, I understand your frustration, but that's not how I read the
> history. nextTick was *intended* for this use case. But it sounds like it
> was the wrong solution. nextTick was implemented as "yield to the event
> loop for whatever else may happen". It's always been pretty clear to me
> that some early data events may get through this gap. The fact that you
> didn't actually want this doesn't mean there's a bug in nextTick. It means
> you screwed up. It means there's a bug in node because you took a valid
> nextTick implementation and used it for the wrong thing. It means you need
> another solution to solve your original problem. I thought that's why we
> started talking about setImmediate.
>
>
> The problem with this characterization of the API's history is that it's
> actually not distinguishable from setTimeout(fn, 0) except in
> implementation. As described, they are for quite literally the same thing
> although one of them is a little better at it because of an implementation
> detail. If this characterization is true (i don't believe it is) then we
> should re-purpose or remove nextTick() and improve the performance of
> setTimeout(fn,0). I'm not suggesting that is what we do, but it's the
> logical conclusion to this characterization.
>
>
> As for whether it's valid to use nextTick or setTimeout or whatever to
> break up computation, that's not your call.
>
>
> Are you saying that core can't state the intention of an API? That's
> insane.
>
> Core is free to change the implementation details and semantics of an API
> at any time, and has on many occasions. This is always done with the
> intention of making it *better*. In order to characterize what is "better"
> the API must have a purpose and that has always been dictated by core (Ryan
> and then Isaac).
>
> People have been doing this in javascript for ages. Node can provide a
> "better" solution, but crippling current valid solutions is not really
> acceptable for a platform that claims to want to be simple and consistent
> and just javascript. IMO, cluster/child_process is for scaling request
> throughput for servers. It has little to do with breaking up computation
> though it can be used for that. This is not my impression, but one I got
> from you and Isaac and other node people when it was being designed. It
> feels like what's happening now, is that you're changing that tune so you
> can push this change forward. But whatever.
>
> You know if you're going to get upset when you receive honest,
> constructive feedback that you requested from actual users of your
> software, you should probably consider just not asking.
>
>
> This is what happened.
>
> Isaac said "this change makes sense, does anyone have code that will
> break". To date, *nobody* has shown real world code that will break or
> linked to any projects that will break. We *know* of code that breaks in
> production under load due to the current semantics, that's why the change
> was proposed in the first place.
>
> Instead, we got a lot of comments about names and about theoretical
> breakage in code without anyone noting running code that actually breaks or
> is even valid. And now we're being taken down the rabbit hole of "I can't
> use this for something it wasn't designed for".
>
> The way in which people are providing feedback to this proposed changed is
> unproductive because they do not recognize the reality of the current
> semantics.
> 1) that we cannot remove nextTick() and it is heavily relied on.
> 2) that much of the code that *currently* relies on nextTick() breaks
> under heavy load because of the current implementation.
>
> All of this feedback is "me too". It's statements of opinion without
> reference the problem that must be solved.
>
> The intention of feedback should be to change the minds of those that
> proposed the change, not to prove that your'e right under your terms.
>
> If it seems as though the responses from Isaac are callus it is because it
> is not his job to convince you that this is a real problem, it's your job
> to convince him that your solution benefits everyone better and still
> solves the problem at hand. That is not happening.
>
>
> :Marco
>
> On Tuesday, May 29, 2012 2:18:35 PM UTC-7, Mikeal Rogers wrote:
>>
>> The job of core is to provide the best API possible to accomplish several
>> use cases.
>>
>> When core provides an API to handle that use case and people decide to
>> ignore it, do something inferior with an API that was not designed for that
>> use case, and then protest altering the this API to better match the use
>> case it was actually intended for I don't have the words to describe how
>> frustrating it is.
>>
>> This is not a matter of "opinion". These APIs were created and documented
>> for a *purpose*. It's great when people find more than one purpose for a
>> given API but when their use case is actually covered by another interface
>> that was specifically designed to handle it we have to ignore that input on
>> the other API.
>>
>> The "change" we're talking about makes nextTick() behave the way most
>> people presume it works and for the use case it was designed for (adding
>> handlers after the current stack is complete but before IO gets processes)
>> the current behavior is a bug. The suggestion that we should let it remain
>> because the current behavior (which is broken for the desired use case)
>> fills another one it was not designed for and for which we have other
>> specifically designed API is ludicrous.
>>
>> -Mikeal
>>
>> On May 29, 2012, at May 29, 20122:08 PM, Marco Rogers wrote:
>>
>> Translation: "You're doing something reasonable. But we don't think you
>> should do it that way, so we're going to shoot you in the foot and then
>> blame you for it." I'm on board with this plan. <- sarcasm
>>
>> Seriously though. Can we at least hear what other options y'all have
>> considered for fixing the original problem? Is there a test case that
>> reproduces it that we can examine? I don't want to mess with nextTick
>> because it works as designed. But if there's no other solution to the
>> problem, I could get behind introducing setImmediate. But with that it
>> seems we're signing up for a whole new round of educating devs about what
>> to do in order to not miss their data events. Sure it seems easy in theory
>> (change nextTick to setImmediate), but in practice it will create a lot of
>> confusion and ambiguity about what just changed.
>>
>> :Marco
>>
>> PS - Sorry I missed the message about moving discussion to the github
>> ticket :-/
>>
>>
>> On Tue, May 29, 2012 at 1:45 PM, Isaac Schlueter <[email protected]> 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 <[email protected]>
>>> 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 <[email protected]> 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.
>>> >
>>> >
>>>
>>
>>
>>
>> --
>> Marco Rogers
>> [email protected] | https://twitter.com/polotek
>>
>> Life is ten percent what happens to you and ninety percent how you
>> respond to it.
>> - Lou Holtz
>>
>>
>>
>

Reply via email to