Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ALL the Browsers #41

Merged
merged 17 commits into from
Jun 8, 2014
Merged

ALL the Browsers #41

merged 17 commits into from
Jun 8, 2014

Conversation

kriskowal
Copy link
Owner

This is continued work to reimplement ASAP with greater rigor, accounting for all browsers. This includes additional automation for verifying the tests pass in all browsers available on Saucelabs, automation we can extend to perform A/B tests, benchmarks, experiments, and coverage analysis.

These are snapshots of the Saucelabs test results matrix for browser windows, and then browser workers. Grey denotes that Workers themselves are unavailable and the tests were not run. The tests are those in test/asap-test.js. These were ported from mocha to a minimal test scaffold designed to integrated with both Node.js and Saucelabs just for this project.

  • Split implementations for browsers and Node.js.
    Now using Browserify-style module redirects.
  • Split implementations of asap and rawAsap.
    rawAsap is used by asap, is about twice as fast, but can be
    stalled by exceptions.
  • Support callable tasks, as a generalization of functions.
  • Use S3 and Mr/s to bundle and publish tests online, for development,
    continuous unit testing, and for ad hoc experiments.
    See scripts/publish-bundle.js.
  • Use Saucelabs to create browser compatibility matrices
    for development, continuous unit testing, and releases.
    See scripts/saucelabs.js
  • Reevaluate the use of various implementations based on data
    obtained experimentally about all relevant browsers, using
    Saucelabs.
  • Add ASAP Gauntlet benchmark draft.
  • Reimplement tests without a test framework.
  • Use a back up plan for engines that tend to forget timers (Firefox 8–18)
  • Address problem that Internet Explorer 10 web workers dequeue timers in LIFO order instead of FIFO.

Saucelabs Matrix

Saucelabs Matrix

-   Split implementations for browsers and Node.js.
    Now using Browserify-style module redirects.
-   Split implementations of asap and rawAsap.
    rawAsap is used by asap, is about twice as fast, but can be
    stalled by exceptions.
-   Support callable tasks, as a generalization of functions.
-   Use S3 and Mr/s to bundle and publish tests online, for development,
    continuous unit testing, and for ad hoc experiments.
    See `scripts/publish-bundle.js`.
-   Use Saucelabs to create browser compatibility matrices
    for development, continuous unit testing, and releases.
    See `scripts/saucelabs.js`
-   Reevaluate the use of various implementations based on data
    obtained experimentally about all relevant browsers, using
    Saucelabs.
-   Add ASAP Gauntlet benchmark draft.
-   Reimplement tests without a test framework.
Fix issue with postponing errors in Internet Explorer workers, since
setTimeout is not FIFO in that context.

Add Saucelabs automation for workers.

Add encrypted credentials for TravisCI and script for producing them.

Use JSHint for linting.
To reflect new development mode dependencies
Addressed problems that arose from running asap in web workers in
Firefox 8-18. This included increasing the timeout for the test suite
in the case of workers, and a back-up plan if timers are ignored.
@kriskowal
Copy link
Owner Author

Unfortunately, the TravisCI integration requires additional effort.

@kriskowal kriskowal changed the title Revised Test ALL the Browsers May 26, 2014
@kriskowal kriskowal changed the title Test ALL the Browsers ALL the Browsers May 26, 2014
requestFlush();
flushing = true;
}
// Not every browser supports `push` on arrays.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which don't?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing we actually care about. It’s been with us since Firefox 1.0, but before IE 5.5, Netscape Navigator at some point. We’re talking about ancient history. In any case, it’s one less function call. Would be interesting to see A/B benchmark numbers.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment is misleading, even if it's a good perf optimization (which I have heard is true).

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With narrative explaining why.

Fixes #21
@juandopazo
Copy link

wow

    such asap

@@ -0,0 +1,6 @@
**
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use the files property in package.json.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in working copy…

@kriskowal kriskowal self-assigned this May 28, 2014
@kriskowal
Copy link
Owner Author

Addressed comments so far. Back to the pool for feedback from @domenic and @rkatic.

@kriskowal kriskowal assigned domenic and unassigned kriskowal May 28, 2014
@rkatic
Copy link
Collaborator

rkatic commented May 29, 2014

Will try to take a look soon.
On May 28, 2014 7:14 PM, "Kris Kowal" notifications@github.com wrote:

Addressed comments so far. Back to the pool for feedback from @domenichttps://github.com/domenicand
@rkatic https://github.com/rkatic.


Reply to this email directly or view it on GitHubhttps://github.com//pull/41#issuecomment-44476655
.

@kriskowal
Copy link
Owner Author

So, TravisCI works now. However, I need to publish a fix to Q-IO for the Saucelabs test matrices to get copied around properly. That is not a blocker, but to be aware.

To allow the Saucelabs test matrix to be copied to S3 properly.
function Task() {}

Task.new = function () {
if (this.freeTasks.length) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it this.freeTasks, or Task.freeTasks?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.freeTasks when this === Task.

@rkatic
Copy link
Collaborator

rkatic commented Jun 1, 2014

I took a look to the node and the browser implementations of ASAP (have no time to also review tests and the testing infrastructure right now), and I don't have any major objection. For me, this is good to go.

I just have a minor objection, that could be probably handled later.
The domain module is required even if the user of ASAP never uses it.
Even if it's the simplest approach, it's probably not the best behavior we can adopt.
Loading the domain module, an additional complexity is added to the system, "wrapping" many built-in functions (setTimeout, nextTick, setImmediate, setIntervall...) and "unlocking" domain related logic in different built-in modules. We should probably avoid this if not necessary, requiring the domain module only if domains are actually in use.

So in raw.js, we can

var parentDomain = process.domain;
if (parentDomain) {
   if (!domain) domain = require("domain");
   domain.active = process.domain = null;
} 

and in asap.js, we can replace domain.active with process.domain.

In this way we can remove require("domain") on top of both files.

// a task throws an exception.
var index = 0;
// If a task schedules additional tasks recursively, the task queue can grown
// unbounded. To prevent memory excaustion, the task queue will periodically
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo "exhaustion"

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@domenic
Copy link
Collaborator

domenic commented Jun 1, 2014

+1 to @rkatic's comments.

Also: it seems like a lot of generated files are being checked in. Perhaps they could not be? Unsure how that would work though.

// shift tasks off the queue after they have been executed.
// Instead, we periodically shift 1024 tasks off the queue.
if (index > capacity) {
queue.splice(0, capacity);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here splice also unnecessary generates an array of 1024 tasks.
How about queue = queue.slice(capacity);?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both strategies generate a garbage array. Only way around this is to manually shift and truncate.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-   Note that raw asap does not handle domains and how to do so
    manually.
-   Clarify message channels, what they would do, why we don't use them.
-   Use try/finally instead of try/catch/finally to avoid munging stack
    traces.
-   Unroll queue shifts and truncate to avoid generating garbage.
@kriskowal
Copy link
Owner Author

Addressed comments by @rkatic and @domenic so far. If TravisCI passes, I will merge and publish unless there are any objections.

// by name.
setImmediate(function () {
throw error;
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we be more clear why kriskowal/q#396 does not apply here?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kriskowal in asap.js, you missed to remove domain loading and to replace
domain.active with process.domain.
On Jun 8, 2014 11:37 AM, "Kris Kowal" notifications@github.com wrote:

In browser-asap.js:

  •        // This hook exists purely for testing purposes.
    
  •        // Its name will be periodically randomized to break any code that
    
  •        // depends on its existence.
    
  •        asap.onerror(error);
    
  •    } else if (hasSetImmediate) {
    
  •        // In WebWorkers on Internet Explorer 10 and 11, the setTimeout
    
  •        // function is not FIFO.
    
  •        // Thankfully these browsers have setImmediate, which behaves
    
  •        // correctly.
    
  •        // In all other known cases, setTimeout is FIFO, including non
    
  •        // Worker contexts in the exact same browsers.
    
  •        // Note that in Internet Explorer 10, setImmediate must be called
    
  •        // by name.
    
  •        setImmediate(function () {
    
  •            throw error;
    
  •        });
    


Reply to this email directly or view it on GitHub
https://github.com/kriskowal/asap/pull/41/files#r13524709.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@rkatic
Copy link
Collaborator

rkatic commented Jun 8, 2014

@kriskowal skipped #41 (comment)?

@kriskowal
Copy link
Owner Author

@rkatic Thanks. I missed that one.

-   Lazy load domains module
-   Elaborate on why I elected setImmediate for error rethrow over
    setTimeout.
@kriskowal kriskowal merged commit 917bcb6 into master Jun 8, 2014
@kriskowal kriskowal deleted the revised branch June 8, 2014 18:48
@kriskowal
Copy link
Owner Author

I’ve merged this, mostly to get it on the main line. For further issues, please open tickets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants