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

Cachalot error #81

Closed
gokulrajridecell opened this issue Jun 12, 2017 · 21 comments
Closed

Cachalot error #81

gokulrajridecell opened this issue Jun 12, 2017 · 21 comments

Comments

@gokulrajridecell
Copy link

Getting this error , with cachalot enabled ., when running unit testcases.
backend cache is BACKEND': 'django_redis.cache.RedisCache'

File "/home/ubuntu/virtualenvs/venv-system/lib/python2.7/site-packages/django/db/migrations/executor.py", line 198, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/ubuntu/virtualenvs/venv-system/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 92, in exit
self.atomic.exit(exc_type, exc_value, traceback)
File "/home/ubuntu/virtualenvs/venv-system/lib/python2.7/site-packages/cachalot/monkey_patch.py", line 146, in inner
self.using, exc_type is None and not needs_rollback)
File "/home/ubuntu/virtualenvs/venv-system/lib/python2.7/site-packages/cachalot/cache.py", line 47, in exit_atomic
atomic_caches = self.atomic_caches[db_alias].pop().values()
IndexError: pop from empty list

can you please help with this?

@BertrandBordage
Copy link
Member

BertrandBordage commented Jun 14, 2017

Do you change the DATABASES or CACHES settings dynamically during your tests?

@gokulrajridecell
Copy link
Author

@BertrandBordage Thank you for responding. The test database is created dynamically each time the test is run.

@BertrandBordage
Copy link
Member

I meant, do you explicitly change these settings during tests?
By the way, which versions of Django & django-cachalot are you using?

@gokulrajridecell
Copy link
Author

no they are not changed explicitly during tests
django version 1.9
django-cachalot 1.4.1

@BertrandBordage
Copy link
Member

Is that possible for you to switch this particular project to django 1.8, 1.10 or 1.11 to test with django-cachalot 1.5.0?

@gokulrajridecell
Copy link
Author

we are in the process of upgrading to django 1.11.
but in the mean time, we want to deploy django-cachalot with django 1.9
will 1.5.0 cachalot avoid this issue?

thanks,

@BertrandBordage
Copy link
Member

Maybe 1.5.0 could avoid this issue, as it contains many refactorings.
Honestly, I never saw the issue you face.
Just in case, is your project open source?

@gokulrajridecell
Copy link
Author

I see. Its not open source.
I recently started working on this project and have been asked to enable cachalot.
The people who had worked on it before faced the same issue when enabling cachalot. so cachalot was not deployed in our production environment.

these are the settings im using:
CACHALOT_ENABLED = True
CACHALOT_ONLY_CACHABLE_TABLES = frozenset(...

....)

@gokulrajridecell
Copy link
Author

Got same failures with cachalot 1.5 version too.. :(

@BertrandBordage
Copy link
Member

Fixed by 6e429fd.

@pixelead0
Copy link

pixelead0 commented Jun 29, 2018

IndexError: pop from empty list

Django==1.11.13
django-cachalot==2.0.1
Python == 2.7.9

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'django_project',
        'USER': 'django_project',
        'PASSWORD': 'django_project',
        'HOST': '',
        'PORT': '',
    }
}
Traceback (most recent call last):
  File "/home/vagrant/.virtualenvs/django-project/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/vagrant/.virtualenvs/django-project/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "/home/vagrant/.virtualenvs/django-project/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/vagrant/.virtualenvs/django-project/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/vagrant/src/libraries/decorators.py", line 21, in wrapper
    return f(request, *args, **kwds)
  File "/home/vagrant/src/libraries/decorators.py", line 49, in wrapper
    return f(request, *args, **kwds)
  File "/home/vagrant/.virtualenvs/django-project/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/home/vagrant/src/applications/payments/views/camp.py", line 57, in camp
    form_payment.save()
  File "/home/vagrant/.virtualenvs/django-project/local/lib/python2.7/site-packages/django/forms/models.py", line 468, in save
    self.instance.save()
  File "/home/vagrant/src/applications/payments/models/payment.py", line 61, in save
    super(Payment, self).save(*args, **kwargs)
  File "/home/vagrant/.virtualenvs/django-project/local/lib/python2.7/site-packages/django/db/models/base.py", line 808, in save
    force_update=force_update, update_fields=update_fields)
  File "/home/vagrant/.virtualenvs/django-project/local/lib/python2.7/site-packages/django/db/models/base.py", line 838, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/home/vagrant/.virtualenvs/django-project/local/lib/python2.7/site-packages/cachalot/monkey_patch.py", line 167, in inner
    self.using, exc_type is None and not needs_rollback)
  File "/home/vagrant/.virtualenvs/django-project/local/lib/python2.7/site-packages/cachalot/cache.py", line 47, in exit_atomic
    atomic_caches = self.atomic_caches[db_alias].pop().values()
