Proposal for 0.8 : Faster method to check if two users are friends

19 views
Skip to first unread message

Louis Ryan

unread,
Mar 28, 2008, 3:43:07 PM3/28/08
to opensocial-an...@googlegroups.com
All,

This issue was raised by a gadget developer

The PhotoAttack app restricts attacking to just friends - this is a wise product choice to avoid spam.

Say Abby attacks Bob.  Bob gets the attack but before he can attack back, the app needs to check if Abby is still Bob's friend.

Currently, the app needs to fetch all of Bob's friends and confirm that Abby is on that list before allowing Bob to attack her back.

Fetching all friends (upto 1000) is an expensive operation.  So, the ask is to support an IsFriend method.


It seems like this problem can be handled in a number of ways..

1. Implement a DataRequest.newFetchAreFriends(<user spec>,<user spec>, opt_callback)

2. Add support for a filter on DataRequest.newFetchPeoplerequest that computes the intersection of two user specs e.g.
     DataRequest.newFetchPeoplerequest(<id spec> , {..., intersect : <id spec>, ...})
   This would allow for checking if the viewer was the owner friend by
      DataRequest.newFetchPeoplerequest(OWNER_FRIENDS, {..., intersect : VIEWER ...})

In general I think I prefer the 2nd approach as its a more general pattern and has a lower impact on the API. It does however imply a general join facility that may be expense/difficult for containers to implement and enforce quota constraints on.

Thoughts?

-Louis
Orkut Team

Evan Gilbert

unread,
Mar 28, 2008, 3:53:14 PM3/28/08
to opensocial-an...@googlegroups.com
Would is make sense to have opensocial.Person.isFriend()? I forget if there were any good reasons to not have this in the original spec - seems like a useful addition.

Your 2nd option is useful anyway as mutual friends is often requested. But isFriend() might be easier.

Evan

Louis Ryan

unread,
Mar 28, 2008, 4:20:09 PM3/28/08
to opensocial-an...@googlegroups.com
It would have to be isViewerFriend() and isOwnerFriend(). The problem has to do with how the users are fetched.

If I fetched a set of Person objects using DataRequest.newFetchPeopl(VIEWER_FRIEND,...) would you expect calls on those Person objects to return the correct result for isOwnerFriend()? This is likely to be a performance impact for the container as you're exploding the friend graph: viewer friend -> viewer friend friend <- owner

We could return this data as field extensions on the Person objects and containers could be smart about avoiding the performance impact if they weren't requested but I think Id rather make these kind of joins explicit so it's clear to developers when they are taking the performance hit and they can manage their code to stay within quota.

Claude

unread,
Mar 29, 2008, 3:35:16 PM3/29/08
to OpenSocial and Gadgets Specification Discussion
How about the more general DataRequest.newFetchNetworkDistance(<user
spec>,<user spec>, opt_callback)?

This would return the number of friend-hops from the first user to the
second user (at Hyves we allow one-way friendships in certain cases).
Calculating network distance can be costly though, so containers are
allowed to give "more than x" as reply. In our traditional API, we
support distances of 0 (first and second user are the same user), 1
(friends), 2 (friends of friends) and "many". "Many" in our case
should be translated into "more than 2", since a gadget does not know
which maximum distance is supported by the container.

Cassie

unread,
Mar 31, 2008, 10:31:29 AM3/31/08
to opensocial-an...@googlegroups.com
Just to further define Louis' #2 option, I think something like this might work:

opensocial.DataRequest.PeopleRequestFields = {
// profileDetails, sortOrder, filter, etc
...
/**
 * Additional options to be passed into the Filter. Specified as a Map<String, Object>.
 */
FILTER_OPTIONS: 'filterOptions'
...
}

opensocial.DataRequest.FilterType = {
// currently just all and hasApp
...
/**
 * Will filter the people requested by checking if they are friends with
 * the given idSpec. Expects a filterOptions parameter to be passed with the following fields defined:
 *  - idSpec The idSpec that each person must be friends with.
 *  - networkDistance An optional parameter, used to specify how long the connection can be for
 *     two people to be considered friends. Defaults to 0 (they must directly be friends).
 *     As an example, 1 would mean "friend of a friend".
*/
IS_FRIENDS_WITH: 'isFriendsWith'
}


By just adding those two enums, we can then support all of these:

