
Show HN: Sync – Realtime partials with Rails - chrismccord
http://chrismccord.com/blog/2013/04/21/sync-realtime-rails-partials/
======
habosa
Wow this really should become part of core Rails. This is definitely real time
done the "rails way". I prefer Rails to anything else I've tried but my ideas
increasingly revolve around real-time, so I either settle for a framework I
like less or Rails + jQuery nonsense. This will be my new go to.

------
marcamillion
I really like this.

The only thing that kinda threw me off a bit was putting the partials in the
/views/sync/resource/ folder. Feels a bit non-RESTy.

I imagine, for a sufficiently complex app that sync folder will become a bit
messy - although, I guess it's like the 'layout' folder.

That's just me being nitpicky though.

This is awesome.

As others pointed out, this would be perfect if it weren't for the fact that
you have to use additional resources to use it properly. i.e. another dyno for
Faye or use Pusher.

Thanks for this though.

Edit: One thing I would love to know is how this interacts with caching
though. Russian Doll Caching specifically. Every time an attributed is update,
does it bust the entire cache and have to reload that entire fragment - as
opposed to just the partial?

~~~
chrismccord
The partials each get separated into their own folder based on their model
name. So it's not a grab-bag of random partials – it's the same folder
structure an application would use for its regular views, but instead with a
parent sync folder. ie, if a views/users/ directory contained
"_profile.html.erb", you would move the sync partial to views/sync/users/.
Having to run an additional process is the best case scenario right now unless
we can get websockets into Rails/Ruby land, but I'm a believer that this
approach is the best solution for current tooling suits the problem quite
well. In regards to russian doll caching I'll have to take a look and verify
what's going on under the hood, but sync will work fine with fragment caching
outside and within a sync'd partial as long as the cache keys properly account
for the resource/scope. When a model is updated on the server and `sync_update
user` is called, Sync will render every partial to string in the
views/sync/users directory, and dispatch a message to listeners on each
channel for each partial. So the sync will only re-render what's contained in
the sync'd partial. If you have fragment caches within your sync'd partial,
they will only bust if their cache key has expired just like a normal render.
Hopefully that helps. Thanks for the input/complements

~~~
tomhallett
Can you provide some details on why the partials have to be namespace'd to the
sync directory? My guess is: sync partials can only be "resource" based, and
can't be given locals like a regular partial. Therefore, sync-partials are a
subset of regular partials, so a different directory makes the distinction
very clear.

Just curious what the reason is.

Looks very cool, I will definitely try it out!

~~~
chrismccord
You're right about part of the reason. One reason the partials are namespaced
is indeed to serve as a distinction since at the moment, only the resource can
hold the context for the partial. ivars will be visible from both the parent
view render and controller sync calls, but likely not reliable since the
partials will be rendered from different actions. The main reason they are
namespaced is to allow rendering of all partials for the sync'd resource when
publishing syncs in the controller. We can just ask the resource to give us
all its partials in the views/sync/[resource pluralized] directory and only
render those partials that are realtime, versus needlessly rendering all
partials (including non-realtime) in the 'normal' resource directory.

------
hemancuso
Looks neat, but I am curious why you would pick such an overused name for the
project. Perhaps call it PartialSync, or something you could google?

~~~
chrismccord
I struggled with the naming to be honest, but settled on something short and
sweet that sounded nice to me. Googling hopefully won't be a problem when
coupled with a copule modifiers, ie "sync realtime partials"

------
hifier
This looks really great. Does anyone have any thoughts on how this could be
combined with client friendly templating so that the rendering of the partial
could be done client side for updates, but server side for the initial page
load?

~~~
wilg
If I understand right, the whole point of Sync is to avoid having to do this.

~~~
hifier
It would simply be a change in the templates that you use and how the changes
are communicated to the client. It could still work the same way from the
perspective that the changes are pushed to the client and the DOM is
automatically replaced. The reason that I ask is that this could offload some
of the server side processing to the client and also reduce the amount of data
transfered over the wire. The server would be pushing JSON instead of HTML.
From the dev's perspective you'd just be using a different templating
framework. I wonder how the current implementation would scale, I imagine it
would take some serious processing power to get to 100k+ concurrent, active
users.

------
robotmay
Looks neat. I actually would have made use of this a couple of weeks ago, but
I'll keep it in mind if we rewrite that section of the app (as the current
solution isn't quite as elegant).

------
benradler
Me gusta. Can this potentially replace a client-side MVC framework like
backbone.js or ember.js entirely or are there limitations?

~~~
chrismccord
Sync is an _alternative_ to Ember/Backbone, but not a replacement. If you're
trying to replicate desktop software in the browser for instance, a heavy
client-side framework is the way to go; however, for certain use cases for web
applications with lots of "richness" but not trying to replicate desktop level
interactivity, think Basecamp, Reddit, Facebook, Twitter, the Sync approach
could definitely hold its own against these types of apps. I've greatly
enjoyed building Backbone apps, and I look forward to playing with Ember, but
not every web application needs to be rendered client-side against a JSON api.
Sync also allows you to wire up your own javascript, so you could even use
backbone models submitting over JSON and render your realtime views with Sync
on the server. I'm excited to see how far we can take this approach.

~~~
benradler
thanks for the info chris, I will be following the project closely. I think I
will try and implement it in one of my instagram-API driven web apps as a
test.

~~~
chrismccord
No problem. Let me know how it goes

------
killion
Great! This will come in handy for new projects. Unfortunately we had to
create the same thing for our existing stuff.

------
acjohnson55
Does anybody know of anything like this for Django? I'm very much interested
in better integration between client-side and server-side code. I'm really not
sold on the client-side MVC paradigm, and I think this sounds like an awesome
alternative.

------
joshcrowder
This is brilliant, looking forward to using this.

Is this in use anywhere?

~~~
chrismccord
I just pushed out the official release this weekend and don't have any apps
yet running in production. My goal is to have people start building out apps
and support any uncovered use cases that crop up. Having said that, there's no
reason this can't be run in production and I plan on deploying a couple
example apps so people can play around.

~~~
tortilla
This looks perfect for a current project with a quite a bit of jQuery and
partials. I may just redo using Sync. Do you have any recommendations for
using on Heroku? Should I just use Pusher? Also does this work with Rails 4?

~~~
chrismccord
Faye will gladly run on Heroku with a foreman process, but I think Pusher is a
tough choice to beat to get you up and running quickly. Sync does indeed
support Rails 4. In fact, the demo app in the screencast is a Rails 4 app :)

~~~
scoot
So either Pusher or Faye are required, and Pusher is a commercial service,
whilst Faye requires a dyno to run on Heroku? Have I got that right? TBH I'm
not familiar with either Pusher or Faye, so just trying to grok the
dependancies for Sync.

~~~
chrismccord
That's correct. If on Heroku, Faye would run in it's own dyno process, while
Pusher is a commercial product. Sync requires a pubsub server to talk to, so
either is a must. I suggest prototyping out with the Pusher free plan if you
just want to throw something up to experiment with.

------
Jarred
This is awesome! The next time I need functionality similar to what a client-
side MVC framework provides, I'll give this a try first.

------
livando
awesome, great way to spike out real time behavior in minutes.

------
TallboyOne
Very cool, I like

------
tikhon
Wow. I'm really impressed. Great work, Chris.

------
andyl
OMG this is great - should be a standard part of rails.

