Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

multicast et threads

+3 votes

Voici un module (serverHealth.py) avec deux classes qui doivent multicaster des infos systèmes à plusieurs noeuds

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
import time
import struct
import sys
import logging
import psutil
import json
from flask import Flask, jsonify
import platform
import re

class get_health(DatagramProtocol):

    def startProtocol(self):
        self.transport.setTTL(5)
        # Join a specific multicast group:
        self.transport.joinGroup("228.0.0.5")

    def datagramReceived(self, datagram, address):
        if repr(datagram) is not None:
            data=(repr(datagram))
            print type (data)
            data.encode('utf-8')

class send_health(DatagramProtocol):

    def startProtocol(self):
        self.transport.joinGroup("228.0.0.5")
        while True:
          self.cpu=psutil.cpu_times()
          self.hostname=platform.node()
          self.vmem=psutil.virtual_memory()
          self.swap=psutil.swap_memory()
          self.net=psutil.net_io_counters(pernic=True)
          self.disks=psutil.disk_partitions()
          time.sleep(2)
          data={"hostname": self.hostname, "cpu":[{"user": self.cpu.user}, {"nice": self.cpu.nice}, {"system": self.cpu.system}, {"idle": self.cpu.idle}, {"iowait": self.cpu.iowait}, {"irq": self.cpu.irq}, {"sorfirq": self.cpu.softirq}, {"steal": self.cpu.steal}],"vmem":[{"total": self.vmem.total}, {"available": self.vmem.available}, {"percent": self.vmem.percent}, {"used": self.vmem.used}, {"cached": self.vmem.cached}], "swap":[{"total": self.swap.total}, {"used": self.swap.used}, {"free": self.swap.free},{"percent": self.swap.percent}]}

          for key, value in self.net.iteritems():
            if re.match(r'eth', key) or re.match(r'bond', key):
               dict={key: [{"bytes_sent": value.bytes_sent}, {"bytes_recv": value.bytes_recv}, {"packets_sent": value.packets_sent}, {"packets_recv": value.packets_recv}, {"errin": value.errin}, {"errout": value.errout}, {"dropin": value.dropin}, {"dropout": value.dropout}]}
               data.update(dict)

          for current in range(len(self.disks)):
            montage={self.disks[current].device: [{"mountpoint": self.disks[current].mountpoint}, {"fstype": self.disks[current].fstype}, {"opts": self.disks[current].opts}, {"percent_used":psutil.disk_usage(self.disks[current].mountpoint).percent}]}
            data.update(montage)
          self.transport.write(str(data), ("228.0.0.5", 8005))

    def datagramReceived(self, datagram, address):
        pass

1;

Voici le "launcher" que j'utilise pour tester mon module avec des threads:

#/usr/bin/python
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
import threading
from serverHealth import get_health
from serverHealth import send_health

def send():
  reactor.listenMulticast(8005, send_health(), listenMultiple=True)
  reactor.run()

def get():
  reactor.listenMulticast(8005, get_health(),listenMultiple=True)
  reactor.run()

thread_send = threading.Thread(target=send)
thread_send.start()
thread_get = threading.Thread(target=get)
thread_get.start()

Le traceback en lancant laucher.py pour tester :

Unhandled Error
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 416, in fireEvent
DeferredList(beforeResults).addCallback(self.continueFiring)
File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 306, in addCallback
callbackKeywords=kw)
File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 295, in addCallbacks
self.
runCallbacks()
File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 577, in _runCallbacks
current.result = callback(current.result, *args, **kw)
--- ---
File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 429, in _continueFiring
callable(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1187, in _reallyStartRunning
self._handleSignals()
File "/usr/lib/python2.7/dist-packages/twisted/internet/posixbase.py", line 300, in _handleSignals
_SignalReactorMixin._handleSignals(self)
File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1152, in _handleSignals
signal.signal(signal.SIGINT, self.sigInt)
exceptions.ValueError: signal only works in main thread

Ma question, comment puis-je faire une classe avec un sender et un receiver qui envoie/reçoit en multicast du json, le sender et le receiver doivent tourner dans deux threads séparés du main en étant non-bloquant ? Chque noeuds doit recevoir en permanance les infos des autres et envoyer des infos le concernant.

demandé 17-Nov-2015 par r3dlight

1 Réponse

0 votes

Twisted peut tourner dans n'importe quel thread mais dans un seul thread à la fois. Si tu veux faire tourner ton code dans un autre thread que main, utilises:

reactor.run(installSignalHandlers=False)

Tu ne pourras pas utiliser reactor pour spawner des subprocess sur un autre thread que main parce la terminaison de ces process ne sera jamais détectée. (Ceci est une limitation de Unix et non de Twisted.)

répondu 1-Mar-2016 par barnumbirr (2,754 points)
...