monmohan / dsjslib

A library implementing several standard data structures and utilities, in JavaScript. Its written and tested using Node.js which is the target platform.
MIT License
773 stars 68 forks source link

Enhance Loading cache #12

Open slorber opened 9 years ago

slorber commented 9 years ago

First of all thanks for this nice lib I did not know.

I was looking for an equivalent of Guava's LoadingCache for a while in js.

Browserify

Notice that your lib works fine in the browser (Browserify) and you can mention that on your readme. However it's better to only load the code we need: var Cache = require("dsjslib/lib/Cache");

Suppliers

Guava support a cache for a single object that would be nice to have in this lib.

See Supplier<Animal> singleAnimalCache = Suppliers.memoizeWithExpiration(animalFromDbSupplier(), 365, TimeUnit.DAYS);

This would remove the burden of managing timers like in this code:

function getHashtagSuggestions() {
    setTimeout(function() {
        exports.getHashtagSuggestionsMemoized = _.memoize(getHashtagSuggestions);
    },10000);
    //
    return ApiRequest({
        method: "GET",
        url: "/suggestions/hashtags"
    });
};

exports.getHashtagSuggestionsMemoized = _.memoize(getHashtagSuggestions);

Support promises

Many of us are currently using promise based libraries like Q and it would be nice to support promises in addition to regular callbacks.

See the boilerplate involded in my example:

function getUserSuggestions(categoryId) {
    return ApiRequest({
        method: "GET",
        url: "/suggestions/users/forCategory/" + categoryId
    });
};

var UserSuggestionsCache = new Cache({
    'maximumSize': 10,
    'expiresAfterWrite': 5,
    'loaderFunction': function cacheLoader(key,onCompleteCallback) {
        getUserSuggestions(key)
            .then(function(result) {
                onCompleteCallback(undefined,result);
            })
            .fail(function(err) {
                onCompleteCallback(err);
            })
            .done();
    }
});

exports.getUserSuggestionsMemoized = function getUserSuggestionsMemoized(categoryId) {
    return Q.Promise(function(resolve,reject) {
        UserSuggestionsCache.get(categoryId,function(err,value) {
            if (err) {
                reject(err);
            } else {
                resolve(value);
            }
        })
    });
};

I would like to be able to write

function getUserSuggestions(categoryId) {
    return ApiRequest({
        method: "GET",
        url: "/suggestions/users/forCategory/" + categoryId
    });
};

var UserSuggestionsCache = new Cache({
    'maximumSize': 10,
    'expiresAfterWrite': 5,
    'loaderFunction': getUserSuggestions
});

exports.getUserSuggestionsMemoized = function getUserSuggestionsMemoized(categoryId) {
    return UserSuggestionsCache.getPromise(categoryId);
};

Note that my ApiRequest here is simply a Q promise factory.

I guess you'd rather not introduce dependencies in your lib but maybe this can be put in a separate project or be added as an optional dependency?

monmohan commented 9 years ago

Hi there, Thanks for your suggestions. Unfortunately I am busy with another project right now and don't have cycles to spend here. Hopefully in some time I can come back to make some improvements. Thanks

slorber commented 9 years ago

Notice the Suppliers memoization is already implemented in this lib: https://github.com/medikoo/memoize