Code Monkey home page Code Monkey logo

cacheman's Introduction

cayasso

Jonathan Brumley Lennon

Installation

$ npm i cayasso

License

(The MIT License)

Copyright (c) 2016 Jonathan Brumley <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

cacheman's People

Contributors

appleboy avatar bushev avatar cayasso avatar dantman avatar eknkc avatar englercj avatar euank avatar lpinca avatar maxwellrebo avatar pwlmaciejewski avatar ratson avatar theworkflow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cacheman's Issues

Issue return promise from get

Hello:
I am using callback version of get

return new Promise(resole,reject)
{
cache.get('foo', function (err, value) {
 if(err)
{
reject(err);
} 
else
{
 resolve(value)
}
});
}

But it gives BlueBird warning Warning: a promise was created in a handler but none were returned from it here.

Then I tried the get with promise

function(){
return cache.get('foo')
}

Here I get then() is not defined.
I am not sure what am I doing wrong here. Can you please help me in this.
Thanks,
Ashwani

Large TTL values

  1. Is it okay (reliable) to set TTL to as large as '12h' or '1d'?
  2. What is the longest recommended TTL value?

Cache with fuzzy logic

Hi everyone!

Currently I'm building a wrapper based on Cacheman that supports fuzzy logic to make a flush of data. I don't know if it could be part of a new feature of Cacheman. I did an example to accomplish that, but would be nice to have in this library.

var Cacheman = require('cacheman');
var fuzzylogic = require('fuzzylogic');

// Set more info to make fuzzy logic
(function (set) {
    Cacheman.prototype.set = function (key, data) {
      var info = {
        key: key,
        cached_time: Date.now(),
        expiration_time: Date.now() + (this._ttl * 1000)
      };

      // Send info to Redis
      this._engine.set(this.key(key) + ':info', info, 86400);

      return set.apply(this, arguments);
    };
})(Cacheman.prototype.set);

// Fuzzy logic
(function (get) {
    Cacheman.prototype.get = function (key) {
      this._engine.get(this.key(key) + ':info', function (err, info) {
        if (info) {
          var timelapse = this._ttl * 1000;

          var half = timelapse / 2;
          var qrt = half / 2;
          var mid_time = info.cached_time + half + qrt;

          var request_time = Date.now();

          var fuzzy = fuzzylogic.trapezoid(request_time, info.cached_time, info.cached_time, mid_time, info.expiration_time);
          var valid = !!Math.round(fuzzy);

          if (!valid) {
            console.log('Flushed!');
            this.del(key);
            this._engine.del(this.key(key) + ':info')
          } else {
            console.log(fuzzy, valid);
          }
        }
      }.bind(this));

      return get.apply(this, arguments);
    };
})(Cacheman.prototype.get);


/* Example */

var cacheHandler = new Cacheman('test', {
  ttl: 10, // 10 seconds
  engine: 'redis',
  port: 6379,
  host: 'localhost'
});

var testCache = function () {
  cacheHandler.get('mykey', function (err, value) {
    if (!value) {
      cacheHandler.set('mykey', { foo: 'bar' }, function (err, value) {
        console.log(value);
      });
    }
  });
};

setInterval(testCache, 250);
testCache();

What do you think?

Override constructor TTL?

Hey there!

Is it possible to pass a different TTL which will override whatever was set in the constructor?

We want to keep most things in cache for 24-hours but there are some items which should be kept for a much shorter duration. We instantiate cacheman by simply doing

var cache = new Cacheman({ttl:config.cacheTTL}); // config.cacheTTL = 24hours

When I try to do a cache.set(key, data, ttl) ... it seems as if the TTL I pass here is ignored. Am I doing something wrong or does cacheman not support this functionality?

Thanks!

multiple engines

I'd like to be able to use multiple engines for the same query:

  • fetch from memory if found
  • otherwise fetch from Redis
  • otherwise fetch from MongoDB
  • otherwise fetch from an external API

It still has duplicate prefix in the actual Redis DB

The latest version still has the duplicate prefix issue, not in the cacheman object (ie. cache._prefix) but in the actual redis DB.

ie.  cacheman:todo:cacheman:todo:myKey

the problem is that when initializing the engine (e.g. cacheman-redis). prefix is passed in.

and when doing the operations, e.g. set/get/del, it will run this.key(key) before calling the engine's operation, which it will set the prefix again.

e.g. line 280 on lib/index.js
 this._engine.set(this.key(key), data, ttl || this._ttl, fn);

so either do not set the prefix to the engine.
or this.key() do not append the prefix.

