Deps.js rewrite, draft API docs are up

319 views
Skip to first unread message

David Greenspan

unread,
Mar 8, 2013, 5:18:05 PM3/8/13
to meteo...@googlegroups.com
I've been working on a refactor of deps in collaboration with Geoff which has acquired the codename "radical deps" (on the deps-radical branch).  It reorganizes deps around the primitives we've converged on for reactivity in our packages, such as "autorun" and ContextSet.  It's slated for the next release.

Feel free to browse the API docs at: http://radical-docs.meteor.com/#deps

To first order, things are renamed as follows:

- Meteor.deps -> Deps
- Meteor.autorun -> Deps.run
- Meteor.flush -> Deps.flush
- Meteor.deps.Context -> Deps.Computation (sort of)
- Meteor.deps.Context.current -> Deps.currentComputation (sort of; and you don't usually need it)
- Meteor.deps._ContextSet -> Deps.Variable

A Computation is like an autorun handle in that it is created and returned by Deps.run and has a stop() method.  It is also the only way to make a reactive context (now just called a reactive computation), so like a Context it has dependencies and gets invalidated when they change.  When a computation is invalidated, however, it reruns at flush time and "bounces back" to valid, until you stop() it.  "Rerunning" a computation is a first-class thing now, not the result of an onInvalidate callback.  There are still onInvalidate callbacks, but their importance is greatly reduced; they are used for bookkeeping and clean-up by reactive data sources, like calling stop() and removing dependencies, and they fire synchronously upon invalidate() rather than waiting for flush time.  Deps.flush simply reruns (recomputes) all invalidated computations.  It's an error now to nest Deps.flush or call it from Deps.run.

ContextSet (previously private) is renamed Deps.Variable and essentially made primitive (we no longer suggest that you keep track of Contexts/Computations yourself when writing a reactive data source).  A Variable is the atomic unit of data for reactivity purposes -- the smallest thing you can depend on.  It doesn't contain a value, but it represents an abstract value that may "change" and cause dependent computations to be invalidated.  See the docs for Deps.Variable for more info and an example.

-- David

Tim Haines

unread,
Mar 8, 2013, 5:59:00 PM3/8/13
to meteo...@googlegroups.com
Hey David and Geoff,

Nice work on this.

Some feedback on first read:

  • I think renaming autorun to run has detrimentally removed a decent clue about what the method does.

  • Purely opinion: The naming feels a little awkward.  Kind of like Deps an abbreviation for Dependencies.  But if that's the case, why not call it Dependencies?  Also, to the newbie, it could probably be mistake for the more common code/library dependencies.  I'd love to be able to offer a suggestion of something that's better, but I don't really have one.   Reactor?  Reactivity?

  • Deps is one of the more difficult components of Meteor to understand I think.  While I mostly understand the intentions of it when I slowly read through the docs, using it is not something I've easily been able to figure out based on having previously read the docs.  No suggestions here - just sharing a perspective of someone who's been using Meteor for couple of months now.

Cheers,

Tim.



--
You received this message because you are subscribed to the Google Groups "meteor-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-core...@googlegroups.com.
To post to this group, send email to meteo...@googlegroups.com.
Visit this group at http://groups.google.com/group/meteor-core?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

David Wihl

unread,
Mar 9, 2013, 8:18:53 AM3/9/13
to meteo...@googlegroups.com
This looks like a step in the right direction, especially Deps.Variable to combine several dependencies into one atomic unit. However, it does not appear to address of the biggest issues we've seen with Meteor, namely partial server updates causing reactivity. As data is loaded progressively from the server multiple reactive context fire and then re-fire as more data is loaded. In a complicated multistage app like our Gander (beta.gander.io) this leads to a lot of flashing and re rendering until everything finally settles down.

So how does the new dependency API address:
1. batching live updates until the client data is at a known stable state?

2. the case of a client updating a collection which is subsequently invalidated by the server? Sure is it possible today to use isSimulated, but AFAIK, that does not really say that everything is in sync. Instead the user sees the UI update, thinks it is done, then has his action undone as the server resets the update. Could the dependency API be set to only trigger once the server has completed the operation rather than just the client operation?

Perhaps we can use a better design pattern to solve the above on our own, but we haven't found one when so much of the collection invalidation logic is in the lower levels of the Meteor APIs. (We already define our own reactive variables to handle client side state changes within our app rather than munging it all into Session variables).

Andrew Wilcox

unread,
Mar 9, 2013, 10:34:32 AM3/9/13
to meteo...@googlegroups.com
I notice in the Variable example

var weatherDeps = new Deps.Variable;

the variable name is "weatherDeps".  This makes sense because it is tracking a dependency in the computation:

Deps.depend(weatherDeps);
 
weatherDeps.changed();

"What has changed?"  "A weather dependency".

Seeing as how the natural name for the concept is "dependency", I wonder if "Variable" might be better named "Dependency"

var weatherDeps = new Deps.Dependency;

Hmm, also consider the confusion in

Variables don't store data, ...
 
What is a "variable"?  A value that can vary.   (Thus "vari-able".   Contrast with a "constant', a value that cannot change).  So you start with a concept of a "variable", something that has a value, and then have to explain how this Variable doesn't have a value.

Compare

Variables don't store data, they just track the set of computations to invalidate if they change. Typically, a data value will be accompanied by a Variable that affords dependency tracking, as in this example:

with

Dependencies don't store data themselves, they just track the set of computations to invalidate if their associated data changes. Typically, a data value will be accompanied by a Dependency that affords dependency tracking, as in this example:

David Greenspan

unread,
Mar 12, 2013, 7:01:37 PM3/12/13
to meteo...@googlegroups.com
Tim, we've taken your suggestion and kept the name "autorun" rather than "run."  I agree Deps is still not as approachable as the rest of Meteor, probably because it is so abstract, and it isn't a package most developers will acquire a deep understanding of.

Andrew, good idea.  There was some internal controversy over the name "Variable" too.  The word has several meanings already (for example "Session variables"), and in all cases variables have values.  We're going with Dependency.

David,

1) Can you give an example?

2) If you don't want the client to update until the mutation lands, you can declare the methods only on the server.  The reason for simulations is to display something on the client sooner.  In the basic case, like clicking a "Like" button or a "Follow" button, say, it makes sense to do the simulation even though it is technically speculative.  These simulations are easy in Meteor because usually the client-side simulation and the server-side real implementation can be the same.  The server ultimately needs to approve the change for security reasons, but there's no normal way for a change to bounce (the "Like" button is only shown if the user is logged in and the action is valid).  You can make any database changes you want in a simulation, and they will be reset when the method lands (unless the server did the same thing).  This lets you provide feedback in all sorts of ways.