IndexError: pop from empty list

 /home/vagrant/.virtualenvs/django-project/local/lib/python2.7/site-packages/cachalot/monkey_patch.py in inner
            @wraps(original)
            def inner(self, exc_type, exc_value, traceback):
                needs_rollback = get_connection(self.using).needs_rollback
                try:
                    original(self, exc_type, exc_value, traceback)
                finally:
                    cachalot_caches.exit_atomic(
                        self.using, exc_type is None and not needs_rollback)
     ...
            return inner
        Atomic.__enter__ = patch_enter(Atomic.__enter__)
        Atomic.__exit__ = patch_exit(Atomic.__exit__)
▼ Local vars
Variable    Value
exc_type    None
exc_value   None
needs_rollback  False
original    <unbound method Atomic.__exit__>
self    <django.db.transaction.Atomic object at 0x7f27141e36d0>
traceback   None
/home/vagrant/.virtualenvs/django-project/local/lib/python2.7/site-packages/cachalot/cache.py in exit_atomic
            if db_alias is None:
                db_alias = DEFAULT_DB_ALIAS
            self.atomic_caches[db_alias].append({})
        def exit_atomic(self, db_alias, commit):
            if db_alias is None:
                db_alias = DEFAULT_DB_ALIAS
            atomic_caches = self.atomic_caches[db_alias].pop().values()
     ...
            if commit:
                to_be_invalidated = set()
                for atomic_cache in atomic_caches:
                    atomic_cache.commit()
                    to_be_invalidated.update(atomic_cache.to_be_invalidated)
                # This happens when committing the outermost atomic block.
▼ Local vars
Variable    Value
commit  True
db_alias    'default'
self    <cachalot.cache.CacheHandler object at 0x7f271debde20>

@PeterDekkers
Copy link

Still getting IndexError: pop from empty list in Cachalot 2.0.1 also.

@timkung1
Copy link

timkung1 commented Aug 6, 2018

Same problem. I can't reproduce it reliably as it only occurs after the server runs for a while.
Django 2.0.7
Cachalot 2.0.1

@BertrandBordage
Copy link
Member

Please try with django-cachalot 2.0.2, I made a workaround that should fix this.

@GabrielDumbrava
Copy link

Hi guys,
I get the same error with:
django==1.11.20
django-cachalot==2.1.0
python3.6
/cachalot/cache.py in exit_atomic, line 47

No specific settings, just the defaults.

@cfobel
Copy link

cfobel commented Nov 17, 2020

We have also experienced this issue with:

django==3.1.1
django-cachalot==2.3.2
python==3.8

CACHES = {"default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache",}}

Error was pop from empty list; /cachalot/cache.py, line 44, in exit_atomic.

@Andrew-Chen-Wang
Copy link
Collaborator

Hey @cfobel if you're using a virtualenv, if you don't mind, try putting the following print statements in cache.py:

# before L39
print("1a", self.atomic_caches, db_alias)

# b4 L44
print("1e", self.atomic_caches, db_alias)

The point is just to see if it's actually going to be atomic. In enter_atomic, we append a dict, soo.... my guess is sometimes, it's just not entering. My best guess is we either 1) aren't properly identifying (although I haven't looked at the code thoroughly) when a view is atomic, 2) it's just entering without a view being labeled for atomicity/transactions, 3) you're not enabling transactions for your view or for an entire project.

Those are just my guesses though.

@gone
Copy link

gone commented Jan 16, 2022

I am getting this with 2.4.5 on local host w/ locmemcache. Also running the django-debug-toolbar panel

@Andrew-Chen-Wang
Copy link
Collaborator

Is this reproducible? Sample project? Is it something I can run 100 times and get this error to pop up once? Are you multithreading by chance? Can you provide a piece of code to demonstrate how the Atomic object changed during your transaction as in the original poster?

@gone
Copy link

gone commented Jan 17, 2022

No it's not reproducible - I wish it was so I could give a more concrete error report.

I do have a sample app, and I think I was running in multi threaded under django-extensions' runserver_plus (so the werkzueg runner). On thinking about it more I think something odd might have happened with a debug thread + a reload. If I'm able to repro I'll provide more info.

@andresichelero
Copy link

andresichelero commented Apr 5, 2023

Using django-cachalot 2.4.4, django 3.1.13, same error:

File "/code/projects/views.py", line 308, in list
	self.update_user_activity(request.user.id)
File "/code/projects/views.py", line 304, in update_user_activity
	user.save()
File "/usr/local/lib/python3.8/contextlib.py", line 75, in inner
	return func(*args, **kwds)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/cachalot/monkey_patch.py", line 175, in inner
	cachalot_caches.exit_atomic(
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/cachalot/cache.py", line 44, in exit_atomic
	atomic_caches = self.atomic_caches[db_alias].pop().values()
IndexError: pop from empty list

Maybe it thinks it has a cache, but it already deleted the old one and is trying to do it again in the empty list? This error happens when refreshing multiple times the page, going back and forth, a bit of patience is needed until the error pops up.

I couldn't find a way to reproduce it, and the code I'm running is not open source, so I don't have more details, but when this error happens, it keeps happening until the docker container we're using for the app is restarted.

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

No branches or pull requests

10 participants