Subprozess oder Thread oder Multiprocessing für mehrere Instanzen einer Klasse oder mehreren Klassen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Spohky
User
Beiträge: 21
Registriert: Montag 17. April 2017, 10:52

Hallo Zusammen

wie im Titel steht, würde ich gerne wissen wie ich mein Vorhaben am besten umsetzen kann.

Ich habe z.B. eine Klasse in der ein TS3 Bot ist, eine Klasse in der ein Streaming Bot ist, eine weitere Klasse in der ein Bot ist, der Socialmedia Postings verschickt.
Alle dieser Bots sind mit einer MySQL-DB verbunden und können darüber gestertet, gestopt und gesteuert werden, zudem sollen auch mehrere Instanzen der Bots möglich sein, außerdem soll das ganze erweiterbar werden, wenn noch mehr Bots hinzukommen

Ich würde nach Möglichkeit gerne eine Datei haben die die Datenbank ausliest und das Management der Bots / Instanzen übernimmt, so sollen die Bots verwaltet werden, änderungen der Einstellungen sollen übergeben werden, wie auch Daten zurück übergeben werden, eine Datenübermittlung zwischen den Prozessen ist bisher nicht vorgesehen, aber in Zukunft eventuell.

Ich habe mich mit allem mal etwas auseinandergesetzt und weiß nicht, welches das Beste ist.

Mir ist wichtig, das die Bots unabhängig und gleichzeitig laufen, auch wenn einer davon abstürzt, aus welchen Grund auch immer.

Zudem da ich noch eher etwas neu bin was Python betrifft, fällt es mir schwer dies zu entscheiden.

Grüße und Danke
Spohky
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich sehe jetzt noch nicht, wieso da ueberhaupt mehrere Threads oder Prozesse sein muessen. Wieso reicht nicht ein Prozess, der in gewissen Intervallen Aufgaben fuer die verschiedenen Bots abholt? Mehrere Prozesse sind doch erst dann notwendig, wenn das sicht mehr skaliert, oder wenn ein einzelner (oder mehrere) Bots so lange fuer eine Aufgabe brauchen, dass andere Aufgaben in der Zwischenzeit liegenbleiben.

Threads und Multiprocessing helfen dir auch nicht bei der Stabilisierung des Systems. Dazu kommen eher Systeme wie zB supervisord zum Einsatz. Damit kannst du beliebig viele Prozesse starten & bei Absturz neu starten.
BlackJack

@Spohky: Ich würde ja sagen Unterprozesse, Threads, Multiprocessing, oder ganz was anderes, je nach dem…

Sorry, aber die Frage ist einfach zu weit gefasst.
Spohky
User
Beiträge: 21
Registriert: Montag 17. April 2017, 10:52

Ein Bot soll permanent laufen, wenn jetzt z.B. 20 TS3Bots laufen, dann dauert ein durchlauf des Scriptes ca. 2sec, somit müsste der letzte Bot ca 38sec warten bis er dran ist, das möchte ich nicht, da wenn es noch mehr Bots werden, dann würde sich dasu aufadieren.

inder Klasse der Bots ist eine "while true" schleide die wenn der Bot laut seiner Config beendet werden soll, beendet wird.
Und ich möchte auch nicht mehrere Bot-Files anlegen, da ich nicht weiß wie viele Bots im Endeffekt laufen werden.


Um das evtl einfacher zu formulieren, ich möchte mit der File "MainControl.py" dynamisch Klassen starten und verwalten, diese sollen selbstständig und unabhängig von einander agieren können, jedoch sollen sie mit der "MainControl.py" kommunizieren können.
BlackJack

@Spohky: Ich verweise noch mal auf meine Antwort. Das kannst Du mit allem machen was der Betreff aufzählt und mit noch viel mehr (RabbitMQ, ZeroMQ, Celery, Pyro, …)
Sirius3
User
Beiträge: 18299
Registriert: Sonntag 21. Oktober 2012, 17:20

@Spohky: warum dauert das 2s? Weil der Bot auf Antwort vom Server warten muß. Deshalb kommt zu BlackJacks Aufzählung auch noch asyncio dazu.
Spohky
User
Beiträge: 21
Registriert: Montag 17. April 2017, 10:52

ich sagte ja ca. 2 Sec es geht auch schneller oder langsamer, je nach dem ob und wieviele Channel im TS erzeugt werden müssen und wieviele User auf dem TS Server sind, es kann bei z.B. 500 Usern auch um einiges länger gehen.
Spohky
User
Beiträge: 21
Registriert: Montag 17. April 2017, 10:52

