2013-03-01 22 views
6

Sto tentando di implementare una risorsa Tastypie che consente operazioni GET & in seguito a una politica di autorizzazione per utente, il modello è piuttosto semplice (simile al modello Note nella documentazione di Tastypie) e la risorsa stessa è anche abbastanza semplice, ho solo un metodo extra override_urls per implementare la ricerca con Haystack.Risposta POST lenta di Django Tastypie

Il mio problema principale ora è che sebbene l'esecuzione del progetto in locale sembra funzionare correttamente, le richieste sono veloci e tutto. Una volta distribuito il progetto (su Linode, utilizzando Nginx, Gunicorn, Runit), ho scoperto che le richieste POST sono troppo lente, richiedendo circa 1,1 minuti per tornare con uno stato 201. Le richieste GET d'altra parte stanno funzionando bene e come previsto.

Ho eseguito un profiler Python Hotshot sulla richiesta e sta dimostrando che l'intera richiesta POST richiede 0,127 secondi CPU. Non sono sicuro di cosa stia succedendo qui.

Devo dire che sto usando ApiKeyAuthentication e DjangoAuthorization per la mia risorsa Tastypie.

Ecco uno screenshot da Chrome Inspector per la richiesta: http://d.pr/i/CvCS

Sarebbe bello se qualcuno mi può indirizzare nella direzione giusta per cercare una risposta a questo problema.

Grazie!

Edit:

Alcuni codice:

modelle & risorse:

class Note(models.Model): 
    timestamp = models.DateTimeField('Timestamp') 
    user = models.ForeignKey(User) 
    page_title = models.CharField("Page Title", max_length=200) 
    url = models.URLField('URL', verify_exists=False) 
    summary = models.TextField("Summary") 
    notes = models.TextField("Notes", null=True, blank=True) 

    def __unicode__(self): 
     return self.page_title 

    def get_absolute_url(self): 
     return self.url 


class NoteResource(ModelResource): 
    user = fields.ForeignKey(UserResource, 'user') 

    class Meta: 
     queryset = Note.objects.all() 
     resource_name = 'note' 
     list_allowed_methods = ['get', 'post'] 
     detail_allowed_methods = ['get'] 
     always_return_data = True 
     authentication = ApiKeyAuthentication() 
     authorization = DjangoAuthorization() 
     # authentication = Authentication() #allows all access 
     # authorization = Authorization() #allows all access 

     ordering = [ 
      '-timestamp' 
     ] 

    def override_urls(self): 
     return [ 
      url(r"^(?P<resource_name>%s)/search%s$" % (
       self._meta.resource_name, trailing_slash()), 
       self.wrap_view('get_search'), name="api_get_search"), 
     ] 

    def obj_create(self, bundle, request=None, **kwargs): 
     return super(NoteResource, self).obj_create(bundle, 
                 request, 
                 user=request.user) 

    def apply_authorization_limits(self, request, object_list): 
     return object_list.filter(user=request.user) 

    def get_search(self, request, **kwargs): 
     self.method_check(request, allowed=['get']) 
     self.is_authenticated(request) 

     sqs = SearchQuerySet().models(Note).filter(
             user=request.user 
            ).auto_query(
             request.GET.get('q', '') 
            ) 

     paginator = Paginator(sqs, 100) 

     try: 
      page = paginator.page(int(request.GET.get('page', 1))) 
     except InvalidPage: 
      raise Http404("Sorry, no results on that page.") 

     objects = [] 

     for result in page.object_list: 
      bundle = self.build_bundle(obj=result.object, request=request) 
      bundle.data['score'] = result.score 
      bundle = self.full_dehydrate(bundle) 
      objects.append(bundle) 

     object_list = { 
      'objects': objects, 
     } 

     self.log_throttled_access(request) 
     return self.create_response(request, object_list) 

Gunicorn Conf:

bind = "0.0.0.0:1330" 
workers = 1 

Nginx Conf (incluso nel nginx.conf principale):

server { 
     listen 80; 
     server_name domain.com example.com; 
     access_log /path/to/home/then/project/access.log; 
     error_log /path/to/home/then/project/error.log; 

     location/{ 
       proxy_pass http://127.0.0.1:1330; 
     } 

     location /static/ { 
       autoindex on; 
       root /path/to/home/then/project/; 
     } 
} 
+0

mostraci il codicez –

+0

@Hedde ha modificato il post –

+0

La cortesia generalmente impone di identificare che questo è stato pubblicato anche nel gruppo di google. Avete alcune regole di elaborazione del segnale impostate sul modello? In particolare post_save? –

risposta

3

OP: calcolato. Nel file principale di nginx.conf (/etc/nginx/nginx.conf), risulta che ho mantenuto keepalive_timeout su 65, che è considerato troppo. L'ho passato a 0 e tutto ha funzionato bene.

Mi dispiace, passare un paio di minuti con questa domanda, allora capito che c'erano altri commenti e poi realizzato il PO ha fatto trovare una soluzione :(e non contrassegnare come risposta.

0

Mentre cambiare la keepalive_timeout sarà . lavoro, non risolve nginx del sottostante Content-Length intestazione bug che sta causando Questo problema è stato fixed in version 0.8.32 of nginx, ma se avete una versione precedente è possibile:

  1. Modificare il keepalive_timeout = 0 sul server
  2. Aggiorna nginx sul tuo server a una versione> = 0.8.32
  3. risolvere il problema nel codice lato server come spiegato here

Speriamo che questo aiuta chiunque altro che si imbatte in questo problema.