jimhigson / oboe.js

A streaming approach to JSON. Oboe.js speeds up web applications by providing parsed objects before the response completes.
http://oboejs.com
Other
4.76k stars 208 forks source link

using alert() in an Oboe callback seems to mess up parsing? #53

Open balrog-kun opened 9 years ago

balrog-kun commented 9 years ago

I'm streaming more than one JSON file simultaneously with Oboe, in Firefox 28.0. One of the streams contains information about a UI event, so for now I'm trying to pop up an alert() box when that event is seen in the stream. But adding the alert() produces an exception in oboe: "Bad array\nLn: 1\nCol: 132\nChr: ["

Neither stream has a [ on column 132, confirmed with firefox's console.

When I add a console.log(c) at the beginning of clarinet.write() in oboe-browser.js, it looks like it's mixing the various streams up, but I could be wrong...

I'm not sure my interpretation of this problem is right, I'll dig in further is someone says that is impossible.

Full stack is emitError@https://rawgithub.com/jimhigson/oboe.js/master/dist/oboe-browser.js:628 write@https://rawgithub.com/jimhigson/oboe.js/master/dist/oboe-browser.js:802 applyEach@https://rawgithub.com/jimhigson/oboe.js/master/dist/oboe-browser.js:497 singleEventPubSub/<.emit@https://rawgithub.com/jimhigson/oboe.js/master/dist/oboe-browser.js:2005 handleProgress@https://rawgithub.com/jimhigson/oboe.js/master/dist/oboe-browser.js:1219

balrog-kun commented 9 years ago

Putting the same alert() in a setTimeout callback doesn't trigger this problem.

eyelidlessness commented 9 years ago

Without looking too closely at the internals of oboe, this isn't terribly surprising. The alert function is a blocking UI call, which prevents processing on the main (only) JS thread. I bet you'd see the same error/stack if the source data was interrupted at some point in the middle of a JSON array. Wrapping with setTimeout causes the alert call to wait until the main thread is unblocked, which presumably waits until oboe has finished processing the data stream.

If you're using alert for debugging, consider using console.log instead. If you're using alert for end-user notification, consider any number of libraries that would present your notification in-page rather than in a modal window.

balrog-kun commented 9 years ago

Agreed but that points at a race condition somewhere. A blocking call breaking parsing would be a bug in either the browser or Oboe. I'm not sure how exactly this can happen. If multiple streams are mixed up that must happen through the use of a global somewhere, but there's too much indirection around clarinet for me to be able to see anything in the code.

Also in Firefox the error pops up while the alert() window is still opened, so there's some concurrency but I don't know anything about it.

balrog-kun commented 9 years ago

I checked that it does not happen in Chromium, only Firefox.

However there is something wrong with using multiple streams in both browsers. I'm testing twitter- or gmail-like automatic reconnections with increasing intervals, and for one stream that works ok, but with two, one of the streams gets stuck in a state before the .start() callback. (no alert()s involved)

jimhigson commented 9 years ago

The alert thing is odd. Alerting is expected to hold up parsing (because it is blocking) but shouldn't actually cause anything to break (well I guess unless the alert is shown for so long that the http times out).

It sounds like a low priority bug since nobody should be using alert in production, but weird and possibly worth getting to the bottom of.

The multiple streams thing is interesting, and something I've not seen in my own usage with several http resources being fetched simulataneously. @balrog-kun - would it be possible to put together a small page demonstrating this issue? Then I'll be able to see what's going on.