Also wenn ich das mit Threads machen würde, dann könnte ich z.B. über 200 Threads laufen lassen,w enn der Server das mitmacht?
Sirius3
User
Beiträge: 18299
Registriert: Sonntag 21. Oktober 2012, 17:20

@Spohky: nein, weil 200 Threads zu viele sind. Ein normaler Server würde auch keine 200 Verbindungen von einer Adresse aus erlauben. Hatte ich schon asyncio erwähnt?
Spohky
User
Beiträge: 21
Registriert: Montag 17. April 2017, 10:52

Ja hast du, ich bin neu in der Materie Python und ich finde leider nur erschwert im Internet die Antworten auf meine Fragen.

Edit:
Mein Problem ist einfach das z.B. der TS3 Bot auf mehreren unabhängigen TS3 Servern agiert, genau wie die anderen Bots auch.
Ich weiß nicht wie ich das so aufbauen kann, dass ich eig garnichts mhr machen muss im nachhinein, wenn ein Bot benötigt wird, dann soll er bereit gestellt werden.
Spohky
User
Beiträge: 21
Registriert: Montag 17. April 2017, 10:52

Ich habe noch mal geschaut und getestet.
Ich kann weder beim TS3 Bot noch beim Streaming Bot Asynchron arbeiten, da ich nicht weiß wann der Bot reagieren muss, sprich ich brauche erst eine Verbindung zum TS3 Server oder zum Chat des YT / Twitch Streams, sprich ich sollte in "Echtzeit" und eig ständig anfragen ob der Bot agieren muss, das würde bei mehreren TS3 Servern oder aktiven Streams zu ungewollten latenzen führen, was weder ich noch die anderen Leute wollen.

Es befinden sich derzeit 32 TS3 Server und 47 Streamer im Pool, können auch mehr werden...

Die Bots laufen im eigentlichen ohne Probleme, nur will ich das managen, so das ich da nicht immer im Spiel sein muss.

Ich habe keine Ahnung, egal wie ich das versuche, es funktioniert nicht, zumdem weiß ich nicht wie mir Asyncio hierbei helfen soll, daich nicht weiß wann welcher Bot wieder Arbeit hat.
BlackJack

@Spohky: Wie schon gesagt: Die Frage ist so allgemein gestellt, das man da nicht wirklich viel sagen kann ausser die möglichen Techniken aufzuzählen. Hier weiss wahrscheinlich auch kaum jemand was TS3 ist, was Du unter einem Bot verstehst, und was da tatsächlich in welcher Konstellation und über welche Protokolle gemacht werden soll.

Bei „Bot“ denken die meisten Leute erst einmal an etwas das auf einer TCP-Verbindung bidirektionale Kommunikation mit etwas anderem auf der Gegenseite betreibt. Und da ist `asyncio` halt eine passende Antwort, insbesondere wenn dazu dann noch die Anforderung „200 gleichzeitig“ kommt.
Spohky
User
Beiträge: 21
Registriert: Montag 17. April 2017, 10:52

Okey, dann hier die Informationen, mit denen Ihr eventuell besser helfen könnt.

TS3 == TeamSpeak 3

Der TS3 Bot fragt den TS3 Server ab und liest aus, wielang ein User AFK ist und verschiebt ihn nach der Zeit X in einen AFk Raum und wenn er wieder Online geht schiebt er ihn zurück in den Raum von zuvor, zudem prüft er ob ein User in einem gewissen Raum ist, der den Bot veranlässt einen neuen Raum zu erzeugen und den User in diesen zu verschieben und noch ein paar weitere Funktionen die in Planung sind. Somit ist die Durchlaufzeit des Scriptes abhängig auf die User und latenz zwischen dem TS3 Server und TS3 Bot.
Für den TS3 Bot nutze ich folgende Lib: https://github.com/benediktschmitt/py-ts3

Für den Streaming Bot, der mit folgenden Libs Arbeitet:
https://developers.google.com/youtube/v ... les/python
http://ingwinlu.github.io/python-twitch/api.html

Hier wird in gewissen Abständen abgefragt ob ein User Streamt, wenn ja dann wird der Bot Aktiv und fängt an den Chat auszulesen und auszuwerten, für Umfragen und wie lange ein Zuschauer aktiv ist, NAchrichten in Intervallen zu veröffentlichen und auch die Annahme und verarbeitung von Befehlen (!Befehl), zudem wird der Chat für die einblendung im Chat vorbereitet, hier kommt es auf eine sehr geringe Verzögerung an.

Für den Socialmedia Poster kann ich das auch anders lösen, da es nicht permanent anfragen stellt, eher in intervallen, da machen Zeiten von bis zu 5 Minuten keinen Unterschied.
Spohky
User
Beiträge: 21
Registriert: Montag 17. April 2017, 10:52

