Django deja de funcionar con RuntimeError: populate() no es reentrante

Resuelto Edward asked hace 9 años • 41 respuestas

He estado desarrollando una aplicación web Django implementada en un servidor Apache con WSGI y todo ha ido sin problemas. Hoy, hice algunos cambios menores en mi aplicación admin.pyen un intento de personalizar la interfaz integrada de Django Admin, e inicialmente cometí un error de sintaxis (un paréntesis sin cerrar). Esto significó que cuando toqué wsgi.pyy cargué el código (tengo WSGI ejecutándose en modo demonio en mi host virtual), mi sitio web fue reemplazado con un error interno del servidor porque WSGI se detuvo cuando encontró el error de sintaxis.

Así que arreglé el error de sintaxis, verifiqué que no tenía más manage.py checky toqué wsgi.pyvolver a implementar. ¡Pero mi sitio web todavía muestra un error interno del servidor! Revisando los registros de Apache, esto es lo que veo:

[Sun Nov 23 13:52:46 2014] [info] mod_wsgi (pid=19093): Create interpreter 'quotes.cs.cornell.edu|'.
[Sun Nov 23 13:52:46 2014] [info] mod_wsgi (pid=19093): Adding '/extra/www/html/quotes/quotes_django' to path.
[Sun Nov 23 13:52:46 2014] [info] mod_wsgi (pid=19093): Adding '/opt/rh/python27/root/usr/lib64/python2.7/site-
packages/' to path.
[Sun Nov 23 13:52:46 2014] [info] [client 128.84.33.19] mod_wsgi (pid=19093, process='quotes.cs.cornell.edu',
  application='quotes.cs.cornell.edu|'): Loading WSGI script '/extra/www/html/quotes/quotes_django/quotes_django/
wsgi.py'.
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19] mod_wsgi (pid=19093): Target WSGI script '/extra/www/html/
quotes/quotes_django/quotes_django/wsgi.py' cannot be loaded as Python module.
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19] mod_wsgi (pid=19093): Exception occurred processing WSGI
script '/extra/www/html/quotes/quotes_django/quotes_django/wsgi.py'.
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19] Traceback (most recent call last):
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]   File "/extra/www/html/quotes/quotes_django/
quotes_django/wsgi.py", line 14, in <module>
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]     application = get_wsgi_application()
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-
packages/django/core/wsgi.py", line 14, in get_wsgi_application
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]     django.setup()
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-
packages/django/__init__.py", line 21, in setup
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]     apps.populate(settings.INSTALLED_APPS)
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-
packages/django/apps/registry.py", line 115, in populate
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]     app_config.ready()
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-
packages/django/contrib/admin/apps.py", line 22, in ready
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]     self.module.autodiscover()
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-
packages/django/contrib/admin/__init__.py", line 23, in autodiscover
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]     autodiscover_modules('admin', register_to=site)
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-
packages/django/utils/module_loading.py", line 74, in autodiscover_modules
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]     import_module('%s.%s' % (app_config.name,         
module_to_search))
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]   File "/usr/lib64/python2.7/importlib/__init__.py", line 
37, in import_module
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]     __import__(name)
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]   File "/extra/www/html/quotes/quotes_django/quotespage/
admin.py", line 25
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]     approve_quotes.short_description = "Approve selected
quotes"
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19]                  ^
[Sun Nov 23 13:52:46 2014] [error] [client 128.84.33.19] SyntaxError: invalid syntax
[Sun Nov 23 13:53:36 2014] [info] [client 128.84.33.19] mod_wsgi (pid=19093, process='quotes.cs.cornell.edu',
  application='quotes.cs.cornell.edu|'): Loading WSGI script '/extra/www/html/quotes/quotes_django/quotes_django/