Wrap cache.get in setInterval()?

Hello there!

I am trying to check the cache every 100ms until I find the update I am expecting to be there. For some reason the following code never resolves, is this something I am doing wrong or is there a better way for me to implement this type of solution?

exports.getCurrentValue = function(key) {
  console.log("In getCurrentValue Function:");

  return new Promise(function(resolve, reject) {
    var checkCache = function() {
      var time = new Date().valueOf();

      var interval = setInterval(function() {
        return cache.get(key)
          .then(function(value) {
            console.log("Checking cache...");
            console.dir(value);
            console.log("COMPARE: " + time + " -- " + value.time);
            if(typeof value != 'undefined' && value.time > time) {
              console.log("CONDITIONS MET");
              clearInterval(interval);
              return value;
            }
          });
      }, 100);
    }    

    checkCache()
      .then(function(value) {
        console.log("should be about to resolve..."); // This log never fires
        resolve(value);
      });
  });
}

I really appreciate your insight and this great library!

Is the project still alive ?

Hello @cayasso , I'm using your project in some of mines, and it seems this repo is not updated from start of 2018, some issues are open withtout answers, and some pull requests just waiting .

Did you plan to continue to work on this project ?

The project is working great, just to know if I take some time to try to improve this project (like doing the typing), or if the pull request will just wait years :/ ...

Regards,

Not necessarily an issue, just can't see a good use case for allowing undefined as a key.

Had an issue with our backend where cacheman was caching things with bad keys (null and even undefined) without complaint. Doing a fetch on null or undefined would return the most recent value, but I'm uncertain of the value of this behavior in general or if cacheman should at least complain a little. It seems unintuitive that an undefined key would work at all.

I added some middleware to catch strange keys, but is there a reason to allow this in the first place?

Get list of keys

Hello:
Is there any way I can get the list of keys currently present in the memory?

Not an issue.

This library just saved my day - epic work sir.
Thanks!

hit/miss debug statements

I think it would be good to use debug to provide opt-in hit/miss/set lines for debugging.

Should we do this as part of cacheman? Assuming that all undefined results are misses.

Or should we do this as part of each of the engines? Which do know about misses.

Occasionally create duplicate prefix cachecache:MYCACHENAME:

Sometimes, it creates the cache key as:
cachecache:mycachename:
instead of
cache:mycachename:

because when creating the Cacheman object, he option.prefix is used for both option._prefix (i.e. cache:mycachename: ) and the engine (Redis) prefix, and the default is "cache".

so occasionally, in RedisClient, before issuing command, this.options.prefix is "cache", and it will append that to the agruments, which is "cache:mycachename", and becomes cachecache:mycachename:

better to have another options just for engine's prefix.

Accept array keys

The options already has a delimiter option and uses it when setting the cache prefix.

Allowing key to be an array and if so joining it using the delimiter would make sense.

Test problems with dependency modules

Hi there,

thanks for your nice implementation. I think a found a problem with testing.

After browsing your test code i found an issue with testing dependency modules. You execute tests which should already be tested in the depedency module itself (like testing cacheman-mongodb engine). The problem is that if i do not have any mongodb/redis or other db instance on my test maschine i am not able to execute the tests successfully.

Another problem is that testing the dependency modules is like testing a database driver. I think the cacheman module tests should only test cacheman code itself and not the code of the dependency modules.

What do you think?

Add increment option.

Both mongodb and redis support an increment. It would be nice to have something similar here.
Specifically I am wanting to use cacheman to implement a rate limiter but without increment it's impossible to do so.

May be out of scope for the module but I thought it'd be cool.

Add socket option

In redis client you can connect directly via socket with the { path: "" } option for createClient.
It would be nice if you could do the same for cacheman

Proposal: Get many keys

I'm looking for a way to cache some things in a mongodb environment. But I need to retrieve many keys at the same time, 50 more or less. I know this is posible with in mongo, using the $in operator, in redis maybe with the HMGET and memory with multiple search. I didn't understand how the file one works, but I guess is not that hard to get from file multiple keys.

If you are ok with the idea, I could fork and do some pull requests

allow to pass ttl in callback of wrapped function

sometimes the lookup of a value will also yield its expiration time. It would be nice that the callback of the work function allows for a third ttl param, for example :

function work(callback) {
  callback(null, { a: 'foo' }, '10s');
}

cache.wrap('foo', work, function (err, data) {
  console.log(data); //-> {a: 'foo'}
});

am not sure how this would work for Promises?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.