DingZh
DingZh

Reputation: 69

ZODB with lightweight web server

For academic purpose, I need to develop a demonstrative application of using ZODB together with some lightweight web server, say CherryPy. ZODB is used in read-only manner. Clients query the server-side ZODB. The server is supposed to "have multiple processes accessing a ZODB concurrently".

Zope documentation says "ZEO is the only way to have multiple processes accessing a ZODB concurrently." But how should I understand and implement this ZEO thing?

For the sake of clarity I wrote some code, just a simple TCP server:

import SocketServer
import ZODB
from ZEO import ClientStorage
from ZODB.DB import DB

addr = ('localhost', 9999)
storage = ClientStorage.ClientStorage(addr)
zdb = DB(storage)

# or the following method:

# import ZODB.config
# zdb = ZODB.config.databaseFromURL('zeo.conf')

class MyTCPHandler(SocketServer.BaseRequestHandler):
    def ZODBThing(self, rec_id):
        con = zdb.open()
        records = con.root()['records']
        buff=records[int(rec_id)]
        con.close()
        return buff

    def handle(self):
        self.data = self.request.recv(1024).strip()
        self.request.sendall(str(self.ZODBThing(self.data)))

if __name__ == "__main__":
    HOST, PORT = "localhost", 9998
    server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
    server.serve_forever()
    zdb.close()
    storage.close()

Upvotes: 0

Views: 215

Answers (1)

sdupton
sdupton

Reputation: 1879

You do not need ZEO for a single process that opens multiple connections and handles concurrency through one connection-per-thread. With FileStorage (instead of ClientStorage) you can do a single-process with your example code above, since you have only one ZODB.DB.DB object per application.

However, once you get more than trivial traffic, Python's scaling model typically does not work well with many threads in one process (due to Global Interpreter Lock) -- you typically want some number of processes on a single host to take advantage of multiple CPU cores, at which point you need either something like ZEO or RelStorage as a back-end for multiple processes to share the same database.

Note: at any scale, too, you likely want to use connection pooling of some sort (just reuse them, only one at a time) instead of creating a connection on each request.

Upvotes: 1

Related Questions