So, Guten Abend noch mal,

ich habe mir da einen Weg überlegt, den ich gerne versuchen würde, nur habe ich ein Problem.
Mein Problem ist, das ich gerne per "multiprocessing.pool" das ganze am versuchen bin, doch er sagt mir immer folgenden Fehler:

Code: Alles auswählen

p = pool(2)
TypeError: 'module' object is not callable.
Ich binde es so ein: from multiprocessing import pool

Kann mir jemand helfen?
Spohky
User
Beiträge: 21
Registriert: Montag 17. April 2017, 10:52

Okey, ich habe das Problem gelöst, hier kann man dicht machen.
Muss ich das Schließen oder wird das Automatisch geschlossen?

Gruß und Danke
Spohky
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Spohky hat geschrieben:Okey, ich habe das Problem gelöst, hier kann man dicht machen.
Muss ich das Schließen oder wird das Automatisch geschlossen?
Wir schließen keine Threads. Der Thread stirbt halt irgendwann, wenn länger nichts geschrieben wird.
Sirius3
User
Beiträge: 18299
Registriert: Sonntag 21. Oktober 2012, 17:20

@Spohky: da Du bei der TS3-Lib sowieso Deine eigene Event-Schleife schreiben mußt, ist es ja kein Problem dort tausende Verbindungen in einer Schleife zu haben, etwas tiefer eingreifend sogar resourcenschonender mit select.
Hunderte von Threads sind nicht die Lösung.
Serpens66
User
Beiträge: 259
Registriert: Montag 15. Dezember 2014, 00:31

Spohky hat geschrieben:Okey, ich habe das Problem gelöst, hier kann man dicht machen.
Muss ich das Schließen oder wird das Automatisch geschlossen?

Gruß und Danke
Spohky
Wie sieht denn deine Lösung nun aus?
Hilft evlt anderen Nutzern.
Spohky
User
Beiträge: 21
Registriert: Montag 17. April 2017, 10:52

Serpens66 hat geschrieben:Wie sieht denn deine Lösung nun aus?
Hilft evlt anderen Nutzern.
also mein Aktuelles vorhaben muss ich natürlich noch anpassen und versuchen, aber der Plan Sieht so aus:

MainProcess.py (anbindung an die MySQL)
> Liest in regelmässigen Abständen die MySQLDB aus, startet die Bots und soll auch prüfen ob ein Bot noch läuft, zudem sollen Updates der Bots automatisch vom WebServer gedownloaded werden und nach zuvoreingestellter Zeit den jeweiligen Bot herunterfahren und updaten und im Anschluss auch wieder starten, durch eine eintragung in der DB kann man hier einfach neue Bots integrieren.
Es werden Subprozesse gestartet und es werden in der Datenbank festgelegt, wieviele aktive Verbindungen nach außen je Bot erlaubt werden und wie viele eigene Threads (local) jede Verbindung selbst nutzen darf.

SubProcess.py (anbindung an die MySQL)
> Liest alle für sich eigenen Bots raus (z.B. 20 TeamSpeak3 Bots) und wirt sie in den Pool der mit x Threads abgearbeitet wird, diese Threads haben eine Berechtigung eine Verbindung nach außen aufzunehmen.
Für einen schnelleren Durchlauf eines Bots werden z.B. beim TS3 Bot alle Member in einen Pool geworfen und mit x Threads die zuvor festgelegt werden abgearbeitet.

Funktion (keine anbindung an die MySQL, nur eine rückmeldung an den SubProcess)
> Bekommt zugeteilt mit welchen angaben er eine Funktion ausführen soll. Gibt am Ende Daten / Rückinfo an den SubProcess.



Ich muss nur noch schauen wie ich das mit einer Log-File mache, bzw. die Logs in der DB ablegen um bei Problemen nachvollziehen zu können wie es zu einem Problem gekommen ist, bzw. wann etwas getan wurde.

Zudem möchte ich hier noch sagen können, wenn der Server 100 Verbindungen nach außen zulässt, x für die API offen zu lassen und die restlichen sollen dann nach bedarf verteilt werden, also wenn keiner Streamt, dann werden hier z.B. nur 2 Verbindungen freigehalten, die anderen verteilen sich nach bedarf dann auf z.B. den TS3 Bot, der ja kontinuierlich läuft. (Ich muss hier nur die Prios setzen und dann sinnvoll verteilen)


Also so sieht der aktuelle Plan aus, mal schauen ob er sich so wie gedacht umgesetzt werden kann. :)

edit: Hab ich jetzt einfach nebenbei mal schnell runtergeschreiben und zusammengefasst was auf meinem Zettelchen detaillierter steht.
Antworten