Giter Site home page Giter Site logo

peterbe / django-cache-memoize Goto Github PK

View Code? Open in Web Editor NEW
155.0 7.0 31.0 100 KB

Django utility for a memoization decorator that uses the Django cache framework.

Home Page: https://django-cache-memoize.readthedocs.io/

License: Mozilla Public License 2.0

Python 99.68% Shell 0.32%

django-cache-memoize's People

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

django-cache-memoize's Issues

Pickle error unsupported

I use Python3.8 with django 3.0.1

and i get the following error
unsupported pickle protocol: 5

File "C:\Users\U779\django_projects\8bit-apps\venv\lib\site-packages\cache_memoize_init_.py", line 131, in inner
result = cache.get(cache_key, MARKER)
File "C:\Users\U779\django_projects\8bit-apps\venv\lib\site-packages\django\core\cache\backends\db.py", line 51, in get
return self.get_many([key], version).get(key, default)
File "C:\Users\U779\django_projects\8bit-apps\venv\lib\site-packages\django\core\cache\backends\db.py", line 92, in get_many
value = pickle.loads(base64.b64decode(value.encode()))

Cache miss each time if used on class instance method

Looks like self param is being taken into account.
Current workaround that works is using empty args_rewrite list:

class MyClass(object):

    @cache_memoize(30, args_rewrite=lambda x: [])
    def get_data(self):
      #....

Automatically (with help) invalidate cache when code changes

Sometimes a change in the code should trigger the invalidation of the cache. The idea is to add the version optional parameter to cache_memoize, defaulting to None. Then the version, if not None, would be added to the cache key.

We could use it like this:

@cache_memoize(60)
def f(...):

Then we fix a bug in f and write:

@cache_memoize(60, version=1)

Another bug fixed (so many ๐Ÿ› ๐Ÿชฒ ) :

@cache_memoize(60, version=2) 

So, when the fixes are deployed the cache will be invalidated, instead of returning a wrong cached value.

Incomplete sdist

Hi,

in order to properly ship the package with Debian, could you please build a compelte sdist tarball, including:

  • license
  • docs
  • tests
  • pytest and tox config

Once done, please upload a (post-)release sdist to PyPI as well.

Thanks,
Nik

Feature Request: extra key components

Sometimes we know, that cache state should depend on some external data like some dependency last update datetime. It would be nice if extra args would be supported so one can pass smth like

@cache_memoize(60, extra=('foo', obj.pk, foo.unix_timestamp))
def foo(*args, **kwargs):
    return 42

This also solves #35

clear cache in different processing

I use celery to do something which take long time, and this func will change origin model. So I must clear the origin cache when the func is done.But I found call the cached method with ' _refresh=True' in celery processing can't clear main processing.How to clear this cache?

Arguments containing colons can be mis-cached

Since the default key construction uses a colon (:) to separate raw string values, strings arguments with colons in them can lead to mis-caching.

(If an argument is user input, this could theoretically be a security issue allowing an user to access the "wrong" object from the cache.)

POC โ€“ the assertion fails since only one call was made, since the cache key is a:b:c:bla for both invocations.

def test_colons():
    calls_made = []
    @cache_memoize(10)
    def fun(a, b, k="bla"):
        calls_made.append((a, b, k))
        return (a, b, k)

    fun('a:b', 'c')
    fun('a', 'b:c')
    assert len(calls_made) == 2

Add a license

Hey there,

I would like to use your package in a project but I noticed you don't have a license file.
would you consider adding a license to your repo to make it clear what the license terms are?

MIT is an often suggested choice if you aren't sure. :-)
See: https://choosealicense.com/

Thanks!

tox runs no tests

Not sure how or when this started (the tox.ini was cloned from somewhere) but running tox -e py36-django21 (for example) doesn't actually run the tests. It just manages to run python --version.

Also the docs don't need to be built for every version.

Issue new release on pypi

Can a new release be issued on pypi? The get_cache_key method is very useful for testing/debugging.

Release the package with Django 3.2 support

Hey, we are working on upgrading edX codebase to Django 3.2. This package is being used in the codebase but it isn't yet released with Django 3.2 support. Kindly consider releasing it with Django 3.2 support.
Thanks

"Dog-piling" prevention support

Under very heavy load when the cached version of that page expires or is missing, there may be sufficient concurrency that multiple workers will all attempt to evaluate the target function simultatenously. This could be "problematic".

Not sure about the best solution here, perhaps some very loose coupling with various locking mechanisms via a path.to.lock.method?

Does invalidate() return the new cached result?

Your README seems to imply that the invalidate() call doesn't return the new value:

>>> expensive_function(100, 200)
121
>>> exensive_function.invalidate(1, 200)
>>> expensive_function(1, 100)
89

โ€ฆ however a call with _refresh=True does:

>>> expensive_function(100, 200)
121
>>> expensive_function(100, 200, _refresh=True)
177
>>> expensive_function(100, 200)
177

Is this correct?

Update in bulk

I have a situation where I am caching records from remote API get requests. I would like to run a background task that fetches a list in bulk and primes the cache in bulk.

It would be useful if there was a helper for this like ".invalidate"

Perhaps cache_memoized_function.set(args, result)? And potentially cache_memoized_function.set_in_bulk([(args1, result1), (args2, result2), ..., (argsN, resultN)])

Right now to do this I need to hit the list api and then parse the results and rerun the memoized function. So I have to fetch the records twice in this case

Use func.__qualname__ instead of func.__name__

By using func.__qualname__ instead of func.__name__ we can apply the decorator to methods and get unique keys including the class' name.

For example if we have two classes with a method with the same name, and we apply @cache_memoize to both of them the same cache key will be used, unless we explicitly use prefix. But IMHO doing as suggested is a safe default.

Just noticed that for Python 2 this would require adding some dependency like https://pypi.org/project/qualname/

Also tag releases on Git

When packaging a python package for NixOS we prefer to run the tests to make sure our packaging works and we have a smoke test to notice when things go wrong.

The PyPi sdist package does not include tests, which is very reasonable. We would like to fetch the latest version directly from Git, which includes the test. However there are no tags to pinpoint the exact commits that were used for the PyPi releases.

Please add tags, if you can.

Why _refresh and invalidate doesn't work?

I'm using this package in django,like this:

class A(models.Model):
    @cache_memoize(300)
    def b(self, arg1='', arg2=None)
         return ...

And clear cache like this:

self.b(_refresh=True)
self.b.invalidate(self)

Both this two method can't clear the method b's cache.

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.