Minimal Reproducible Example:
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
Observed behavior:
- If I press
Lbefore any write transactions are made then both instances agree. - In one of the instances I press
Aand add an employee with name (say)foo. In that instance pressingLcorrectly reflects the write transaction. However in the other instance pressingLshows only the old version of the database. - If I quit
Qthe lagging instance and restart it then it shows the correct state of the database.
Expected behavior:
Both instances should be aware of transactions made by the other.
Notes:
- I have set
server_sync = Truewhile makingstorage = ClientStorage(('localhost', 9999), server_sync = True). But this doesn't fix. - I also tried to set
cache_size = 0but that didn't fix it either. - On a
Ubuntu 22.04.1 LTSmachine with the package versions:ZEO==5.4.0,ZODB==5.8.0andPython==3.10.6.
Please help. The documentation of ZEO server is terse and somewhat difficult to follow.
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.