In case it's not clear, Meteor.methods declares simulations (stubs) on the client and real implementations on the server.  isSimulation is basically equivalent to isClient at the moment.

Hope this helps.

-- David







Andrew Wilcox

unread,
Mar 12, 2013, 7:32:50 PM3/12/13
to meteo...@googlegroups.com


On Friday, March 8, 2013 5:59:00 PM UTC-5, Tim Haines wrote:
  • Purely opinion: The naming feels a little awkward.  Kind of like Deps an abbreviation for Dependencies.  But if that's the case, why not call it Dependencies?  Also, to the newbie, it could probably be mistake for the more common code/library dependencies.  I'd love to be able to offer a suggestion of something that's better, but I don't really have one.   Reactor?  Reactivity?
"Reactive"

var weather = "sunny";
var weatherDeps = new Reactive.Dependency;

var getWeather = function () {
  Reactive.depend(weatherDeps);
  return weather;
};

var setWeather = function (w) {
  weather = w;
  // (could add logic here to only call changed()
  // if the new value is different from the old)
  weatherDeps.changed();
};

Tim Haines

unread,
Mar 12, 2013, 7:56:17 PM3/12/13
to meteo...@googlegroups.com
When my co-founder and I talk about adding the behavior that Deps allows, we say "We need to make this reactive", or "How do we make this reactive".  +1 for Reactive.  In addition to Andrew's examples, Reactive.Computation seems to fit well too.

};

Tom Coleman

unread,
Mar 12, 2013, 8:00:10 PM3/12/13
to meteo...@googlegroups.com
+1 -- dependency tracking is a implementation detail of making code reactive.

Nick Martin

unread,
Mar 18, 2013, 8:02:51 PM3/18/13
to meteo...@googlegroups.com
Just want to close the loop on this so it doesn't look like we simply ignored your input =)

We were still actively debating this, but then having to push 0.5.8 in a hurry forced us to run with Deps for lack of time to rename. This doesn't mean we can't rename in the future (back-compatibility is easy in this case).

-- Nick

Tim Haines

unread,
Mar 20, 2013, 4:52:51 PM3/20/13
to meteo...@googlegroups.com
Hey Nick,

Thanks for following up on this.  It's understandable that you decided to push the update in a hurry when you released the security update.

For the benefit of the people following this conversation, it would be good to hear any conclusions you reached on the merits of renaming Deps to Reactivity.  Maybe it's as simple as "it's released now as Deps, and the impact of renaming it again would involve too much effort for too little benefit".  But if there are other reasons for not renaming, it would be useful to hear them to further understanding.

Cheers,

Tim.

Nick Martin

unread,
Mar 20, 2013, 5:30:04 PM3/20/13
to meteo...@googlegroups.com
Sure!

We didn't really come to any conclusions.

The problem with the name 'Reactor' is that it is already the name of a different and unrelated async event pattern (http://en.wikipedia.org/wiki/Reactor_pattern)

The main issue on the table with the name 'Reactivity' is that it is an adjective, not a noun. This makes for awkward sentences and doesn't read as well in many cases.

Cheers,
-- Nick

Iain Shigeoka

unread,
Mar 22, 2013, 5:52:29 PM3/22/13
to meteo...@googlegroups.com
+1 for a name change to some form of Reactive and autorun

I'm late to the party but I do prefer a longer, more descriptive name both for Deps and run (back to autorun). For the most part, code using the API tends to be "tricky" by nature so more descriptive, easier to read names rather than terse ones will help readability.

-iain
Reply all
Reply to author
Forward
0 new messages