Opened 15 years ago

Closed 14 years ago

Last modified 11 years ago

#9437 closed (fixed)

OperationalError under fastcgi when maxrequests=1 is set

Reported by: Matt Bartolome Owned by: Matt Bartolome
Component: GIS Version: dev
Severity: Keywords: gis geodjango
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I'm trying to run django (with a contrib.gis model) under fastcgi with the maxrequests=1 parameter so I don't have to restart the process to see code changes:

$ python manage.py runfcgi --settings=myproject.settings method=prefork pidfile=/var/run/myproject.pid host=127.0.0.1 port=7778 maxrequests=1

I'm using nginx on the front end with postgresql_psycopg2. When I remove the GIS contrib portion from my model (and use the regular django.db.models) I no longer get the error.

My models.py (it does not seem to matter if I have a geometry field in the model or not):

from django.contrib.gis.db import models
from django.conf import settings
from django.contrib.sites.models import Site
from django.core.files import File

class Drawing(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField()
    date = models.DateTimeField()
    created = models.DateTimeField(auto_now=True)

    objects = models.GeoManager()

    def get_absolute_url(self):
        domain = Site.objects.get(id=settings.SITE_ID).domain
        return "%s/drawings/%s/" % (domain,self.slug)

    def __unicode__(self):
        return self.title

Traceback:

File "/usr/local/lib/python2.5/site-packages/django/core/handlers/base.py" in get_response
  77.                     request.path_info)
File "/usr/local/lib/python2.5/site-packages/django/core/urlresolvers.py" in resolve
  181.                     sub_match = pattern.resolve(new_path)
File "/usr/local/lib/python2.5/site-packages/django/core/urlresolvers.py" in resolve
  179.             for pattern in self.urlconf_module.urlpatterns:
File "/usr/local/lib/python2.5/site-packages/django/core/urlresolvers.py" in _get_urlconf_module
  198.             self._urlconf_module = __import__(self.urlconf_name, {}, {}, [''])
File "/home/mbartolome/projects/gis/spec/urls.py" in <module>
  6. from gis.tilecache import views as t_views
File "/home/mbartolome/projects/gis/tilecache/views.py" in <module>
  4. from gis.cwagrid.models import CWAGrid
File "/home/mbartolome/projects/gis/cwagrid/models.py" in <module>
  6. class CWAGrid(models.Model):
File "/home/mbartolome/projects/gis/cwagrid/models.py" in CWAGrid
  9.     geom = models.MultiPolygonField(srid=2230, db_column='the_geom')
File "/usr/local/lib/python2.5/site-packages/django/contrib/gis/db/models/fields/__init__.py" in __init__
  45.         self._unit, self._unit_name, self._spheroid = get_srid_info(srid)
File "/usr/local/lib/python2.5/site-packages/django/contrib/gis/models.py" in get_srid_info
  261.         cur.execute(stmt)
File "/usr/local/lib/python2.5/site-packages/django/db/backends/util.py" in execute
  19.             return self.cursor.execute(sql, params)

Exception Type: OperationalError at /spec/
Exception Value: server closed the connection unexpectedly
	This probably means the server terminated abnormally
	before or while processing the request.

Attachments (3)

models.py.diff (622 bytes ) - added by Matt Bartolome 15 years ago.
gis contrib models.py add connection.close() in get_srid_info
gis-connection-close-trunk.diff (587 bytes ) - added by jbronn 14 years ago.
gis-connection-close-1.1.X.diff (542 bytes ) - added by jbronn 14 years ago.

Download all attachments as: .zip

Change History (16)

comment:1 by Matt Bartolome, 15 years ago

Sorry, the error actually happens deeper in the chain. From the traceback you can see it is triggered through a model you import through a view in urls.py.

urls.py

from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()

from gis.tilecache import views as t_views
from gis.spec import views

urlpatterns = patterns('',
    (r'^$', views.index),
)

The models.py causing the error:

from django.contrib.gis.db import models

class CWAGrid(models.Model):
    id = models.AutoField(primary_key=True,db_column='gid')
    indexnum = models.IntegerField(db_column='indexnum')
    geom = models.MultiPolygonField(srid=2230, db_column='the_geom')
    objects = models.GeoManager()

    def  __unicode__(self):
        return str(self.indexnum)
    class Meta:
        db_table = 'cwagrid'

Without the geometry field I get no such error.

comment:2 by Matt Bartolome, 15 years ago

Cc: blake@… removed

Seems like the OperationalError occurs when any model is instantiating a new cursor and executing a statement.

Lines 252:262 of django.contrib.gis.db.models (which is what I've been focusing on here for this case)

        from django.db import connection
        cur = connection.cursor()
        qn = connection.ops.quote_name
        stmt = 'SELECT %(table)s.%(wkt_col)s FROM %(table)s WHERE (%(table)s.%(srid_col)s = %(s\
rid)s)'
        stmt = stmt % {'table' : qn(SpatialRefSys._meta.db_table),
                       'wkt_col' : qn(SpatialRefSys.wkt_col()),
                       'srid_col' : qn('srid'),
                       'srid' : srid,
                       }
        cur.execute(stmt)

When the close_connection signal handler in django.db is commented out the error disappears.

# Register an event that closes the database connection
# when a Django request is finished.
def close_connection(**kwargs):
    connection.close()
signals.request_finished.connect(close_connection)

I'm not sure where to look to find out how the connection gets established under fastcgi if maxrequests=1. I know when the process starts django.db.init.py is called which establishes a connection but after that I'm clueless as signals.request_finished is fired and closes it. I'm still looking...

comment:3 by jbronn, 15 years ago

Component: Contrib appsGIS
milestone: post-1.0
Owner: changed from nobody to jbronn

comment:4 by Matt Bartolome, 15 years ago

Has patch: set
Owner: changed from jbronn to Matt Bartolome
Status: newassigned

by Matt Bartolome, 15 years ago

Attachment: models.py.diff added

gis contrib models.py add connection.close() in get_srid_info

comment:5 by (none), 15 years ago

milestone: post-1.0

Milestone post-1.0 deleted

comment:6 by Jacob, 15 years ago

milestone: 1.1
Triage Stage: UnreviewedAccepted

comment:7 by jbronn, 15 years ago

Resolution: fixed
Status: assignedclosed

(In [10254]) Fixed #9437 -- Now close database connection within get_srid_info. Thanks, mattxbart.

comment:8 by jbronn, 14 years ago

Resolution: fixed
Status: closedreopened

comment:9 by jbronn, 14 years ago

milestone: 1.11.2

Reopened because while the issue was fixed for get_srid_info (a function call which has now been deferred till after db/model initialization), the connection is not closed when retrieving the version for PostGIS. SpatiaLite, although using a similar mechanics, is not affected.

by jbronn, 14 years ago

by jbronn, 14 years ago

comment:10 by jbronn, 14 years ago

Resolution: fixed
Status: reopenedclosed

(In [12948]) Fixed #9437 -- Now close the connection after getting the PostGIS version during spatial backend initialization.

comment:11 by jbronn, 14 years ago

(In [12949]) [1.1.X] Fixed #9437 -- Now close the connection after getting the PostGIS version during spatial backend initialization.

Backport of r12948 from trunk.

comment:12 by Jacob, 12 years ago

milestone: 1.2

Milestone 1.2 deleted

comment:13 by Aymeric Augustin <aymeric.augustin@…>, 11 years ago

In f2f98abb955c83eca3ceea62d1711c80ae028d33:

Avoided closing the database connection within a transaction.

Refs #9437.

Note: See TracTickets for help on using tickets.
Back to Top