Skip to content

Instantly share code, notes, and snippets.

@possibilities
Created August 23, 2012 22:53

Revisions

  1. possibilities revised this gist Nov 18, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@ From Meteor's documentation:

    > In Meteor, your server code runs in a single thread per request, not in the asynchronous callback style typical of Node. We find the linear execution model a better fit for the typical server code in a Meteor application.
    This guide serves as a mini-tour of tool, trix and patterns that can be used to run async code in Meteor.
    This guide serves as a mini-tour of tools, trix and patterns that can be used to run async code in Meteor.

    ## Basic async

  2. possibilities revised this gist Sep 8, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -110,7 +110,7 @@ If you want to collect results from parallel async jobs you'll have to do a litt

    ## Unblocking `Meteor.methods`

    While each approach described so far breaks from Meteor's default synchronous programming style requests from a given client are still processed one at a time. If you have a method that could take a long time call `this.unblock()` and subsequent requests will be run in a new fiber.
    Each approach described so far breaks from Meteor's default synchronous programming style, but requests from a given client are still processed one at a time. If you have a method that could take a long time call `this.unblock()` and subsequent requests will be run in a new fiber.

    Meteor.methods({
    moveForkliftToBuilding9: function(message) {
  3. possibilities revised this gist Aug 29, 2012. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -161,8 +161,6 @@ Thanks to the following people for their help with this:

    Tom Coleman [@tmeasday](https://github.com/tmeasday)

    mhr (TODO: get real info)

    ## Resources

    [http://stackoverflow.com/a/11510874](http://stackoverflow.com/a/11510874)
  4. possibilities revised this gist Aug 28, 2012. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -40,7 +40,8 @@ Sometimes we want to run more than one async methods in parallel and wait for th
    // We're going to make http get calls to each url
    var urls = [
    'http://google.com',
    'http://news.ycombinator.com'
    'http://news.ycombinator.com',
    'https://github.com'
    ];

    // Keep track of each job in an array
  5. possibilities revised this gist Aug 28, 2012. No changes.
  6. possibilities revised this gist Aug 28, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -152,7 +152,7 @@ At this point I'm leaving this purposely unfinished because until I have opportu

    Include all useful info mentioned by Matt [here](https://gist.github.com/3491825)

    Instead of example like `asyncJob` come up with meaningful names and implementations
    Instead of example like `asyncJob` and `parallelAsyncJob` come up with meaningful names and implementations

    ## Contributions

  7. possibilities revised this gist Aug 28, 2012. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -152,6 +152,8 @@ At this point I'm leaving this purposely unfinished because until I have opportu

    Include all useful info mentioned by Matt [here](https://gist.github.com/3491825)

    Instead of example like `asyncJob` come up with meaningful names and implementations

    ## Contributions

    Thanks to the following people for their help with this:
  8. possibilities revised this gist Aug 28, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -124,7 +124,7 @@ While each approach described so far breaks from Meteor's default synchronous pr

    If you need to access Meteor's full environment in an asynchronous method's callback Meteor provides a wrapper called `Meteor.bindEnvironment`:

    *TODO this one sucks so far, fix it*
    *TODO make better example*

    var fn = function(error, result) {
    console.log('done ' + result);
  9. possibilities revised this gist Aug 28, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -122,7 +122,7 @@ While each approach described so far breaks from Meteor's default synchronous pr

    ## Accessing Meteor's full environment from async callbacks

    If you need to access Meteor's full environment in an asynchronously method's callback Meteor provides a wrapper called `Meteor.bindEnvironment`:
    If you need to access Meteor's full environment in an asynchronous method's callback Meteor provides a wrapper called `Meteor.bindEnvironment`:

    *TODO this one sucks so far, fix it*

  10. possibilities revised this gist Aug 28, 2012. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -154,7 +154,11 @@ Include all useful info mentioned by Matt [here](https://gist.github.com/3491825

    ## Contributions

    Thanks to Tom Coleman [@tmeasday](https://github.com/tmeasday) for his help with this!
    Thanks to the following people for their help with this:

    Tom Coleman [@tmeasday](https://github.com/tmeasday)

    mhr (TODO: get real info)

    ## Resources

  11. possibilities revised this gist Aug 28, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -150,7 +150,7 @@ At this point I'm leaving this purposely unfinished because until I have opportu

    ## TODO

    Add all useful info mentioned by Matt [here](https://gist.github.com/3491825)
    Include all useful info mentioned by Matt [here](https://gist.github.com/3491825)

    ## Contributions

  12. possibilities revised this gist Aug 28, 2012. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -150,8 +150,6 @@ At this point I'm leaving this purposely unfinished because until I have opportu

    ## TODO

    Cleanup, writing is terrible

    Add all useful info mentioned by Matt [here](https://gist.github.com/3491825)

    ## Contributions
  13. possibilities revised this gist Aug 28, 2012. 1 changed file with 5 additions and 4 deletions.
    9 changes: 5 additions & 4 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -131,10 +131,11 @@ If you need to access Meteor's full environment in an asynchronously method's ca
    };

    fn = Meteor.bindEnvironment(callback, function(e) {
    console.log("Something went wrong! " +
    "Everything is broken! " +
    "Your life is ruined!",
    e.stack);
    var message = "Something went wrong! " +
    "Everything is broken! " +
    "Your life is ruined!";

    console.log(message, e.stack);
    });

    myAsyncMethodThatNeedAccessToMeteorEnv(fn);
  14. possibilities revised this gist Aug 28, 2012. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -127,8 +127,6 @@ If you need to access Meteor's full environment in an asynchronously method's ca
    *TODO this one sucks so far, fix it*

    var fn = function(error, result) {
    if (error)
    throw error;
    console.log('done ' + result);
    };

  15. possibilities revised this gist Aug 28, 2012. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -133,8 +133,10 @@ If you need to access Meteor's full environment in an asynchronously method's ca
    };

    fn = Meteor.bindEnvironment(callback, function(e) {
    console.log("Something went wrong! Everything is broken! " +
    "Your life is ruined!", e.stack);
    console.log("Something went wrong! " +
    "Everything is broken! " +
    "Your life is ruined!",
    e.stack);
    });

    myAsyncMethodThatNeedAccessToMeteorEnv(fn);
  16. possibilities revised this gist Aug 28, 2012. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -126,18 +126,18 @@ If you need to access Meteor's full environment in an asynchronously method's ca

    *TODO this one sucks so far, fix it*

    var callback = function(error, result) {
    var fn = function(error, result) {
    if (error)
    throw error;
    console.log('done ' + result);
    };

    callback = Meteor.bindEnvironment(callback, function (e) {
    fn = Meteor.bindEnvironment(callback, function(e) {
    console.log("Something went wrong! Everything is broken! " +
    "Your life is ruined!", e.stack);
    });

    myAsyncMethodThatNeedAccessToMeteorEnv(callback);
    myAsyncMethodThatNeedAccessToMeteorEnv(fn);

    ## Packaging async node modules

  17. possibilities revised this gist Aug 28, 2012. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -133,7 +133,8 @@ If you need to access Meteor's full environment in an asynchronously method's ca
    };

    callback = Meteor.bindEnvironment(callback, function (e) {
    console.log("Something went wrong! Everything is broken! Your life is ruined!", e.stack);
    console.log("Something went wrong! Everything is broken! " +
    "Your life is ruined!", e.stack);
    });

    myAsyncMethodThatNeedAccessToMeteorEnv(callback);
  18. possibilities revised this gist Aug 28, 2012. 1 changed file with 16 additions and 2 deletions.
    18 changes: 16 additions & 2 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -120,9 +120,23 @@ While each approach described so far breaks from Meteor's default synchronous pr

    *Note: borrowed this method name from Matt Debergalis because I think it's hilarious*

    ## Accessing Meteor's full environment from async calls
    ## Accessing Meteor's full environment from async callbacks

    TODO
    If you need to access Meteor's full environment in an asynchronously method's callback Meteor provides a wrapper called `Meteor.bindEnvironment`:

    *TODO this one sucks so far, fix it*

    var callback = function(error, result) {
    if (error)
    throw error;
    console.log('done ' + result);
    };

    callback = Meteor.bindEnvironment(callback, function (e) {
    console.log("Something went wrong! Everything is broken! Your life is ruined!", e.stack);
    });

    myAsyncMethodThatNeedAccessToMeteorEnv(callback);

    ## Packaging async node modules

  19. possibilities revised this gist Aug 28, 2012. 1 changed file with 9 additions and 2 deletions.
    11 changes: 9 additions & 2 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -109,9 +109,16 @@ If you want to collect results from parallel async jobs you'll have to do a litt

    ## Unblocking `Meteor.methods`

    TODO
    While each approach described so far breaks from Meteor's default synchronous programming style requests from a given client are still processed one at a time. If you have a method that could take a long time call `this.unblock()` and subsequent requests will be run in a new fiber.

    Meteor.methods({
    moveForkliftToBuilding9: function(message) {
    this.unblock();
    forklift.moveTo({ building: 9 })
    }
    });

    TODO
    *Note: borrowed this method name from Matt Debergalis because I think it's hilarious*

    ## Accessing Meteor's full environment from async calls

  20. possibilities revised this gist Aug 28, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -32,7 +32,7 @@ Sometimes we need to run async code in `Meteor.methods`. For this we create a `F

    ## Parallel async

    We also commonly need to run multiple async calls in parallel. This could be applied to any async method but here we're using Meteor's own Meteor.http.get's async method signature because it's commonly desirable to run a batch of http calls in parallel and wait for the result (or not wait for the result using the unblocking technique described below).
    Sometimes we want to run more than one async methods in parallel and wait for them all to complete before returning:

    Meteor.methods({
    parallelAsyncJob: function(message) {
  21. possibilities revised this gist Aug 28, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@ This guide serves as a mini-tour of tool, trix and patterns that can be used to

    ## Basic async

    Often we want to use a 3rd party library without a synchronous interface or we want to use the asynchronous interface because we're going to run something that could take a very long time to complete and we want to use the unblocking technique (described below) to process additional request for the client while we wait. The basic pattern for this can be found all over Meteor's codebase and looks like this:
    Sometimes we need to run async code in `Meteor.methods`. For this we create a `Future` to block until the async code has finished. This pattern can be seen all over Meteor's own codebase:

    Meteor.methods({
    asyncJob: function(message) {
  22. possibilities revised this gist Aug 28, 2012. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,8 @@
    If you're reading this you probably understand that Meteor's server side code is all run synchronously. This article gives a mini-tour of patterns we can use when we need to run asynchronous code in the Meteor environment
    From Meteor's documentation:

    > In Meteor, your server code runs in a single thread per request, not in the asynchronous callback style typical of Node. We find the linear execution model a better fit for the typical server code in a Meteor application.
    This guide serves as a mini-tour of tool, trix and patterns that can be used to run async code in Meteor.

    ## Basic async

  23. possibilities revised this gist Aug 28, 2012. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ Often we want to use a 3rd party library without a synchronous interface or we w
    Meteor.methods({
    asyncJob: function(message) {
    // Setup a future
    // Set up a future
    var fut = new Future();

    // This should work for any async method
    @@ -42,7 +42,7 @@ We also commonly need to run multiple async calls in parallel. This could be app
    // Keep track of each job in an array
    var futures = _.map(urls, function(url) {

    // Setup a furture for the current job
    // Set up a future for the current job
    var future = new Future();

    // A callback so the job can signal completion
    @@ -84,7 +84,7 @@ If you want to collect results from parallel async jobs you'll have to do a litt
    /// Make async http call
    Meteor.http.get(url, function(error, result) {

    // Get the title, if there was no error
    // Get the title if there was no error
    var title = (!error) && getTitle(result);
    onComplete(error, title);
    @@ -133,4 +133,4 @@ Thanks to Tom Coleman [@tmeasday](https://github.com/tmeasday) for his help with

    ## Resources

    [http://stackoverflow.com/a/11510874](http://stackoverflow.com/a/11510874)
    [http://stackoverflow.com/a/11510874](http://stackoverflow.com/a/11510874)
  24. possibilities revised this gist Aug 27, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -125,7 +125,7 @@ At this point I'm leaving this purposely unfinished because until I have opportu

    Cleanup, writing is terrible

    Add all useful info mentioned by matt [here](https://gist.github.com/3491825)
    Add all useful info mentioned by Matt [here](https://gist.github.com/3491825)

    ## Contributions

  25. possibilities revised this gist Aug 27, 2012. 1 changed file with 7 additions and 1 deletion.
    8 changes: 7 additions & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -121,10 +121,16 @@ TODO

    At this point I'm leaving this purposely unfinished because until I have opportunities to use these techniques more than once, in real apps, I don't want to guess what the right abstractions are. Hopefully people will write awesome smart packages for this stuff and we can find out together what will be most effective and then campaign for our favorites to be be included in core.

    ## TODO

    Cleanup, writing is terrible

    Add all useful info mentioned by matt [here](https://gist.github.com/3491825)

    ## Contributions

    Thanks to Tom Coleman [@tmeasday](https://github.com/tmeasday) for his help with this!

    ## Resources

    [http://stackoverflow.com/a/11510874](http://stackoverflow.com/a/11510874)
    [http://stackoverflow.com/a/11510874](http://stackoverflow.com/a/11510874)
  26. possibilities revised this gist Aug 26, 2012. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -121,6 +121,10 @@ TODO

    At this point I'm leaving this purposely unfinished because until I have opportunities to use these techniques more than once, in real apps, I don't want to guess what the right abstractions are. Hopefully people will write awesome smart packages for this stuff and we can find out together what will be most effective and then campaign for our favorites to be be included in core.

    ## Contributions

    Thanks to Tom Coleman [@tmeasday](https://github.com/tmeasday) for his help with this!

    ## Resources

    [http://stackoverflow.com/a/11510874](http://stackoverflow.com/a/11510874)
  27. possibilities revised this gist Aug 26, 2012. 1 changed file with 15 additions and 33 deletions.
    48 changes: 15 additions & 33 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -69,53 +69,35 @@ We also commonly need to run multiple async calls in parallel. This could be app

    If you want to collect results from parallel async jobs you'll have to do a little more work:

    *Note: Eager to see a better implementation of this!

    Meteor.methods({
    parallelAsyncJob: function(message) {

    // Setup a future
    var fut = new Future();

    var urls = [
    'http://google.com',
    'http://news.ycombinator.com',
    'https://github.com'
    ];

    var urlResults = [];

    var onComplete = function(err, result) {
    urlResults.push(result);

    // Once we've recieved all the results
    // return them
    if (urlResults.length >= urls.length)

    // Return the results
    fut.ret(urlResults);
    };

    // Keep track of each job in an array
    _.each(urls, function(url) {

    var futures = _.map(urls, function(url) {
    var future = new Future();
    var onComplete = future.resolver();
    /// Make async http call
    Meteor.http.get(url, function(error, result) {

    // Get the title
    var title = getTitle(result);

    // Inform the future that we're done with,
    // it and send the title in place of the
    // raw result
    // Get the title, if there was no error
    var title = (!error) && getTitle(result);
    onComplete(error, title);
    });

    return future;
    });

    // Wait for async to finish before returning
    // the result
    return fut.wait();

    // wait for all futures to finish
    Future.wait(futures);

    // and grab the results out.
    return _.invoke(futures, 'get');
    }
    });

  28. possibilities revised this gist Aug 24, 2012. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -88,7 +88,8 @@ If you want to collect results from parallel async jobs you'll have to do a litt
    var onComplete = function(err, result) {
    urlResults.push(result);

    // Once we've recieved all the results return them
    // Once we've recieved all the results
    // return them
    if (urlResults.length >= urls.length)

    // Return the results
  29. possibilities revised this gist Aug 24, 2012. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -67,6 +67,10 @@ We also commonly need to run multiple async calls in parallel. This could be app

    [Code](https://github.com/possibilities/parallel-async-test-app)

    If you want to collect results from parallel async jobs you'll have to do a little more work:

    *Note: Eager to see a better implementation of this!

    Meteor.methods({
    parallelAsyncJob: function(message) {

  30. possibilities revised this gist Aug 24, 2012. 1 changed file with 47 additions and 0 deletions.
    47 changes: 47 additions & 0 deletions meteor-async.md
    Original file line number Diff line number Diff line change
    @@ -67,6 +67,53 @@ We also commonly need to run multiple async calls in parallel. This could be app

    [Code](https://github.com/possibilities/parallel-async-test-app)

    Meteor.methods({
    parallelAsyncJob: function(message) {

    // Setup a future
    var fut = new Future();

    var urls = [
    'http://google.com',
    'http://news.ycombinator.com',
    'https://github.com'
    ];

    var urlResults = [];

    var onComplete = function(err, result) {
    urlResults.push(result);

    // Once we've recieved all the results return them
    if (urlResults.length >= urls.length)

    // Return the results
    fut.ret(urlResults);
    };

    // Keep track of each job in an array
    _.each(urls, function(url) {

    /// Make async http call
    Meteor.http.get(url, function(error, result) {

    // Get the title
    var title = getTitle(result);

    // Inform the future that we're done with,
    // it and send the title in place of the
    // raw result
    onComplete(error, title);
    });

    });

    // Wait for async to finish before returning
    // the result
    return fut.wait();
    }
    });

    [Code](https://github.com/possibilities/parallel-async-return-values-test-app)

    ## Unblocking `Meteor.methods`