Needs work
Project:
Drupal for Facebook
Version:
6.x-3.0-rc8
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
8 Mar 2011 at 21:16 UTC
Updated:
10 Mar 2011 at 08:22 UTC
Facebook sdk api call function support polymorphic arguments. The fb_api function in fb module doesn't implement that. Here is new fb_api function that support that:
/**
* Simple wrapper around $fb->api() which caches data.
*
* This is intended to avoid performace problems when, for example,
* $fb->api('me') is called several times in a single request.
*/
function fb_api(/* polymorphic */) {
static $cache;
$fb = $GLOBALS['_fb'];
if (!$fb) {
return;
}
if (!isset($cache)) {
$cache = array();
}
$func_args = func_get_args();
$key = serialize($func_args);
if (!isset($cache[$key])) {
$cache[$key] = call_user_func_array(array($fb, 'api'), $func_args);
}
return $cache[$key];
}
Please, test and add it to the fb module.
Comments
Comment #1
Dave Cohen commentedThe cache key should not be serialized. Each ID passed in should be stored individually, and ideally it would check each ID against the cache before calling $fp->api.
Remember, you can always call $fb->api() instead of fb_api(). You just wont get the caching. If youre careful about calling it, that won't matter.
Comment #2
oc666 commentedThe serialize is for cases when the fb->api need more than one argument. So, the serialize make this easy, and it's unique. That way, you can get unique cache key for multi-arguments function. Additionally, you get caching for the multi-arguments call and single argument as well.
For example, if you send argument 'me' to the function, the use 'me' string as a key is the same as the use of serialize(array('me')). You can check it yourself. It is the same if you send more than one argument.
The fb module should be full implemented for the facebook php-sdk, so this is drupal layer for facebook, so I think the use of fb_api instead of $fb->api is better, cause $fb is private for the layer (like object). The evidence for that is that the $fb source is $GLOBALS['_fb'] (the underline prefix of the variable means private property in object oriented programming).
I'm using the next code (after patching the fb module with function above) for creating album:
and it's working perfect.
Comment #3
Dave Cohen commentedThe problem with the serialized key is this...
Let's say the first query is for IDs 'me' and '1234'. It won't use the cache because its the first query.
Next query is for just 'me'. It won't use the cache because 'me' does not exactly match the serialized key. In this case it should use the cache because we already queried for 'me'.
Next query is for '1234' and 'me'. Again, it will not use the cache because the serialized key has a different order. But again it should use the cache.
So the cache in your patch is only useful when you have the exact same IDs in the exact same order, which is unlikely.
I disagree. Why create a layer that is just drupal-specific but adds nothing else? Facebook changes their APIs all the time and it would just be a lot of work for no gain. The reason to use fb_api() instead of $fb->api() is for the caching, as described in the comments in the code.
Comment #4
oc666 commentedFirst of all, If someone call function with different order of arguments, it should behave differently. Polymorphic function should behave exactly like regular function, although, in this function the output would be the same but the caching would be differently.
Second, you could fix the problem you describe if you sort the array before serialize.
From the fb module:
This module should be a platform, so we need to supply Drupal API for that. One that develop via this module doesn't know what is exactly $GLOBAL['_fb'] unless he study the code.