Skip to content

Instantly share code, notes, and snippets.

Created August 27, 2012 20:05
Show Gist options
  • Save possibilities/3491825 to your computer and use it in GitHub Desktop.
Save possibilities/3491825 to your computer and use it in GitHub Desktop.
13:25 deberg: [17:21:57] hey, i just saw your question.
13:25 eiki: [17:22:17] great - any ideas?
13:25 deberg: [17:22:19] the thing to use is futures.
13:25 eiki: [17:22:36] what's the difference?
13:25 eiki: [17:22:45] and do you know of any sample code?
13:25 deberg: [17:23:02] yeah, one place to look is the meteor HTTP package.
13:25 deberg: [17:23:11] packages/http/httpcall_server.js:64
13:25 deberg: [17:23:39] this is the basic pattern for wrapping a node callback.
13:25 eiki: [17:24:09]
13:25 deberg: [17:24:35] you want to declare a new future, call future.return() inside the callback, and block the outer caller (your method) with future.wait().
13:25 ***: Playback Complete.
13:25 Mode: +cnt
13:25 Created at: Jan 28, 2010 12:55 AM
13:25 deberg: if you want to do Meteory things inside the callback context, you also want Meteor.bindEnvironment, which will wrap your callback and set up all the dynamic variables for write fencing and error reporting.
13:26 eiki: deberg: you lost me there :p
13:26 deberg: but usually you can get away w/o that. if all you need to do is get the return value out of the async callback and back into the original caller, just use future.return() and future.wait().
13:26 deberg: okay. we need a simpler example :/
13:26 eiki: ok I think I get the last part
13:26 eiki: we have async in async
13:26 eiki: and pretty much I would do it in the same way as a Promise now
13:27 eiki: deberg can you hang on
13:27 EhevuTov has joined (~EhevuTov@
13:27 eiki: got to drive a little
13:27 eiki: be right back
13:27 Leeol has joined (
13:27 tsurdilo1 has left IRC (Quit: Leaving.)
13:27 eiki has left IRC (Remote host closed the connection)
13:28 TRS52 has left IRC (Quit: KVIrc 4.2.0 Equilibrium
13:28 possibilities: deberg, what are the Meteory things you speak of?
13:28 deberg: something like this.
13:28 deberg:
13:28 deberg: (untested)
13:28 deberg: hi mike.
13:28 deberg: writing to the DB for one.
13:28 possibilities: yo (;
13:29 possibilities: ok, can you paste a quick usaage of Meteor.bindEnvironment too?
13:29 possibilities: i'll compile this into something for the wiki, or a gist or something
13:29 tsurdilo has joined (
13:29 deberg: packages/mongo-livedata/mongo_driver.js:95
13:29 deberg: uses both techniques.
13:30 deberg: future to block the caller until the async node DB driver calls its callback.
13:30 deberg: and then wrap a finish() callback in bindEnvironment so that that code has the Meteor dynamics.
13:30 possibilities: interesting, ok
13:31 deberg: i think what we'll want eventually is a Meteor.wrap() that encapsulates all of this.
13:31 deberg: i have to port a couple of async NPM packages to know the pattern for sure, though.
13:31 deberg: or someone else can :)
13:32 deberg: the bindEnvironment implementation is in packages/meteor/dynamics_nodejs.js
13:34 deberg: so, Meteory things are specifically any functions that call EnvironmentVariable.get().
13:34 tryggvil_ has left IRC (Read error: Connection reset by peer)
13:34 tryggvil_ has joined (
13:35 eiki has joined (
13:35 rads has joined (
13:35 possibilities: trying to figure out what in the mongo driver uses EnvironmentVariable.get() seems like refresh() doesn't but maybe i'm not digging deep enough
13:36 possibilities: in the example you pointed to packages/mongo-livedata/mongo_driver.js:95
13:37 deberg: okay.
13:37 possibilities: ah, looks like it's in commited
13:37 deberg: so think of bindEnvironment as setting up the special Meteor variables, which are all instances of EnvironmentVariable.
13:37 possibilities: cool, thanks, will dig deeper later
13:38 deberg: the Fiber that a method invocation runs inside gets those set up at initialization.
13:38 deberg: but anytime you break out of the Fiber and use an async callback, you have to reestablish them.
13:38 deberg: cool.
13:39 rads has left IRC (Ping timeout: 245 seconds)
13:41 banduk: guys, how to refer to the accounts userId from a collection (eg. profile)
13:41 banduk: ?
13:41 ankur has left IRC (Ping timeout: 246 seconds)
13:45 merunga has joined (~merunga@
13:45 merunga has left IRC (Client Quit)
13:49 eiki has left IRC (Remote host closed the connection)
13:50 possibilities: banduk, you're trying to establish a relationship between profile collection and user right?
13:51 idiomatique has left IRC (Quit: idiomatique)
13:53 banduk: yes
13:53 eiki has joined (
13:53 banduk: possibilities: yes, sure
13:53 eiki: deberg: just came back
13:53 possibilities: banduk, save the id as an attribute on the profile document
13:53 akhripin has left IRC (Ping timeout: 246 seconds)
13:53 possibilities: Profile.update(profileId, { $set: {userId: this.userId} })
13:53 possibilities: or somth
13:54 eiki: deberg: there are two use case I think, not sure which one of your examples does which
13:55 eiki: deberg: 1. browser client calls meteor server method that can return nothing but the client wants a session variable to change an reactively let the client know
13:55 banduk: possibilities: thanks! I'll just finish something I'm doing than I'll test!
13:55 deberg: 1 is confusing.
13:55 deberg: if the method doesn't return anything, how does the client know when to update the session variable?
13:56 eiki: deberg: 2. browser client calls a server method (async in async) but wants to wait for the answer but without blocking other meteor server requests
13:56 deberg: eiki: you want to unblock requests from the same client, or from other clients?
13:56 eiki: deberg: no the async method in the meteor server method needs to Session.set(thevariable)
13:56 deberg: sorry, i don't know what you mean by "Async in async".
13:57 arturadib has left IRC (Remote host closed the connection)
13:57 deberg: eiki: Session is a client-only module. server code doesn't have access to it.
13:57 eiki: deberg:
13:57 deberg: on the client, you can set it using the method callback, which runs async once the method returns.'foo', arg1, arg2, function (err, res) {Session.set('thevar', res);});
13:58 eiki: somemethod -> uses an async method (in our case the awssum node library)
13:58 eiki: well there lays the problem you see...
13:59 eiki: the "res" there is undefined
13:59 eiki: because of the async method in "foo"
13:59 eiki: uuuuunless, I use a Promise
13:59 akhripin has joined (
13:59 deberg: right.
13:59 deberg: that's what Future is for.
13:59 eiki: but that blocks other calls :p
14:00 deberg: it only blocks calls from the *same client*.
14:00 deberg: you want those unblocked?
14:00 eiki: yes
14:00 deberg: inside your method, call `this.unblock();`
14:00 eiki: the blocking is "same client" though today if I understand you
14:00 deberg: :)
14:00 deberg:
14:01 deberg: usually it's a lot easier if the client methods run serially. but in some cases w/ long-running methods, sure, you can unblock them.
14:01 deberg: useful for'move-the-forklift-to-building-9');
19:03 deberg: i've used in the past for some of the flow control ideas.
19:03 deberg: i think we can fold the best parts into meteor proper.
19:03 deberg: we never intended to expose Future -- it's just that we haven't gotten to building the right abstractions on top of it.
19:03 deberg: so same w/ flow control.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment