You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by Adam Winer <aw...@google.com> on 2008/08/14 17:49:07 UTC

Feature proposal: OpensocialPreload

In the Orkut OpenSocial implementation (pre-Shindig), we have an
existing OpenSocial API prefetcher that has proven extremely useful in
reducing latency from initial API requests.  Our existing Orkut
implementation:
  - records incoming API requests
  - uses those records to statistically guess what API calls a
    gadget makes when first rendering
  - fetches the data for those API calls, and inserts the data
    into the gadget
  - transparently intercepts items within the first
    newDataRequest() call and uses the preloaded result instead,
    with no HTTP round-trip if all items are present

This technique successfully delivers content to ca. 90% of gadget
renders, with another 7% or so gadgets that do not make OpenSocial
data requests at all.  Overall, this eliminates more than 2 out of
every 3 data requests in production.
I've been thinking over how to bring it into Shindig, and would like
to start with a declarative approach via an optional feature,
OpensocialPreload.  Statistical sampling would be a follow-on
implementation detail to provide a similar optimization for those
not declaratively specifying the feature (though I'm happy to share
more details on how it could work.)

XML:
<Optional feature="OpensocialPreload">
  <!-- key "viewer", fetch the viewer data -->
  <Param name="viewer">
    /people/@viewer/@self
  </Param>
  <!-- key "friends", fetch the viewer data -->
  <Param name="friends">
    /people/@viewer/@friends?count=20
  </Param>
</Optional>

Note: the method is GET.  POST/PUT/DELETE cannot be preloaded.

A big problem with this syntax: just as the <Preload> entry supports
"views" entry, this needs to as well.  I don't see an obvious way to
shoehorn this into the existing Gadget spec.  Is there any support for
per-view features?  A "views" attribute on features would be useful
here.

Javascript API:

/**
 * Gets any data requested with the "OpensocialPreload" feature.
 *
 * @return {opensocial.DataResponse} returns any data requested for
 *    preloading
 */
opensocial.getPreloadData() { ... }

Regards,
Adam Winer

Re: Feature proposal: OpensocialPreload

Posted by Adam Winer <aw...@google.com>.
Agreed, we need to converge in the OpenSocial spec.  Obviously,
template-internal markup like os:DataSet won't apply more generically, but
analogous syntax in <ModulePrefs> could.  I'll get a thread started in the
OpenSocial spec group.
On Thu, Aug 14, 2008 at 10:29 AM, David Byttow <da...@google.com>wrote:

> Hi Adam,
>
> I think that this is probably a good general solution for preloading data,
> but you should definitely take a look at the current proposal for
> DataPipelining within the OpenSocial Templates domain (
>
> http://wiki.opensocial-templates.org/index.php?title=OpenSocial_Data_Pipelining
> ).
> We have been discussing the need for a special <os:DataSet> markup which
> can
> be processed either on the server or the client (to stay inline with the
> concept of client/server agnostic processing of templates). This markup has
> all kinds of advantages, which are beyond the scope of shindig-dev. In
> addition to the spec, you can also read up on the ongoing discussions
> regarding OpenSocial Templates and data pipelining on on the
> os-templates@yahoogroups.com mailing list.
>
> I'd like to see how we can align these efforts if at all possible.
>
> David
>
> On Thu, Aug 14, 2008 at 8:49 AM, Adam Winer <aw...@google.com> wrote:
>
> > In the Orkut OpenSocial implementation (pre-Shindig), we have an
> > existing OpenSocial API prefetcher that has proven extremely useful in
> > reducing latency from initial API requests.  Our existing Orkut
> > implementation:
> >  - records incoming API requests
> >  - uses those records to statistically guess what API calls a
> >    gadget makes when first rendering
> >  - fetches the data for those API calls, and inserts the data
> >    into the gadget
> >  - transparently intercepts items within the first
> >    newDataRequest() call and uses the preloaded result instead,
> >    with no HTTP round-trip if all items are present
> >
> > This technique successfully delivers content to ca. 90% of gadget
> > renders, with another 7% or so gadgets that do not make OpenSocial
> > data requests at all.  Overall, this eliminates more than 2 out of
> > every 3 data requests in production.
> > I've been thinking over how to bring it into Shindig, and would like
> > to start with a declarative approach via an optional feature,
> > OpensocialPreload.  Statistical sampling would be a follow-on
> > implementation detail to provide a similar optimization for those
> > not declaratively specifying the feature (though I'm happy to share
> > more details on how it could work.)
> >
> > XML:
> > <Optional feature="OpensocialPreload">
> >  <!-- key "viewer", fetch the viewer data -->
> >  <Param name="viewer">
> >    /people/@viewer/@self
> >  </Param>
> >  <!-- key "friends", fetch the viewer data -->
> >  <Param name="friends">
> >    /people/@viewer/@friends?count=20
> >  </Param>
> > </Optional>
> >
> > Note: the method is GET.  POST/PUT/DELETE cannot be preloaded.
> >
> > A big problem with this syntax: just as the <Preload> entry supports
> > "views" entry, this needs to as well.  I don't see an obvious way to
> > shoehorn this into the existing Gadget spec.  Is there any support for
> > per-view features?  A "views" attribute on features would be useful
> > here.
> >
> > Javascript API:
> >
> > /**
> >  * Gets any data requested with the "OpensocialPreload" feature.
> >  *
> >  * @return {opensocial.DataResponse} returns any data requested for
> >  *    preloading
> >  */
> > opensocial.getPreloadData() { ... }
> >
> > Regards,
> > Adam Winer
> >
>

Re: Feature proposal: OpensocialPreload

Posted by David Byttow <da...@google.com>.
Hi Adam,

I think that this is probably a good general solution for preloading data,
but you should definitely take a look at the current proposal for
DataPipelining within the OpenSocial Templates domain (
http://wiki.opensocial-templates.org/index.php?title=OpenSocial_Data_Pipelining).
We have been discussing the need for a special <os:DataSet> markup which can
be processed either on the server or the client (to stay inline with the
concept of client/server agnostic processing of templates). This markup has
all kinds of advantages, which are beyond the scope of shindig-dev. In
addition to the spec, you can also read up on the ongoing discussions
regarding OpenSocial Templates and data pipelining on on the
os-templates@yahoogroups.com mailing list.

I'd like to see how we can align these efforts if at all possible.

David

On Thu, Aug 14, 2008 at 8:49 AM, Adam Winer <aw...@google.com> wrote:

> In the Orkut OpenSocial implementation (pre-Shindig), we have an
> existing OpenSocial API prefetcher that has proven extremely useful in
> reducing latency from initial API requests.  Our existing Orkut
> implementation:
>  - records incoming API requests
>  - uses those records to statistically guess what API calls a
>    gadget makes when first rendering
>  - fetches the data for those API calls, and inserts the data
>    into the gadget
>  - transparently intercepts items within the first
>    newDataRequest() call and uses the preloaded result instead,
>    with no HTTP round-trip if all items are present
>
> This technique successfully delivers content to ca. 90% of gadget
> renders, with another 7% or so gadgets that do not make OpenSocial
> data requests at all.  Overall, this eliminates more than 2 out of
> every 3 data requests in production.
> I've been thinking over how to bring it into Shindig, and would like
> to start with a declarative approach via an optional feature,
> OpensocialPreload.  Statistical sampling would be a follow-on
> implementation detail to provide a similar optimization for those
> not declaratively specifying the feature (though I'm happy to share
> more details on how it could work.)
>
> XML:
> <Optional feature="OpensocialPreload">
>  <!-- key "viewer", fetch the viewer data -->
>  <Param name="viewer">
>    /people/@viewer/@self
>  </Param>
>  <!-- key "friends", fetch the viewer data -->
>  <Param name="friends">
>    /people/@viewer/@friends?count=20
>  </Param>
> </Optional>
>
> Note: the method is GET.  POST/PUT/DELETE cannot be preloaded.
>
> A big problem with this syntax: just as the <Preload> entry supports
> "views" entry, this needs to as well.  I don't see an obvious way to
> shoehorn this into the existing Gadget spec.  Is there any support for
> per-view features?  A "views" attribute on features would be useful
> here.
>
> Javascript API:
>
> /**
>  * Gets any data requested with the "OpensocialPreload" feature.
>  *
>  * @return {opensocial.DataResponse} returns any data requested for
>  *    preloading
>  */
> opensocial.getPreloadData() { ... }
>
> Regards,
> Adam Winer
>

Re: Feature proposal: OpensocialPreload

Posted by Adam Winer <aw...@google.com>.
On Thu, Aug 14, 2008 at 9:53 AM, Kevin Brown <et...@google.com> wrote:

> Overall, I like this idea, but I have a few comments:
>
> On Thu, Aug 14, 2008 at 8:49 AM, Adam Winer <aw...@google.com> wrote:
>
> > In the Orkut OpenSocial implementation (pre-Shindig), we have an
> > existing OpenSocial API prefetcher that has proven extremely useful in
> > reducing latency from initial API requests.  Our existing Orkut
> > implementation:
> >  - records incoming API requests
> >  - uses those records to statistically guess what API calls a
> >    gadget makes when first rendering
> >  - fetches the data for those API calls, and inserts the data
> >    into the gadget
> >  - transparently intercepts items within the first
> >    newDataRequest() call and uses the preloaded result instead,
> >    with no HTTP round-trip if all items are present
> >
> > This technique successfully delivers content to ca. 90% of gadget
> > renders, with another 7% or so gadgets that do not make OpenSocial
> > data requests at all.  Overall, this eliminates more than 2 out of
> > every 3 data requests in production.
> > I've been thinking over how to bring it into Shindig, and would like
> > to start with a declarative approach via an optional feature,
> > OpensocialPreload.  Statistical sampling would be a follow-on
> > implementation detail to provide a similar optimization for those
> > not declaratively specifying the feature (though I'm happy to share
> > more details on how it could work.)
> >
> > XML:
> > <Optional feature="OpensocialPreload">
> >  <!-- key "viewer", fetch the viewer data -->
> >  <Param name="viewer">
> >    /people/@viewer/@self
> >  </Param>
> >  <!-- key "friends", fetch the viewer data -->
> >  <Param name="friends">
> >    /people/@viewer/@friends?count=20
> >  </Param>
> > </Optional>
> >
> > Note: the method is GET.  POST/PUT/DELETE cannot be preloaded.
> >
> > A big problem with this syntax: just as the <Preload> entry supports
> > "views" entry, this needs to as well.  I don't see an obvious way to
> > shoehorn this into the existing Gadget spec.  Is there any support for
> > per-view features?  A "views" attribute on features would be useful
> > here.
>
>
> It probably would be, but that's beyond the scope of Shindig :)


Yes, I know...  I was torn about whether to post this to the opensocial spec
first or shindig-dev.  I'll initiate a spec conversation today.


>
> >
> >
> > Javascript API:
> >
> > /**
> >  * Gets any data requested with the "OpensocialPreload" feature.
> >  *
> >  * @return {opensocial.DataResponse} returns any data requested for
> >  *    preloading
> >  */
> > opensocial.getPreloadData() { ... }
>
>
> This is just an implementation detail, so it shouldn't be published as a
> public opensocial method. I'd suggest attaching it to opensocial in the
> same
> way that we attach the data to gadgets.io for HTTP Preloads.


Yeah, I considered that.  It has one major advantage - it's exactly how the
statistical sampling approach works - but had two reasons why I didn't go
that way.

First, it requires careful reconciliation of the URLs generated by the JS
with the declaratively specified URLs.  An example URL I gave above is:

  /people/@viewer/@self

The actual URL that Shindig's Javascript generates today is

  /people/@viewer/@self?fields=id,name,thumbnailUrl&startIndex=0&count=20&orderBy=topFriends&filterBy=all

Normalizing URLs on the client to allow for comparison seems painful.  (For
statistical sampling, it's not, because you're sample is of the actual
generated URLs.)

Second, as long as this is implicit, you have to be careful with the
lifetime for the prefetched data, akin to a cache;  don't return cached
get-app-data after a set-app-data call, etc.  That concern goes away with an
explicit call.  (The semantic I've used for statistical sampling is that
prefetched data can only be substituted for the first API request.)

-- Adam



>
>
>
> >
> >
> > Regards,
> > Adam Winer
> >
>

Re: Feature proposal: OpensocialPreload

Posted by Kevin Brown <et...@google.com>.
Overall, I like this idea, but I have a few comments:

On Thu, Aug 14, 2008 at 8:49 AM, Adam Winer <aw...@google.com> wrote:

> In the Orkut OpenSocial implementation (pre-Shindig), we have an
> existing OpenSocial API prefetcher that has proven extremely useful in
> reducing latency from initial API requests.  Our existing Orkut
> implementation:
>  - records incoming API requests
>  - uses those records to statistically guess what API calls a
>    gadget makes when first rendering
>  - fetches the data for those API calls, and inserts the data
>    into the gadget
>  - transparently intercepts items within the first
>    newDataRequest() call and uses the preloaded result instead,
>    with no HTTP round-trip if all items are present
>
> This technique successfully delivers content to ca. 90% of gadget
> renders, with another 7% or so gadgets that do not make OpenSocial
> data requests at all.  Overall, this eliminates more than 2 out of
> every 3 data requests in production.
> I've been thinking over how to bring it into Shindig, and would like
> to start with a declarative approach via an optional feature,
> OpensocialPreload.  Statistical sampling would be a follow-on
> implementation detail to provide a similar optimization for those
> not declaratively specifying the feature (though I'm happy to share
> more details on how it could work.)
>
> XML:
> <Optional feature="OpensocialPreload">
>  <!-- key "viewer", fetch the viewer data -->
>  <Param name="viewer">
>    /people/@viewer/@self
>  </Param>
>  <!-- key "friends", fetch the viewer data -->
>  <Param name="friends">
>    /people/@viewer/@friends?count=20
>  </Param>
> </Optional>
>
> Note: the method is GET.  POST/PUT/DELETE cannot be preloaded.
>
> A big problem with this syntax: just as the <Preload> entry supports
> "views" entry, this needs to as well.  I don't see an obvious way to
> shoehorn this into the existing Gadget spec.  Is there any support for
> per-view features?  A "views" attribute on features would be useful
> here.


It probably would be, but that's beyond the scope of Shindig :)


>
>
> Javascript API:
>
> /**
>  * Gets any data requested with the "OpensocialPreload" feature.
>  *
>  * @return {opensocial.DataResponse} returns any data requested for
>  *    preloading
>  */
> opensocial.getPreloadData() { ... }


This is just an implementation detail, so it shouldn't be published as a
public opensocial method. I'd suggest attaching it to opensocial in the same
way that we attach the data to gadgets.io for HTTP Preloads.


>
>
> Regards,
> Adam Winer
>