django: fastCGI Probleme...

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hm. Stehe irgendwie auf dem Schlauch... Ich bekomme django nicht mit fastCGI zum laufen :(

Leider habe ich keinen Zugriff auf die Apache Log-Dateien :(

Das kleine Test-Skript aus dem Wiki läuft einwandfrei: [wiki]Web-Skripte zum Laufen bringen#EinKleinerFastcgiTest[/wiki]

Wenn man es selber macht, sieht es ja so aus (der dispatcher):

Code: Alles auswählen

from flup.server.fcgi import WSGIServer

from fastCGI_test_app import app

WSGIServer(app).run()
Es es möglich django als "app" zu bekommen? Dann könnte ich das damit mal probieren. Auf jeden Fall geht's wie auf http://www.djangoproject.com/documentat ... ith-apache beschrieben nicht.
Auch lokal funktioniert das ganze nicht. In der Log sehe ich allerdings auch nur sowas:
[Wed Sep 19 14:31:48 2007] [notice] mod_fcgid: server /home/jens/workspace/PyLucid0.8(django)/index.fcgi(9358) started
[Wed Sep 19 14:31:49 2007] [notice] mod_fcgid: server /home/jens/workspace/PyLucid0.8(django)/index.fcgi(9359) started
[Wed Sep 19 14:31:49 2007] [notice] mod_fcgid: process /home/jens/workspace/PyLucid0.8(django)/index.fcgi(9358) exit(server exited), terminated by calling exit(), return code: 255
[Wed Sep 19 14:31:49 2007] [notice] mod_fcgid: process /home/jens/workspace/PyLucid0.8(django)/index.fcgi(9356) exit(server exited), terminated by calling exit(), return code: 255
[Wed Sep 19 14:31:55 2007] [notice] mod_fcgid: process /home/jens/workspace/PyLucid0.8(django)/index.fcgi(9359) exit(server exited), terminated by calling exit(), return code: 255

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Also bei mir funktioniert der Django-Code mit Lightys FastCGI. Welches FastCGI Modul nutzt du denn?

Eine WSGI-App bekommst du eigentlich ganz einfach mit ``django.core.handlers.wsgi.WSGIHandler()``.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Anscheinend ist es der neuere "fcgid"...

Also du meinst das so:

Code: Alles auswählen

import os
os.environ['DJANGO_SETTINGS_MODULE'] = "PyLucid.settings"

from flup.server.fcgi import WSGIServer
from django.core.handlers.wsgi import WSGIHandler

app = WSGIHandler() # Evtl. ohne die Klammern?

WSGIServer(app).run()

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Das stimmt so, also mit den Klammern.
TUFKAB – the user formerly known as blackbird
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Aha! Das bringt mich ein Stückchen weiter! Denn so geht's...

Nun funktioniert es auch... Ich hab mir mal was gebastelt:

Code: Alles auswählen

#!/usr/bin/python

import os

from django.core.handlers.wsgi import WSGIHandler
from django.core.servers.fastcgi import runfastcgi

os.environ['DJANGO_SETTINGS_MODULE'] = "PyLucid.settings"

def tb_catch_app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    yield '<h1>FastCGI Traceback catch:</h1>'

    global msg
    yield "<pre>"
    yield msg
    yield "</pre>"

try:
    runfastcgi(method="threaded", daemonize="false")
except Exception, err1:
    import traceback
    msg = traceback.format_exc()
    
    from flup.server.fcgi import WSGIServer
    WSGIServer(tb_catch_app).run()
else:
    msg = "Error: Nothings happends?!?!"
    from flup.server.fcgi import WSGIServer
    WSGIServer(tb_catch_app).run()
Ich denke das sollte irgendwie auch eleganter gehen, oder???

Zum eigentlichen Problem: Anscheinend waren meine benutzten Parameter für runfastcgi() falsch. Das verhinderte wohl eine Ausführung.
Ich hatte wohl statt den Parameter method="threaded" das angegeben: socket="fcgi.sock"

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

OK, also beim GPcom geht's nun mit fastCGI...

Nun probiere ich es bei unserm PyHosting... Dort sehe ich in den log's das:
[Fri Sep 21 13:06:32 2007] [error] [client 88.76.139.87] FastCGI: comm with (dynamic) server "./index.fcgi" aborted: (first read) idle timeout (50 sec)
[Fri Sep 21 13:06:32 2007] [error] [client 88.76.139.87] FastCGI: incomplete headers (0 bytes) received from server "./index.fcgi"
Komisch. Ist eigentlich das selbe Skript...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jens hat geschrieben:Nun probiere ich es bei unserm PyHosting... [...] Komisch. Ist eigentlich das selbe Skript...
xorAxAx gefragt?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ahouben
User
Beiträge: 1
Registriert: Samstag 22. September 2007, 21:18

Das ist dann meistens ein Problem mit der Umformatierung beim Hochladen auf den Server. Set transfer mode to binary, then upload again.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ne, also es lag wohl an den Dateirechten. suexec ist da wohl etwas penibel. In meinem Fall hatte die Gruppe Schreibrechte und das mag suexec nicht.

Aber jetzt siehts dennoch komisch aus! Also bei dem Skript von oben: http://www.python-forum.de/post-77936.html#77936
tritt doch tatsächlich der Fall ein das "Error: Nothings happends?!?!" ausgegeben wird! Das sollte ja IMHO nie auftreten...

Jetzt wo ich mir mal http://code.djangoproject.com/browser/d ... fastcgi.py angesehen habe, könnte es ja sein, das etwas auf stderr geschrieben wurde... Das könnte ich ja mal versuchen abzufangen...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab mich heute nochmal dem Thema django + fastCGI angenommen...

Ich hab was dolles gefunden und zwar in /django/core/servers/fastcgi.py :

Code: Alles auswählen

wsgi_opts['debug'] = False # Turn off flup tracebacks
http://code.djangoproject.com/browser/d ... =6075#L121

Warum nur ist das Hardcoded? Ich suche schon seid einiger Zeit eine Möglichkeit für einen solchen "Low-Level"-Debug Modus. Dabei exstiert der schon so einfach, ist aber immer abgeschaltet :(

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jens hat geschrieben:Warum nur ist das Hardcoded?
Weil Django eine eigene Traceback-Middleware hat die etwas gegen das Leaken von Informationen abgesichert ist. Wie zum Beispiel Datenbankpasswörter.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ja, das stimmt. Allerdings ist es so: Wenn du einen Fehler in einer Middleware hast, dann funktioniert der django traceback überhaupt nicht!

Geh mal hin und setzte eine FastCGI App mit SQLite auf. Dann entziehst du der SQLite Datei die Schreibrechte. Wenn nun die Session Middleware versucht die Session zu schreiben, dann Peng.
Vom normalen Traceback sieht man nix. Nur in der Apache Log schneien Fehlermeldungen über stderr rein.

Im Browser sieht man nur was von "FastCGI Unhandled Exception"...

Wenn man aber den flup tracebacks aktiviert, dann sieht man auch einen Traceback im Browser...

Wenn man also keinen Zugriff auf die Apache Log hat, schaut man normalerweise in die Röhre...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jens hat geschrieben:Ja, das stimmt. Allerdings ist es so: Wenn du einen Fehler in einer Middleware hast, dann funktioniert der django traceback überhaupt nicht!
Ja, mag ja sein.
jens hat geschrieben:Vom normalen Traceback sieht man nix. Nur in der Apache Log schneien Fehlermeldungen über stderr rein.

Im Browser sieht man nur was von "FastCGI Unhandled Exception"...
Naja, findest du es besser die Datenbankpasswörter zu leaken, damit der User sich selbst einloggen kann und sich die Daten selbst aus der Datenbank holt?
jens hat geschrieben:Wenn man also keinen Zugriff auf die Apache Log hat, schaut man normalerweise in die Röhre...
Das ist an sich auch nicht verkehrt, denn error.log ist genau der Ort wo so etwas hin soll. Wenn man keinen Zugriff darauf hat, dann hat man ein generelles Problem und nicht angezeigte Tracebacks sind noch das geringste.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich sagt ja nicht, das der flup traceback generell an geschaltet werden sollte. Aber es sollte so sein, das man in einschalten kann, ohne an django rumfummeln zu müssen.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Kannst ja einen Patch schreiben. Viel Glück.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:


GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also irgendwie ist das alles nix mit fastCGI... Ich hab lokal einen Apache laufen und kann dort in die LOG Dateien schauen... Aber auch daraus wird man oft nicht schlau, wenn dort nur sowas auftaucht wie:
[Tue Feb 19 10:26:03 2008] [error] [client 127.0.0.1] (104)Connection reset by peer: FastCGI: comm with server "/home/jens/workspace/PyLucid_trunk/pylucid/index.fcgi" aborted: read failed, referer: http://localhost/
[Tue Feb 19 10:26:03 2008] [error] [client 127.0.0.1] Handler for fastcgi-script returned invalid result code 1, referer: http://localhost/
Hin und wieder tauchen dort ausgaben von stderr auf, das hilft dann schon mal weiter...

z.Z. hänge ich wein wenig fest. Ich möchte das eine Traceback-App nur einmal läuft, damit jede Änderung sofort aktiv ist, ohne das ich die Prozesse killen muss oder Apache einen Neustart braucht.

Ich hab mal eine kleine Test App gemacht:

Code: Alles auswählen

#!/usr/bin/env python2.4
# -*- coding: utf-8 -*-

import os, time
from flup.server.fcgi_fork import WSGIServer


start_overall = time.time()

def app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    yield '<p>overall time: %.2fsec</p>\n' % (time.time() - start_overall)

    pid = os.getpid()
    yield '<p>pid: %s</p>\n' % pid


WSGIServer(
    app, maxRequests=1, maxSpare=1, maxChildren=1
).run()
Man kann sehen, das die pid pro Request eine andern Nummer ist. Denoch werden Änderungen im Sourcecode nicht direkt sichtbar. Das kann man auch an der Zeit sehen, die immer schön weiter läuft und nicht bei jedem Request von Null anfängt.

Ich bin wohl auf der Suche nach einer "auto-reload" Funktion für fastCGI, gibt es sowas?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich hab's, die Holzhammer Methode:

Code: Alles auswählen

#!/usr/bin/env python2.4
# -*- coding: utf-8 -*-

from flup.server.fcgi_fork import WSGIServer

import os, time

pid = os.getpid()
start_overall = time.time()

def app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    yield '<p>overall time: %.2fsec</p>\n' % (time.time() - start_overall)

    global pid
    yield '<p>pid1: %s</p>\n' % pid

    yield '<p>pid2: %s</p>\n' % os.getpid()

    import signal
    os.kill(pid, signal.SIGHUP)

WSGIServer(
    app, maxRequests=1, maxSpare=1, maxChildren=1
).run()
Wenn man os.kill() auskommentiert kann man sehen, das der Hauptprozess immer der selbe ist, aber die App immer in einem neuen Prozess gestartet wird.
Würgt man den Hauptprozess ab, dann startet die App quasi nach jedem Request von neuem...

Kann man das so machen? Solle ich ein anderes Signal senden?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Unter Lighty werden bei mir FastCGI-Prozesse beim Server-Reload neu gestartet - sehr nützlich bisher.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Apache mus man restarten. Das dauert lange und man kann es nur mit root machen :(

Edit: Hm, mit os.kill() scheint Apache zusammen zu brechen...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten