Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"fence has already activated -- too late to add writes"

Tags:

meteor

What does the following error message mean?

fence has already activated -- too late to add writes

Here's an example of how to get it:

Environment:

  • Mac OS X Lion
  • Meteor 0.3.8

Project creation:

meteor create test
cd test
meteor add coffeescript http
mv test.js test.coffee
meteor

test.coffee:

Records = new Meteor.Collection("records")

if Meteor.is_client
    Meteor.startup ->
        Meteor.call "test"

if Meteor.is_server
    Meteor.methods
        test: ->
            Meteor.http.get "http://www.meteor.com", ->
                Records.insert some:"data"
like image 924
Lloyd Avatar asked Dec 26 '22 21:12

Lloyd


2 Answers

Once the method is done executing you can't add additional writes. To delay completing the methods you can use Futures. Something like this:

Meteor.methods({
  foo: function() {
    var futures = _.map(urls, function(url) {
      var future = new Future();
      var onComplete = future.resolver();

      Meteor.http.get(url, function(error, result) {
        // do whatever you need

        onComplete();
      });

      return future;
    });

    Future.wait(futures);
  }
});
like image 122
avital Avatar answered Jan 17 '23 23:01

avital


Methods have to finish all their writes before they return.

In this example the easiest way would be to simply omit the callback, and use the return value of Meteor.http.get:

if Meteor.is_server
    Meteor.methods
       test: ->
          data = Meteor.http.get "http://www.meteor.com"
          Records.insert some:"data"

Behind the scenes this is using Futures like avital says. If you want to do multiple callbacks in parallel or other complex things, you can use the Futures api. However, if you are just making one request, or your requests already have to be in sequence, using the synchronous version of Meteor.http.get works and is easier to type.

like image 41
n1mmy Avatar answered Jan 17 '23 23:01

n1mmy