Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CI and Update Tested Versions #239

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

Andrew-Chen-Wang
Copy link
Contributor

@Andrew-Chen-Wang Andrew-Chen-Wang commented May 6, 2021

Fixes #241 as well

  • CI testing Django 3.2 would actually only test Django 3.2 because GitHub actions converted 3.0 to an integer and tax didn't read it correctly (testing on Django 3.2a according to the logs)
  • Updated Python and Django versions
  • Tested all 3 memcache backends

* CI testing Django 3.0 would actually only test Django 3.2 because GitHub actions converted 3.0 to an integer and tax didn't read it correctly (testing on Django 3.2a according to the logs)
* Updated Python and Django versions
@mahyard
Copy link

mahyard commented Aug 24, 2021

hi @jsocol
you may know that this interesting plugin is being used by the Open edX platform for rate-limiting user requests.
since the platform is about to be upgraded to utilize Django 3.2, I volunteered to make sure that django-ratelimit supports that version of django. I'm ready to contribute either to test or debug the code.
edx/upgrades#41

@Andrew-Chen-Wang
Copy link
Contributor Author

Andrew-Chen-Wang commented Aug 24, 2021

@mahyard I will finish updating this PR sometime in the next few hours for CI configuration; any bad tests will then be up to you and I'll add you as a contributor to the fork. (Sorry, just completely forgot about this PR 😅 )

@Andrew-Chen-Wang
Copy link
Contributor Author

@mahyard Django 3.2 is fully supported; no tests failed: https://github.com/Andrew-Chen-Wang/django-ratelimit/actions/runs/1163763411

@jsocol
Copy link
Owner

jsocol commented Aug 24, 2021

Thank you @mahyard for opening this and @Andrew-Chen-Wang for doing the polishing! Not the first time I've been caught by "x.0 gets parsed as the number x" 🤦

@mahyard
Copy link

mahyard commented Aug 24, 2021

Thank you @Andrew-Chen-Wang for your efforts on this commit
I think django-redis needs to be upgraded too. 4.10.0 doesn't support Django:: 3.
I believe that 5.0.0 could be your first option. I've already run tox successfully omitting python 3.9 and pypy36.

  py36-django22: commands succeeded
  py36-django31: commands succeeded
  py36-django32: commands succeeded
  py37-django22: commands succeeded
  py37-django31: commands succeeded
  py37-django32: commands succeeded
  py38-django22: commands succeeded
  py38-django31: commands succeeded
  py38-django32: commands succeeded
  py38-djangomain: commands succeeded
  congratulations :)

@mahyard
Copy link

mahyard commented Aug 24, 2021

I just found that CI tests pick the latest version of django-redis.
it should be the option in the tox.ini as well.

@Andrew-Chen-Wang
Copy link
Contributor Author

Andrew-Chen-Wang commented Aug 24, 2021

👍 One more thing to note. Django has deprecated python-memcached in favor of a the pylibmc. @jsocol do you want me to test both packages as seen here https://github.com/noripyt/django-cachalot or would the replacement of python-memcached with pylibmc suffice? Imo, replacing is good enough to me (the linked repo tests several possible cache and db backend, but this package prob doesn't need it).

ref:

@jsocol
Copy link
Owner

jsocol commented Aug 24, 2021

👍 One more thing to note. Django has deprecated python-memcached in favor of a the pylibmc. @jsocol do you want me to test both packages as seen here https://github.com/noripyt/django-cachalot or would the replacement of python-memcached with pylibmc suffice? Imo, replacing is good enough to me (the linked repo tests several possible cache and db backend, but this package prob doesn't need it).

Good to know! It's been a minute but is pylibmc the one that's a C-based extension, or am I confusing that with something else?

Basically, if there's a compelling reason people might have to continue running python-memcached (e.g. they are in a deployment where pylibmc is unavailable for a reason like C extensions aren't present) then I'd say both. But if there's no reason people would need to keep using python-memcached, then I think it's fine to just go with the new and shiny.

@Andrew-Chen-Wang
Copy link
Contributor Author

Andrew-Chen-Wang commented Aug 24, 2021

You can take a look at a comparison made by Pinterest here: https://github.com/pinterest/pymemcache#comparison-with-other-libraries

