dsjslib icon indicating copy to clipboard operation
dsjslib copied to clipboard

Enhance Loading cache

Open slorber opened this issue 9 years ago • 2 comments

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?

slorber avatar Apr 13 '15 17:04 slorber

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

monmohan avatar Apr 15 '15 06:04 monmohan

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

slorber avatar Apr 27 '15 09:04 slorber