Reputation: 2438
For minimal reproducible example consider this:
I first start a ZEO server with the command: runzeo -C zeo.conf
. The following are the contents of my zeo.conf
:
<zeo>
address 127.0.0.1:9999
</zeo>
<filestorage>
path /path/to/testing.fs
</filestorage>
Then I create two connections to this ZEO server by running python employees.py
twice on separate terminals. The contents of employees.py
are:
import persistent
from ZODB import DB
from ZODB.FileStorage import FileStorage
import transaction
from ZEO.ClientStorage import ClientStorage
class Employees(persistent.Persistent):
def __init__(self,name=None):
self.name=name
def list_employees():
return employees.keys()
def add_employee(name):
if name != "" and name not in list_employees():
employees[name] = Employees(name)
root['employees'] = employees
transaction.commit()
storage = ClientStorage(('localhost', 9999), server_sync = True)
db = DB(storage)
connection = db.open()
root = connection.root()
if "employees" not in root:
root["employees"] = {}
employees=root["employees"]
while True:
choice=input("Press:\n"
"'L' to list employees,\n"
"'A' to add an employee,\n"
"'Q' to quit: ")
choice=choice.lower()
if choice=="l":
print(list_employees())
elif choice=="a":
name=input("Employee name: ")
with transaction.manager:
add_employee(name)
elif choice=="q":
break
L
before any write transactions are made then both instances agree.A
and add an employee with name (say) foo
. In that instance pressing L
correctly reflects the write transaction. However in the other instance pressing L
shows only the old version of the database.Q
the lagging instance and restart it then it shows the correct state of the database.Both instances should be aware of transactions made by the other.
server_sync = True
while making storage = ClientStorage(('localhost', 9999), server_sync = True)
. But this doesn't fix.cache_size = 0
but that didn't fix it either.Ubuntu 22.04.1 LTS
machine with the package versions: ZEO==5.4.0
, ZODB==5.8.0
and Python==3.10.6
.Please help. The documentation of ZEO server
is terse and somewhat difficult to follow.
Upvotes: 0
Views: 42
Reputation: 1427
Instead of using normal dict you should use PerstitentMapping (or BTree) to store your employees else the object you edit would be local a local copy that you manipulate in both clients. In your code that copy would only be refreshed if you restart a client. The problem get even worse with your code the last client that writes overwrites all other clients states with it own local copy. See the comments for the changes needed to fix the problem.
import persistent
from ZODB import DB
from ZODB.FileStorage import FileStorage
import transaction
from ZEO.ClientStorage import ClientStorage
class Employees(persistent.Persistent):
def __init__(self,name=None):
self.name=name
def list_employees():
#convert KeyView to list
return list(employees.keys())
def add_employee(name):
if name != "" and name not in list_employees():
employees[name] = Employees(name)
storage = ClientStorage(('localhost', 9999), server_sync = True)
db = DB(storage)
connection = db.open()
root = connection.root()
if "employees" not in root:
with transaction.manager:
#use persitent mapping instead of normal dict
root["employees"] = persistent.mapping.PersistentMapping()
employees=root["employees"]
while True:
choice=input("Press:\n"
"'L' to list employees,\n"
"'A' to add an employee,\n"
"'Q' to quit: ")
choice=choice.lower()
if choice=="l":
#always use transaction
with transaction.manager:
print(list_employees())
elif choice=="a":
name=input("Employee name: ")
with transaction.manager:
add_employee(name)
elif choice=="q":
break
Upvotes: 0