เครื่องปฏิกรณ์แบบบิดหยุดทำงาน แต่โปรแกรมไม่สิ้นสุดใช่ไหม

ฉันกำลังเขียนสคริปต์เล็กๆ เพื่อใช้กับ Deluge Deluge ใช้ Twisted และฉันก็ไม่เข้าใจวิธีการทำงานของมันมากนัก โดยปกติฉันจะค้นหาข้อมูลเพิ่มเติมเกี่ยวกับมัน แต่การเริ่มต้นกับ Twisted อาจใช้เวลานาน ยาว และอยู่นอกเหนือขอบเขตของโปรเจ็กต์เล็กๆ นี้ เลยคิดว่าจะถามที่นี่

ตอนนี้ฉันมีรหัสนี้ ฉันจะพยายามอธิบายส่วนเฉพาะที่ฉันต้องการความช่วยเหลือ

import base64

import processargs

from deluge.ui.client import client
from twisted.internet import reactor

from deluge.log import setupLogger
setupLogger()

options = processargs.readConfig(os.path.expanduser("~/.deluge-automator"))

d = client.connect(
    host=options['host'],
    port=int(options['port']),
    username=options['username'],
    password=options['password']
)

def start():
    #other code

    t = client.core.add_torrent_file(tfile,
                                     base64.encodestring(data), None)

    t.addCallback(on_torrent_added_success, tfile)
    t.addErrback(on_torrent_added_fail)


def handle_stop_signal(SIGNAL, stack):
    client.disconnect()
    reactor.stop()


def on_torrent_added_success(result, tfile):
    #other code
    start()


def on_torrent_added_fail(result):
    print "Add torrent failed!"
    print "result: ", result


def on_connect_success(result):
    #other code
    start()


d.addCallback(on_connect_success)


def on_connect_fail(result):
    print "Connection failed!"
    print "result: ", result


d.addErrback(on_connect_fail)

signal.signal(signal.SIGTERM, handle_stop_signal)
signal.signal(signal.SIGINT, handle_stop_signal)

reactor.run()

เมื่อเพิ่มทอร์เรนต์สำเร็จ มันควรจะกลับไปที่ start() และมันก็เป็นเช่นนั้น แต่ฉันคิดว่ามันสูญเสียเครื่องปฏิกรณ์หรืออะไรบางอย่างไป เพราะตอนนี้เมื่อใดก็ตามที่ได้รับ SIGTERM หรือ SIGINT เครื่องปฏิกรณ์จะปิด แต่จะไม่ออกจากโปรแกรม:

± % python2 main.py
Connection was successful!
result:  10
^C^CConnection failed!
result:  [Failure instance: Traceback: <class 'twisted.internet.error.ReactorNotRunning'>: Can't stop reactor that isn't running.
/usr/lib/python2.7/site-packages/twisted/internet/defer.py:551:_runCallbacks
/usr/lib/python2.7/site-packages/deluge/ui/client.py:412:__on_login
/usr/lib/python2.7/site-packages/twisted/internet/defer.py:368:callback
/usr/lib/python2.7/site-packages/twisted/internet/defer.py:464:_startRunCallbacks
--- <exception caught here> ---
/usr/lib/python2.7/site-packages/twisted/internet/defer.py:551:_runCallbacks
main.py:70:on_connect_success
main.py:32:start
main.py:49:handle_stop_signal
/usr/lib/python2.7/site-packages/twisted/internet/base.py:577:stop
]

เครื่องปฏิกรณ์จึงหยุดทำงาน แต่ไม่ได้ออกจากโปรแกรม ฉันต้องขัดจังหวะคีย์บอร์ดสองครั้ง หนึ่งครั้งเพื่อหยุดเครื่องปฏิกรณ์ และครั้งที่สองเพื่อส่งข้อผิดพลาด มีวิธีใดในการตั้งค่าการวนซ้ำเช่นนี้หรือไม่?


person mrobinson7627    schedule 20.11.2012    source แหล่งที่มา


คำตอบ (1)


เครื่องปฏิกรณ์จัดการ sigint, sigterm เอง (อาจมีพารามิเตอร์ reactor.run() ที่ปิดการใช้งานนั้น) ติดตั้ง reactor.addSystemEventTrigger('before', 'shutdown', client.disconnect) แทน

ดู twisted: จับการขัดจังหวะของคีย์บอร์ดและการปิดเครื่องอย่างถูกต้อง

person jfs    schedule 20.11.2012
comment
แค่ต้องการเสริมว่า ไม่ปลอดภัย ที่จะเรียก Twisted API ภายในตัวจัดการสัญญาณ ตัวจัดการสัญญาณเป็นรูปแบบหนึ่งของการเปลี่ยนบริบทที่ต้องยึดถือไว้ก่อน ซึ่งไม่ปลอดภัยพอๆ กับเธรด และต้องได้รับการปฏิบัติอย่างระมัดระวัง เฉพาะ Twisted API ที่ทำเครื่องหมายว่าปลอดภัยสำหรับเธรดเท่านั้นที่สามารถใช้ในตัวจัดการสัญญาณได้ (สิ่งที่น่าสนใจที่สุดคือ reactor.callFromThread) - person Jean-Paul Calderone; 21.11.2012