In other words, we'll be testing on two backends: pylibmc (yes you're guess was right; it's the C bindings one) and pymemcache, the true replacement library for python-memcached. pymemcache is a suitable replacement since it's written entirely in Python. Django has it natively supported via a cache backend but only in Django 3.2+.

So to me, the reason to keep testing python-memcached is for supporting Django 2.2 and 3.1. Deprecation timeline: https://www.djangoproject.com/download/ I guess I'll test on all three? There will prob be a lot of jobs being queued since we're tripling everything.

@Andrew-Chen-Wang
Copy link
Contributor Author

Andrew-Chen-Wang commented Aug 24, 2021

All memcache backends are now tested. pymemcache having some issues. Seems like it only doubled due to the replacement of a backend rather than an addition.

Not sure what to make of this. Using the real uri fails python-memcached but fake one doesn't. It seems like pymemcache and pylibmc expect valid connections? Idk how to resolve tbh:

@Andrew-Chen-Wang
Copy link
Contributor Author

@jsocol Memcached is failing on pymemcache (python-memcached's replacement) and pylibmc. A solution for now is that memcached support for the CacheFail tests are simply ignored if not using python-memcached since we don't know how users will configure their cache server failover strategy.

@@ -10,7 +10,7 @@ jobs:
memcached:
image: memcached
ports:
- 11211:11211
- 57823:11211
Copy link
Contributor Author

@Andrew-Chen-Wang Andrew-Chen-Wang Aug 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was intentionally set to 11211 so that the connection would fail by setting a LOCATION of a random free client port. Please revert the last two commits.

Copy link

@mahyard mahyard Aug 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my bad! all of yesterday I was doing nothing. I thought... never mind. I will revert it right now.

@mahyard
Copy link

mahyard commented Aug 27, 2021

@Andrew-Chen-Wang
both pylibmc and pymemcache throw an error on this line:

added = cache.add(cache_key, initial_value, period + EXPIRATION_FUDGE)

what if we put it in a try-except block to check the connection and decide whether/what we need to return?
I mean sth like this:

>>> from pylibmc import ServerDown, ConnectionError
>>> try:
...   added = cache.add(cache_key, initial_value, period + EXPIRATION_FUDGE)
... except (ServerDown, ConnectionError):
...   #here we can handle connection error of pylibmc

@mahyard
Copy link

mahyard commented Aug 28, 2021

Hi @Andrew-Chen-Wang
How are you doing? Did you see my suggestion?

@Andrew-Chen-Wang
Copy link
Contributor Author

@mahyard apologies. Beginning of school. Will have much less time.

Based on my past PRs, having a direct dependency was a no-no. Though we could do a broad exception and then have the variable set in the except clause. I'm not sure when else the Django cache system will raise an exception besides configuration problems.

@jsocol
Copy link
Owner

jsocol commented Aug 29, 2021

Yeah we can't assume pylibmc is always installed, and I don't like implicitly changing the behavior based on the presence of a library (you could easily configure ratelimit to use a cache based on a different django cache backend). However, I also suspect that we could probably do something around the added = cache.add similar to what we do around count = cache.incr a few lines below.

Taking a step back here, though, I think we might get further by breaking apart a few steps here.

Currently we're splitting breaking out tests based on the memcached client, but all of them are still running the redis tests—that's a sign that maybe we should rethink this a bit. Maybe a first step is to think about how to parametrize the tests across "cache backend" instead of across "memcached client". Then add pylibmc, since that has been around for a while. Then add pymemcache, since that's new. And keep python-memcached for now, both because it's deprecated but not removed yet in 3.2, and because it's the closest thing to a reference implementation here.

So before we go too far down this road, I'm going to look at step 1 and rethink how we parametrize cache backend. I'd like to know for sure that the current tests that pass with python-memcached also, for example, all pass with django-redis—I'm not 100% sure they actually do because they don't run that way.

@jsocol
Copy link
Owner

jsocol commented Aug 29, 2021

I did two parts of this separately in #248 and #249 so we could get to a good starting point. I'm leaving some more commentary on #241, but I need to think on it a bit. Input would be super welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Test on PyMemcacheCache on Django 3.2
3 participants