


Tabellar
Ich weiß, jedoch ist xmpppy eine Wieterentwicklung von Jabberpy, die die API so weit wie möglich beibehlaten möchte. In wie weit das gelungen ist, kann ich nicht beurteilen. Aber der Autor von xmpppy ist auch Entwickler bei Jabberpy.tabellar hat geschrieben:Ich werd mir xmpppy mal anschauen. Jabberpy ist nunmal ausgereift und wird z.B. in "Programming Jabber" (O'Reily) verwendet. Ich verwende unseren privaten "JabberServer", der nur über SSL (443) erreicht werden kann. Den amessage Server verwende ich z.B. im Zusammenspiel mit FreeMind, damit ist in der derzeitigen Version Collaboration via Jabber Protokoll möglich.
Sicher, eine Klasse Idee. Jedoch gebe ich zu, dass ich mich mit der programmierung von Jabber-Programmen nicht auskenne.tabellar hat geschrieben:Wie gesagt, ich wollte Euch mal meine Gedanken und Tests mitteilen. Ich bin gerade eben an einem Thema dran, wo die Themen des Zugriffs und der Schnittstellen eher zweitrangig sind. Da muss ich erst noch ganz andere Dinge intern knacken. Ich sehe das ganze so, dass die Schnittstellen, egal ob Socket Verbindung (asynchore), Datei oder Jabber Schnittstellen eben NUR Interfaces sind. Es gibt dann eben trotzdem diverse andere interen Komponenten wie zB. einen Db (SQLite) Wrapper, Session oder Eventhandler, die dann die EIGENTLICHE Arbeit machen. Mit der angesprochenen Jabber Schnittstelle konnte ich eben sehr schnell mit einem Standard Jabber Client (JAJC, Exodus) auf den laufenden Pseudo Prototyp Server "internetweit" zugreifen. Ich seh ob er läuft (online) ist und entsprechende Meldungen oder Logs postet er mir an den entsprechenden Jabber Client, mit dem ich irgendwo im Internet angemeldet bin...
Klar, aber dazu bräuchte man doch einen Jabber Server. Und wenn ich einen SQL Server brauche, dann sollte es doch keine Vorraussetzung sein, dass ich einen Jabber Server habe. VOr allem Erfordert ein Jabber Server natürlich auch wieder Administration.tabellar hat geschrieben:Also, um unabhängig zu sein, ist natürlich eine Lösung mit asynchore ideal. Hat man einen eigenen Jabber Server, kann man von dem die Dienste für die connections und die Userverwaltung der einzelnen "Agents" verwenden. Gerade bei der Agenten Entwicklung finde ich SQLite ideal, da es sehr klein und leistungsfähig ist und nicht unbedingt ein grosser Datenbank Server sein muss.
Gut. Ich habe mir auch noch folgendes überlegt:tabellar hat geschrieben:Eine gscheite und gschickte Lösung ist natürlich immer gut und natürlich anzustreben...
Wir kommen langsam an den Punkt, an dem ich gerade rumhirne ...Leonidas hat geschrieben:Gut. Ich habe mir auch noch folgendes überlegt:
- Ein Kern (muss keine Netzwerkfähigkeiten beinhalten, sondern nur das bereitstellen was alle Transports brauchen (könnten), wie zum Beispiel eine Userdatenbank mit jeweiligen Rechten)
- Transports (greifen auf Kern zu, haben dort praktisch Superuserrechte, also dürfen sie alles und sie erlauben hat den Benutzern den Zugriff, oder eben nicht).
- Sonstiges: Vielleicht kann man die Userverwaltung auch noch auskoppeln.
Jetzt bleibt die Frage, wie greifen die Transports auf den Kern (oder das "Sonstige") zu:
Das ist natürlich eine tolle Sache, nur wird sowas schnell kompliziert und je komplizierter, desto schwieriger und aufwendiger zu implementieren. Und Anfällig wird sowas auch gerne.tabellar hat geschrieben:Services wären also wie folgt:
- Data Manager
- User Manager
- client to server (c2s)
- Log Komp.
Transport Backbone [Kern]:
- Message Switch/Router
- Event Manager
- ...
Naja, die Transportschicht wäre, wenn alle Services auf einem Server laufen, recht stabil. Also mit der flexibilität sollte man auch nicht übertreiben, denn man kann sie ja erweitern, das ist das tolle an Python. Fremdmodule sind zu vermeiden (besonders C-Erweiterungen), aber wenn sie viel helfen ist das auch in Ordnung.tabellar hat geschrieben:Also, die Hauptknacknuss ist die Transportschicht zwischen den Services. Wie flexibel muss sie sein, wie schnell, wie stabil, DB Logging? Fremdmodule?![]()
Mit "Transportschicht" habe ich nicht unbedingt damit gemeint, dass die Services auf unterschiedlichen Rechnern laufen, sonder wie der Aufruf von Funktionen innerhalb des Programmes gehandelt wird. Sprich, ob hard codiert oder "etwas flexibler". Also gut, bleiben wir einfachLeonidas hat geschrieben:Das ist natürlich eine tolle Sache, nur wird sowas schnell kompliziert und je komplizierter, desto schwieriger und aufwendiger zu implementieren. Und Anfällig wird sowas auch gerne.
Naja, die Transportschicht wäre, wenn alle Services auf einem Server laufen, recht stabil. Also mit der flexibilität sollte man auch nicht übertreiben, denn man kann sie ja erweitern, das ist das tolle an Python. Fremdmodule sind zu vermeiden (besonders C-Erweiterungen), aber wenn sie viel helfen ist das auch in Ordnung.tabellar hat geschrieben:Also, die Hauptknacknuss ist die Transportschicht zwischen den Services. Wie flexibel muss sie sein, wie schnell, wie stabil, DB Logging? Fremdmodule?![]()
Nein, aber ich vermute das wäre auch ein Fall für asynchat.tabellar hat geschrieben:Hast Du schon asyncore Erfahrungen?
Code: Alles auswählen
#!/usr/bin/env python
# -*- encoding: latin-1 -*-
"""SQLatorD - the SQLator daemon
2005-06-24: A quick dirty TCP-Socket server for SQLite by Tabellar
2005-06-13: A XML-RPC server for the SQLite database by Leonidas
"""
import socket
from pysqlite2 import dbapi2 as sqlite
class SQLator(object):
def __init__(self):
self.port=8082
self.dbfile="testdb.sqlite"
try:
self.con=sqlite.connect(self.dbfile)
print "SQLiteDB '" + self.dbfile + "' connected..."
except:
print "SQLiteDB " + self.dbfile + " connection failed..."
def run(self):
"""---"""
self.run=1
self.sock=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.bind(("",self.port))
print "SQLatorD waiting on port:", self.port
while self.run:
data,addr = self.sock.recvfrom(1024)
#addr=Tupel ("text",portnr)
try:
result=self.sqlExecute(data)
print str(result)
self.sendData(str(result),addr)
except:
print "Abfragefehler..."
self.sendData("Abfragefehler...",addr)
def sqlExecute(self,sql):
cur=self.con.cursor()
cur.execute(sql)
resultList=cur.fetchall()
self.con.commit()
return resultList
def sendData(self,data,addr):
BUFSIZE = 1024
while data:
self.sock.sendto(data[:BUFSIZE], addr)
data = data[BUFSIZE:]
def main():
sqls=SQLator()
sqls.run()
if __name__ == '__main__':
main()
Code: Alles auswählen
#!/usr/bin/env python
# -*- encoding: latin-1 -*-
"""SQLatorC - the SQLator client
2005-06-24: A TCP-Socket client for the SQLator Daemon by Tabellar
2005-06-13: A client for the SQLator Daemon, for using SQLite over network by Leonidas
"""
import socket,sys
port = 8082
host = "localhost"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", 0))
intro = """SQLator remote shell
Enter ".help" for instructions"""
def dotparse(command):
if command == 'quit':
s.close()
sys.exit()
elif command == 'help':
help()
else:
print 'No such command'
def help():
helptext = {'.help' : 'Show this message',
'.quit' : 'Exit this program'}
for key in helptext.keys():
print key, helptext[key]
#print textwrap.wrap(helptext)
def sendQuery(query):
s.sendto(query, (host, port))
data=''
BUFSIZE=1024
while BUFSIZE==1024:
sockData=s.recv(1024)
data=data+sockData
BUFSIZE=len(sockData)
return data
def main():
print intro
while True:
query = raw_input('sqlator> ')
if query.startswith('.'):
# parse, without the dot
dotparse(query[1:])
else:
print sendQuery(query)
if __name__ == '__main__':
main()
C:\Programme\sqlator>SQLatorD.py
SQLiteDB 'testdb.sqlite' connected...
SQLatorD waiting on port: 8082
[(1, None, 0, u'test Workflow', 1, 0)]
[(1, None, 0, u'test Workflow', 1, 0)]
Ich hätte nie gedacht, dass ich das mal hinbekommen würde ...Gentux1 root # python SQlatorC.py
SQLator remote shell
Enter ".help" for instructions
sqlator> select * from twfInst;
[(1, None, 0, u'test Workflow', 1, 0)]
sqlator>
Bei der Geschichte melde ich mal Interesse an.tabellar hat geschrieben:...Ich bin gerade an einem Thema dran, wo ich einen richtig schnellen, threadsicheren Server mit vielen DB Zugriffen brauchen könnte, aber natürlich in Python. Es geht um "Reaktive Systeme" (EventHandling) und "Workflowmanagement" und entsprechend vielen DB Zugriffen. Vielleicht mach ich dazu mal einen Thread in "Showcase" oder "Ideen" auf. Gibt's vielleicht den einen oder anderen Interessenten ? Ich würd mich freuen!!!
Tabellar
Hallo querdenker,querdenker hat geschrieben:Bei der Geschichte melde ich mal Interesse an.
Und hab auch noch einen Vorschlag für die DB: FirebirdSQL
Wir haben das DB-System im Dauereinsatz, Installation ist sowohl unter Win* als auch unter Unix einfach und klein (ca 10 MB).
Und die Python-Seite ist mit KInterbasdb auch gut unterstützt.
mfg, querdenker
@querdenker:querdenker hat geschrieben:@tabellar:
Interesse besteht eigentlich in allen 3 Bereichen, d.h. EventManagment, Workflow und DB.
Magst du mir mal ein wenig mehr darüber erzählen?
mfg, querdenker
Ich würde vermutlich einfach mal draufloshacken und gucken was gerade nötig ist. Wenn ich mal wieder Zeit habe (und diese Woche ist ziemlich stressig) könnte ich mal versuchen einen Proof-of-Concept zu schreiben.tabellar hat geschrieben:Beim SQLator würdest Du ja gerne die Socket Geschichte mit XML-RPC verbinden. Das würde aber auch bedeuten, dass der Server entsprechende "Objektmethoden" zur Verfügung stellen müsste. Wie und was würdest Du Dir da vorstellen?
Ich hab schon mal "etwas" vorgegriffen und eine einfache XML-RPC-Socket Version gebasteltLeonidas hat geschrieben:Ich würde vermutlich einfach mal draufloshacken und gucken was gerade nötig ist. Wenn ich mal wieder Zeit habe (und diese Woche ist ziemlich stressig) könnte ich mal versuchen einen Proof-of-Concept zu schreiben.
Code: Alles auswählen
#!/usr/bin/env python
# -*- encoding: latin-1 -*-
"""SQLatorD - the SQLator daemon
2005-06-30: A quick dirty XML-RPC Socket Server by Tabellar
2005-06-24: A quick dirty TCP-Socket server for SQLite by Tabellar
2005-06-13: A XML-RPC server for the SQLite database by Leonidas
"""
import socket
import xmlrpclib
from pysqlite2 import dbapi2 as sqlite
class SQLator(object):
def __init__(self):
self.port=8082
self.dbfile="testdb.sqlite"
try:
self.con=sqlite.connect(self.dbfile)
print "SQLiteDB '" + self.dbfile + "' connected..."
except:
print "SQLiteDB " + self.dbfile + " connection failed..."
def run(self):
"""---"""
self.run=1
self.mainsock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.mainsock.bind(("",self.port))
self.mainsock.listen(1) #max 1 Verbindung gleichzeitig
print "SQLatorD waiting on port:", self.port
while self.run:
connection,address=self.mainsock.accept()
print "Server connected by ",address
while 1:
data = connection.recv(1024)
if not data: break
print "received: ",data
params,method=xmlrpclib.loads(data)
print "Method:",method
print "Params:",params
try:
if method=="selectCurFetchAll":
result=self.selectCurFetchAll(params)
response=xmlrpclib.dumps(((str(result[0])),(str(result[1]))),"selectCurFetchAll")
connection.send(response)
else:
connection.send("Methode nicht erkannt")
except:
print "Abfragefehler..."
connection.send("Abfragefehler...")
print "connection closed..."
connection.close()
def selectCurFetchAll(self,sqlquery):
cur=self.con.cursor()
cur.execute(str(sqlquery[0]))
resultList=cur.fetchall()
self.con.commit()
return resultList
def main():
sqls=SQLator()
sqls.run()
if __name__ == '__main__':
main()
Code: Alles auswählen
#!/usr/bin/env python
# -*- encoding: latin-1 -*-
"""SQLatorD - the SQLator daemon
2005-06-30: A simple quick dirty XML-RPC Socket Connection by Tabellar
"""
import socket
import xmlrpclib
#socket connection
port = 8082
host = "localhost"
con=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
con.connect((host,port))
#xml-rpc Input
Method="selectCurFetchAll"
Param=("select * from twfInst;")
#xmlrpclib "dumps"
request=xmlrpclib.dumps(((Param),),methodname=Method)
#xml-rpc-String
"""<?xml version='1.0'?>
<methodCall>
<methodName>selectCurFetchAll</methodName>
<params>
<param>
<value><string>select * from twfInstNode;</string></value>
</param>
</params>
</methodCall>"""
#Server XML-RPC Request
con.send(request)
#Server XML-RPC Response
data=con.recv(1024)
#xmlrpclib "loads"
param,method=xmlrpclib.loads(data)
#Print der Daten
print
print "Methode:", method
print "Input :", Param
for i in param:
print "Output :", i
#Connection schliessen
con.close()
TabellarC:\Programme\sqlator>RPCSQLatorC.py
Methode: selectCurFetchAll
Input : select * from twfInst;
Output : (1, None, 0, u'test Workflow', 1, 0)
Output : (2, None, 0, u'test', 123, 0)
Ich verwende auußer PySQLite nur Pyro und das ist kein C-Modul, somit kann man es auch mit einpacken ohne dass es jegliche Probleme macht (und so groß ist pyro) auch nicht.tabellar hat geschrieben:Mir kommt das ganze ein bisschen überladen vorMir ist noch nicht so ganz klar, warum du hier so viele Frameworks verwendest. Ich hab das ganze mal überflogen, aber noch nicht getestet. Ich bin kein Freund des endlosen Modul-Importierens...
Theoretisch schon, jedoch können aktuell auch mehrere Server gleichzeitig laufen ohne sich ins gehege zu kommen, mit einem einfach bereitgestellten con-Objekt wäre ich mir da gar nicht so sicher. Außerdem könnte SQLatorB zukünftig auch eine User-Datenbank bereitstellen, dietabellar hat geschrieben:Was genau soll Pyro bewirken? Das SQLatorB öffnet ja die DB und stellt anschliessend eine Pyro Objekt zur Verfügung. Reicht hier nicht einfach das Bereitstellen eines Connection Objektes(von pysqlite)???
Ja, das war nur so zum testen ob es geht gedacht und kann sehr schnell korrigiert werden.tabellar hat geschrieben:Die Asyncore/Asynchat Geschichte im SQLatorD gefällt mir ganz gut. Was mich ein wenig an deiner "allgemeinen XML-RPC" Verwendung stört, ist die allgemeine execute Funktion, die letztendlich die cur.fetchall() des Connection Objektes aufruft. Es gibt aber auch noch andere "Connection.Cursor Funktionen" ...Die Thematik habe ich bei meiner Socket/XML-RPC Version oben mal aufgezeigt.
Den Socket/Queue und Threading server darfst du gerne schreiben.. womit du zwar die Funktionalität von Pyro kopierst, aber wenn du magst...tabellar hat geschrieben:Ich finde, das ganze sollte "leichtgewichtig" sein mit nicht zu vielen "import Modulen". Maximal Socket, Asyncore, Asynchat, PySQLite. Eine Alternative dazu wäre auch eine Variante mit SocketServer, Threading und Queue... (Clientverwaltung in jeweils einem eigenen Thread + Lock Mechanismus auf die Single-User-Datenbank ).
Nun, auch wenn mehrere Server laufen würden, hätten diese auch nur ein "Connection" Objekt, welches sie von PySQLite erhalten. Sprich die Thematik für den Zugriff auf dieselbe DB wird dadurch nicht einfacher, sondern schwerer, weil die DB Zugriffe nicht mehr zentral gehandelt werden.Leonidas hat geschrieben:Theoretisch schon, jedoch können aktuell auch mehrere Server gleichzeitig laufen ohne sich ins gehege zu kommen, mit einem einfach bereitgestellten con-Objekt wäre ich mir da gar nicht so sicher. Außerdem könnte SQLatorB zukünftig auch eine User-Datenbank bereitstellentabellar hat geschrieben:Was genau soll Pyro bewirken? Das SQLatorB öffnet ja die DB und stellt anschliessend eine Pyro Objekt zur Verfügung. Reicht hier nicht einfach das Bereitstellen eines Connection Objektes(von pysqlite)???
Ich hab da schon ein paar ganz gute BeispieleLeonidas hat geschrieben:Den Socket/Queue und Threading server darfst du gerne schreiben.. womit du zwar die Funktionalität von Pyro kopierst, aber wenn du magst...
Spassig ist dies ja allemal, und sich die Dinge anzuschauen bringt einen ja auch immer einen Schritt weiter...Leonidas hat geschrieben:Gut dass ich dir nicht noch den xmlrpcd_twisted gezeigt habe, der ist kompatibel zum asyncore Server, benötigt aber noch Twisted *g* (und war dank Pyro und dem LayerServer in einer Stunde fertig).
Doch, die Zugriffe laufen alle über SQLiteB und werden somit zentral gehandhabt.tabellar hat geschrieben:Nun, auch wenn mehrere Server laufen würden, hätten diese auch nur ein "Connection" Objekt, welches sie von PySQLite erhalten. Sprich die Thematik für den Zugriff auf dieselbe DB wird dadurch nicht einfacher, sondern schwerer, weil die DB Zugriffe nicht mehr zentral gehandelt werden.Leonidas hat geschrieben:Theoretisch schon, jedoch können aktuell auch mehrere Server gleichzeitig laufen ohne sich ins gehege zu kommen, mit einem einfach bereitgestellten con-Objekt wäre ich mir da gar nicht so sicher. Außerdem könnte SQLatorB zukünftig auch eine User-Datenbank bereitstellentabellar hat geschrieben:Was genau soll Pyro bewirken? Das SQLatorB öffnet ja die DB und stellt anschliessend eine Pyro Objekt zur Verfügung. Reicht hier nicht einfach das Bereitstellen eines Connection Objektes(von pysqlite)???
Naja, ich verwende ganz gerne Sachen die schon funktionieren und sich erprobt haben, besonders wenn man dabei keine Nachteile hat.tabellar hat geschrieben:Ich hab da schon ein paar ganz gute BeispieleLeonidas hat geschrieben:Den Socket/Queue und Threading server darfst du gerne schreiben.. womit du zwar die Funktionalität von Pyro kopierst, aber wenn du magst...... Aber mir geht es gar nicht darum Pyro zu kopieren, sondern die Netzwerk Thematik besser verstehen zu lernen... Dies ist auch der Grund, warum ich mir andere Frameworks nicht gleich zu Nutze machen möchte.
Okay. Ich stell den online, wenn ich wieder zuhause bin. Du wirst sehen, dass der praktisch genauso funktioniert wie die async-Variante, also auch mit Factories und Protocols und XML-RPC kodierten Aufrufen. War ja auch praktisch ein Async-Port auf Twisted, mehr nicht.tabellar hat geschrieben:Spassig ist dies ja allemal, und sich die Dinge anzuschauen bringt einen ja auch immer einen Schritt weiter...Leonidas hat geschrieben:Gut dass ich dir nicht noch den xmlrpcd_twisted gezeigt habe, der ist kompatibel zum asyncore Server, benötigt aber noch Twisted *g* (und war dank Pyro und dem LayerServer in einer Stunde fertig).![]()