wsgi.py'.
[Sun Nov 23 13:53:36 2014] [error] [client 128.84.33.19] mod_wsgi (pid=19093): Target WSGI script '/extra/www/html/
quotes/quotes_django/quotes_django/wsgi.py' cannot be loaded as Python module.
[Sun Nov 23 13:53:36 2014] [error] [client 128.84.33.19] mod_wsgi (pid=19093): Exception occurred processing WSGI
script '/extra/www/html/quotes/quotes_django/quotes_django/wsgi.py'.
[Sun Nov 23 13:53:36 2014] [error] [client 128.84.33.19] Traceback (most recent call last):
[Sun Nov 23 13:53:36 2014] [error] [client 128.84.33.19]   File "/extra/www/html/quotes/quotes_django/         
quotes_django/wsgi.py", line 14, in <module>
[Sun Nov 23 13:53:36 2014] [error] [client 128.84.33.19]     application = get_wsgi_application()
[Sun Nov 23 13:53:36 2014] [error] [client 128.84.33.19]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-
packages/django/core/wsgi.py", line 14, in get_wsgi_application
[Sun Nov 23 13:53:36 2014] [error] [client 128.84.33.19]     django.setup()
[Sun Nov 23 13:53:36 2014] [error] [client 128.84.33.19]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-
packages/django/__init__.py", line 21, in setup
[Sun Nov 23 13:53:36 2014] [error] [client 128.84.33.19]     apps.populate(settings.INSTALLED_APPS)
[Sun Nov 23 13:53:36 2014] [error] [client 128.84.33.19]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-
packages/django/apps/registry.py", line 78, in populate
[Sun Nov 23 13:53:36 2014] [error] [client 128.84.33.19]     raise RuntimeError("populate() isn't reentrant")
[Sun Nov 23 13:53:36 2014] [error] [client 128.84.33.19] RuntimeError: populate() isn't reentrant

La primera serie de errores muestra que WSGI falla debido al error de sintaxis en mi archivo admin.py. Sin embargo, la segunda serie de errores parece mostrar un error interno de Django:

RuntimeError: populate() isn't reentrant

arrojado del populatemétodo de registry.py.

Buscar en Google este mensaje de error arroja sorprendentemente poca información, ninguna de la documentación de Django. Aparentemente, a veces puede suceder si nombras una aplicación dos veces en tu archivo settings.py, pero no voy a hacer eso. Más importante aún, no he cambiado settings.pydesde el momento en que el sitio web funcionaba bien; lo único que cambié fue admin.py.

Intenté revertir todos los cambios que hice, por lo que todo mi código Python volvió al estado en que estaba cuando el sitio web estaba funcionando, ¡y todavía recibo el populate() isn't reentranterror cuando intento hacer que WSGI recargue el código!

También intenté comentar diferentes aplicaciones en la sección INSTALLED_APPS de settings.py, e incluso con solo 'django.contrib.staticfiles' habilitado, el error aún ocurre. Curiosamente, sigo recibiendo el error incluso si comento todas las aplicaciones. ¡Django arroja el error incluso cuando no está cargando ninguna aplicación!

¿Alguien sabe qué está pasando aquí? ¿O alguna forma mejor de depurar este error, ya que el rastreo en el registro de Apache es bastante inútil?

Notas: estoy usando Django 1.7, Apache 2.2 y Python 2.7.

Edward avatar Nov 24 '14 03:11 Edward
Aceptado

Esto se debe a un error en la configuración de Django en alguna parte. Desafortunadamente, Django está ocultando el error detrás de este mensaje de error genérico e inútil.

Para revelar el verdadero problema, abra django/apps/registry.pyy alrededor de la línea 80, reemplace:

raise RuntimeError("populate() isn't reentrant")

con:

self.app_configs = {}

Esto permitirá que Django continúe cargando y revelará el error real.

Encontré este error por varias causas diferentes. Una vez fue porque tuve una mala importación en uno de los admin.py de mi aplicación.

Cerin avatar Apr 30 '2019 21:04 Cerin

Actualización del futuro

Dado que esta pregunta ha seguido recibiendo atención años después de que la hice originalmente, pensé que debería actualizar mi respuesta para ayudar mejor a los futuros lectores a resolver sus problemas.

