[megoldva] python daemon: signal megszakítja a hálózati kapcsolatot

Csináltam egy hálózatos daemont pythonban, teszi a dolgát, start, stop működik.
Reload-ot szeretnék csinálni úgy hogy küldök neki valami signalt.
Ha egyszer küldöm, rendben van, újraolvassa, lehet újra csatlakozni s utána is működik a reload.

De ha egymás után kétszer küldök neki signalt, akkor mindig szétkapcsolja a hálózatot. Vázlatosan:


def reload (a=None, b=None): print 'RELOAD OK'

signal.signal(signal.SIGHUP, reload)
...
while 1:
    clientsock, clientaddr = s.accept()

$ kill -HUP pid
RELOAD OK
$ kill -HUP pid
RELOAD OK
...
    clientsock, clientaddr = s.accept()
  File "/usr/lib/python2.4/socket.py", line 161, in accept
    sock, addr = self._sock.accept()
socket.error: (4, 'Interrupted system call') 

Van-e valami triviális megoldás ennek kiküszöbölésére?

(Mostani workaround: try, majd except-ben shutdown és újra socket létrehozás.)

szaszi

Hozzászólások

NEM PRÓBÁLTAM, de esetleg a while-ba az accept elé tenni a signal elkapást? (Ötlet: csak egyszer megy, utána újra regisztrálni kell).

Hmm... a signal elkapást nem tudom nagyon sehova rakni, signalra mindenképpen a (hozzá regisztrált) függvény fog végrehajtódni. Azt hogy mikor van a hozzárendelés, persze tudnám befolyásolni, de nem sok értelme volna. Azt meg, hogy mikor jön a signal, végképp nem tudoom belülről befolyásolni.

Vagy valamit nagyon félreértettem -- mindenesetre már megoldódott!

szaszi

Érzésem szerint maradnod kell ennél a workaround-nál. A signal modul dokumentációja írja:

"When a signal arrives during an I/O operation, it is possible that the I/O operation raises an exception after the signal handler returns. This is dependent on the underlying Unix system's semantics regarding interrupted system calls."

Abban nem vagyok biztos, hogy a socket-et újból létre kell hoznod, nem elég, ha újból accept-elsz?

Most így néz ki:


s = socket...
while 1:
   try:
      s.accept()
   except:
      s.shutdown...
      s = socket...
      continue

Ha itt az except-be betennék egy accept-et és az megint elszáll, akkor kellene még egy except, aztán megint egy...

Persze talán nem valós élethelyzet, hogy valaki csak a reloadot nyomkodja mint a veszekedett fene -- de azért nyugodtabb vagyok ha működik!

Illetve... Ha except-be raktam az accept-et, akkor valóban, de most csak a continue van ott: így teljesen jó!


   try:
      s.accept()
   except:
      continue

Köszönöm!

szaszi