req.newFetchPeopleRequest('OWNER_FRIENDS', {filter: 'IS_FRIENDS_WITH', filterOptions : {'idSpec' : 'VIEWER'}})
req.newFetchPeopleRequest('VIEWER_FRIENDS', {filter: 'IS_FRIENDS_WITH', filterOptions : {'idSpec' : OWNER'}})
req.newFetchPeopleRequest('OWNER_FRIENDS', {filter: 'IS_FRIENDS_WITH', filterOptions : {'idSpec' : 'VIEWER', networkDistance: 2}}) // I just made this last thing up, but you could see how it could perhaps be used for the # of friend hops as discussed by Claude

Thoughts?
(Oh, and the isFriendsWith filter could probably use a better name...)

- Cassie

Louis Ryan

unread,
Mar 31, 2008, 1:09:04 PM3/31/08
to opensocial-an...@googlegroups.com
Looks good. We could use VIEWER/OWNER_FRIENDS_OF_FRIENDS etc as idSpecs rather than arbitrary distance to limit the graph expansion. This would also prevent expansions across large IdSpec sets which would be very expensive.

Cassie

unread,
Mar 31, 2008, 1:21:01 PM3/31/08
to opensocial-an...@googlegroups.com
True... but you, as a container, can just refuse to support any large calculations you don't want to make...(maybe just networkDistance = 0 || 1) while at the same time other containers can choose that network expansion is their primary goal in life and can use the same api.

Or, would people rather have an explicit api with FRIENDS_OF_FRIENDS etc?
Please vote!

- Cassie

Arne Roomann-Kurrik

unread,
Mar 31, 2008, 4:44:10 PM3/31/08
to opensocial-an...@googlegroups.com
+1 IS_FRIENDS_WITH with the networkDistance parameter limited by a container's policy.  This feels more expressive, as it could potentially allow filtering by "friend of <arbitrary id>", while it still allows containers to block expensive operations in line with what Louis suggested.

~Arne
--
OpenSocial IRC - irc://irc.freenode.net/opensocial

Claude

unread,
Apr 1, 2008, 6:53:55 AM4/1/08
to OpenSocial and Gadgets Specification Discussion
+1
I would suggest the networkDistance to be the number of hops though,
so one higher than the current spec. 0 would mean the user self, 1 is
friends, 2 is friends of friends. It seems more logical, since a 2nd
degree network means friends of friends, I think? It should then
default to 1

req.newFetchPeopleRequest('OWNER_FRIENDS', {filter: 'IS_FRIENDS_WITH',
filterOptions : {'idSpec' : 'VIEWER', networkDistance: 0}})
would retrieve the viewer only if he is the owner (perhaps not that
useful, we can probably leave this out of the spec.)

req.newFetchPeopleRequest('OWNER_FRIENDS', {filter: 'IS_FRIENDS_WITH',
filterOptions : {'idSpec' : 'VIEWER', networkDistance: 1}})
would retrieve the viewer only if he is the owners friend

req.newFetchPeopleRequest('OWNER_FRIENDS', {filter: 'IS_FRIENDS_WITH',
filterOptions : {'idSpec' : 'VIEWER', networkDistance: 2}})
would retrieve the viewer only if he is the owners friend of friends

It should be clear that networkDistance is the maximum distance, not
the exact distance between two members. By definition, a user is
therefor always friends with himself.

On Mar 31, 7:21 pm, Cassie <d...@google.com> wrote:
> True... but you, as a container, can just refuse to support any large
> calculations you don't want to make...(maybe just networkDistance = 0 || 1)
> while at the same time other containers can choose that network expansion is
> their primary goal in life and can use the same api.
>
> Or, would people rather have an explicit api with FRIENDS_OF_FRIENDS etc?
> Please vote!
>
> - Cassie
>
> On Mon, Mar 31, 2008 at 7:09 PM, Louis Ryan <lr...@google.com> wrote:
> > Looks good. We could use VIEWER/OWNER_FRIENDS_OF_FRIENDS etc as idSpecs
> > rather than arbitrary distance to limit the graph expansion. This would also
> > prevent expansions across large IdSpec sets which would be very expensive.
>
> > > On Sat, Mar 29, 2008 at 9:35 PM, Claude <claude.claude...@gmail.com>

Cassie

unread,
Apr 14, 2008, 9:18:05 AM4/14/08
to opensocial-an...@googlegroups.com
Claude - that sounds good. Note that if the general people fetching
proposal gets accepted:
http://groups.google.com/group/opensocial-and-gadgets-spec/browse_thread/thread/6b2ba00f8a38cb45

Then the networkDistance param will be moved inside the idSpec object
and won't be needed as a parameter here.

Okay, so given Claude's change it seems like Arne and Claude are on
board and maybe Louis.
Anybody else want to chime in?

Thanks.
- Cassie

Dan Peterson

unread,
Apr 24, 2008, 7:40:25 PM4/24/08
to opensocial-an...@googlegroups.com
+1 -- seems much easier to allow developers to get this functionality into their gadgets

-Dan

On Mon, Apr 14, 2008 at 6:18 AM, Cassie <do...@google.com> wrote:

Claude - that sounds good. Note that if the general people fetching
proposal gets accepted:
http://groups.google.com/group/opensocial-and-gadgets-spec/browse_thread/thread/6b2ba00f8a38cb45

Then the networkDistance param will be moved inside the idSpec object
and won't be needed as a parameter here.

Okay, so given Claude's change it seems like Arne and Claude are on
board and maybe Louis.
Anybody else want to chime in?

Thanks.
- Cassie

Lane LiaBraaten

unread,
Apr 24, 2008, 7:58:25 PM4/24/08
to opensocial-an...@googlegroups.com
+1

Cassie

unread,
Apr 25, 2008, 7:08:43 AM4/25/08
to opensocial-an...@googlegroups.com
Approved for 0.8
- Cassie
Reply all
Reply to author
Forward
0 new messages