1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
from __future__ import print_function
import Pyro4
from database import DummyDatabase
Pyro4.config.SERVERTYPE = "thread"
database = DummyDatabase()
@Pyro4.behavior(instance_mode="single")
@Pyro4.expose
class SingletonDatabase(object):
"""
This pyro object will exhibit problems when used from multiple proxies at the same time
because it will access the database connection concurrently from different threads
"""
def __init__(self):
print("[%s] new instance and connection" % self.__class__.__name__)
self.conn = database.connect(user=None) # user is per-call, not global
def store(self, key, value):
# get the user-token from the USER annotation
ctx = Pyro4.current_context
user = ctx.annotations["USER"].decode("utf-8")
self.conn.store(key, value, user=user)
def retrieve(self, key):
# get the user-token from the USER annotation
ctx = Pyro4.current_context
user = ctx.annotations["USER"].decode("utf-8")
return self.conn.retrieve(key, user=user)
def ping(self):
return "hi"
@Pyro4.behavior(instance_mode="session")
@Pyro4.expose
class SessionboundDatabase(object):
"""
This pyro object will work fine when used from multiple proxies at the same time
because you'll get a new instance for every new session (proxy connection)
"""
def __init__(self):
# get the user-token from the USER annotation
ctx = Pyro4.current_context
user = ctx.annotations["USER"].decode("utf-8")
self.connection = database.connect(user)
print("[%s] new instance and connection for user: %s" % (self.__class__.__name__, user))
def store(self, key, value):
self.connection.store(key, value)
def retrieve(self, key):
return self.connection.retrieve(key)
def ping(self):
return "hi"
Pyro4.Daemon.serveSimple({
SingletonDatabase: "example.usersession.singletondb",
SessionboundDatabase: "example.usersession.sessiondb"
})
|