Use GreaseMonkey’s persistent data functions as a aged Cache.

GreaseMonkey (Don’t know that GreaseMonkey is the greatest thing since slice bread? See Greasemonkey) has two persistent data function’s, GM_setValue and GM_getValue, which let you set and get values. See Mark Pilgrams excellent Dive Into Greasemonkey : Storing and retrieving persistent data for more details. (even better, go to GreaseSpot and it’s api wiki).

UPDATE : Revised

All well and good, but I wanted to store some data there (the results of a AJAX GET request), but didn’t want to store ithem forever just for a day or two or at least a couple of hours.

and so I “created” 2 functions, GM_setCachedDataValue and GM_getCachedDataValue, which allow use of the GM persistent data function’s as a aged Cache! This allows me to “say” get me this value, unless it is older that X milliseconds old.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* GM_setCachedDataValue set the value, using the key name, and the cacheDate for the value based on the current datetime.
* to see the values set use about:config in the firefox awsome bar and filter with greasemonkey.scriptvals.http://www.FollowRank.com/
* @param {String} key  The key argument is a string of no fixed format.  Required.
* @param {Object} value The value argument can be a string, boolean, or integer. Required.
* @returns void
*
*/

function GM_setCachedDataValue(key, value){
// key is the name of the value stored
// value is the value to be stored
var currentTime = new Date().valueOf();
var raw = currentTime.valueOf();
GM_setValue(key, value);
GM_setValue(key + '_cacheDate', raw.toString());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* GM_getCachedDataValue returns the value indicated by the key if a) it exists, b) if it is less the maxDuration milliseconds old; otherwise return a blank.
* @param {String} key key is the name of the value stored. key argument is a string of no fixed format.  Required.
* @param {Number} maxDuration is the  Maximum Duration (or how old) in milliseconds the cached data can be. maxDuration is a number. Required.
* @returns a Integer, String or Boolean
*/

function GM_getCachedDataValue(key, maxDuration){
// key is the name of the value stored
// maxDuration is Maximum Duration (or how old) in milliseconds the cached data can be
// note fillter for  about:config is greasemonkey.scriptvals.http://www.FollowRank.com/
if (typeof maxDuration != "number") {
console.error('maxDuration is NOT a number, but rather a ' + typeof maxDuration);
return "";
}
var currentTime = new Date();
var raw = GM_getValue(key + '_cacheDate', ""); // get the age of the cache
if (raw != "") {
var cache_dt = new Date(parseInt(raw));
var age = currentTime.getTime() - cache_dt.getTime();
var allowed_age = maxDuration;
1
2
3
4
5
6
7
8
9
10
11
12
 if (age < = allowed_age) {
// if the age is less than the max allowed age the get and return the cached value
return GM_getValue(key, "");
}
else {// if the age is greater than the max then blank out the cache date and value and return black
GM_setValue(key, "");
GM_setValue(key + '_cacheDate', "");
console.info('GM cahaced data was too old so I killed it! Age was = ' + age + ' and allowed aged was =' + allowed_age);
}
}
return "";
}

How to use this :

before doing my Ajax request I check my aged cahce to see if the value is there and is no older (in milliseconds) that a given age. If it returns a non blank value that take that as the value and proceed, otherwise assume that it is either non there or a stale value, in either case that means I have to fetch fresh data which then needs to be stored. Clear as mud?

here is a sample javascript code to show how to use it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var MaxCacheAge = 60 * 60 * 24 * 1000; // Max Age for the Cached data is 1 day in milliseconds
var tmp = GM_getCachedDataValue("LastRequest", MaxCacheAge);
if (tmp != "") {
LastRequest = eval(tmp);
}
else {
GM_xmlhttpRequest({
method: 'GET',
url: 'http://greaseblog.blogspot.com/atom.xml',
onload: function(response){
LastRequest = eval(response.responseText);
GM_setCachedDataValue("LastRequest", response.responseText);
},
onerror: function(response){
LastRequest = "";
console.error('ERROR' + response.status);
}
});
}

This is generally faster than waiting for the calling service to return the get request, and if that service has a throttle limit (for Twitter it is 150 requests per hour limit, see Rate limiting) it will (might) save you from hitting that too soon.

UPDATE : Revised

Leave a Reply