Resulta que hay (al menos) dos razones diferentes por las que podría recibir el error "populate() no es reentrante" y, por lo tanto, dos enfoques diferentes para resolver el problema:

  1. Hay un error en su código Python o en su configuración de Django que hace que su aplicación no se inicialice correctamente. Como señala la respuesta de @Cerin, Django oculta el problema real detrás del inútil mensaje "poblar no es reentrante". Para solucionar este problema y revelar el error real, siga los consejos de @Cerin y edítelo django/apps/registry.pypara que Django deje de lanzar RuntimeError.

  2. En un momento hubo un error en su código Python, pero lo solucionó y Django sigue fallando con este mensaje porque WSGI no recargará su código reparado. Este es un problema de WSGI, no un problema de Django. Una forma de solucionarlo es editar temporalmente wsgi.pypara que su applicationfunción finalice el proceso WSGI (obligándolo a reiniciar), como lo describí en mi respuesta original; otra es configurar la startup-timeoutopción mod_wsgi para que WSGI se reinicie, como lo describe @Graham Dumpleton en los comentarios. Reiniciar todo el servidor Apache también soluciona este problema, porque incidentalmente reiniciará WSGI, aunque eso es un poco complicado y no siempre es posible si no eres administrador del servidor web.

Respuesta original a continuación:


El administrador de mi servidor reinició Apache y eso solucionó mágicamente este problema. Se cargan exactamente los mismos archivos de Python sin causar populate() isn't reentrant. Incluso intenté cargar otro archivo con un error de sintaxis, luego lo arreglé y el servidor pudo cargar el nuevo archivo y ejecutarlo correctamente sin problemas.

Todavía no sé qué estaba mal, pero lo marco como respondido ya que el problema desapareció. (Bueno, lo marcaré como respondido tan pronto como StackOverflow me permita aceptar mi propia respuesta).

Actualización : después de seguir recibiendo este error cuando accidentalmente subo Python con errores de sintaxis, descubrí una solución que es más fácil que reiniciar Apache. Cuando WSGI comienza a generar el populate() isn't reentranterror, reemplazo el de mi proyecto Django wsgi.pycon esta función simple:

def application(environ, start_response):
    if environ['mod_wsgi.process_group'] != '': 
        import signal
        os.kill(os.getpid(), signal.SIGINT)
    return ["killed"]

Luego vuelvo a cargar mi sitio web y el proceso del demonio WSGI se reinicia (lo cual puedo saber mirando el registro de Apache, aunque el sitio web todavía muestra el mismo error 500).

Si luego vuelvo wsgi.pya la normalidad y vuelvo a cargar, WSGI recoge con éxito mi código sin lanzarlo populate() isn't reentrant(asumiendo que esta vez no tengo errores de sintaxis). Por lo tanto, no es necesario reiniciar Apache en su totalidad, solo el proceso WSGI, y puedo hacerlo sin privilegios de root.

Edward avatar Nov 24 '2014 15:11 Edward

Sé que esta es una respuesta antigua pero contribuiré con mi solución:

Como forma de diagnosticar el origen del problema, ejecute manage.py checky vea si encuentra algo allí.

En mi caso, el problema era un requisito obsoleto y Django no podía importar un submódulo.

Asegúrese de que sus requisitos estén actualizados

Jesus Gomez avatar Apr 14 '2017 15:04 Jesus Gomez

No es una respuesta sino una reflexión.

Cuando actualiza a Django 1.7 y tiene un error 500 y recarga su página, Apache dice "populate() no es reentrante". Creo que es cuando cargas tu página, Apache carga todos los módulos que necesitas para tu aplicación y cuando se maneja el error, no descarga el módulo. Entonces, cuando recargas tu página, Apache carga nuevamente estos módulos pero ya está cargado. Entonces, Apache dice "populate() no es reentrante".

Tengo dos acciones para corregir esto: reiniciar Apache o corregir el error que maneja el primer error 5OO.

Intente reiniciar Apache con:

sudo service httpd restart

Espero que te ayude.

Vianney Thurotte avatar Nov 24 '2014 10:11 Vianney Thurotte