Hi all,
I've started to play with rpyc as it looks like it will fit
what I need very well and I've been very impressed so far, however I
have come up with one slight inconsistency which I can't quite figure
out so I'm hoping someone here may be able to :)
The problem in a nutshell is a discrepency between how long an
asynchronous connection takes to return on a UNX like system compared
to a win32 system. For simplicty sake we can take the two blobs of
example code from the tutorial on the website as your server and
client (though the problem is there in other client server code also)
with the addition of a simple timer to see how long the call to
'conn.root.FileMonitor' takes (obviously swapping out the location of
the temp file depending on *nix/win32):
<snip server>
import rpyc
import os
import time
from threading import Thread
class FileMonitorService(rpyc.Service):
class exposed_FileMonitor(object): # exposing names is not
limited to methods :)
def __init__(self, filename, callback, interval = 1):
self.filename = filename
self.interval = interval
self.last_stat = None
self.callback = rpyc.async(callback) # create an async
callback
self.active = True
self.thread = Thread(target =
self.work)
self.thread.start()
def exposed_stop(self): # this method has to be exposed too
self.active = False
self.thread.join()
def work(self):
while self.active:
stat = os.stat(self.filename)
if self.last_stat is not None and self.last_stat !=
stat:
self.callback(self.last_stat, stat) # notify the
client of the change
self.last_stat = stat
time.sleep(self.interval)
if __name__ == "__main__":
from rpyc.utils.server import ThreadedServer
ThreadedServer(FileMonitorService, port = 18871).start()
</snip server>
<snip client>
import rpyc, time
#win32
f = open("c:\\Users\\username\\AppData\\Local\\temp\\floop.bloop",
"w")
#nix
#f = open("/tmp/floop.bloop", "w")
conn = rpyc.connect("localhost", 18871)
bgsrv = rpyc.BgServingThread(conn) # create a bg thread to process
incoming events
def on_file_changed(oldstat, newstat):
print "file changed"
print " old stat: %s" % (oldstat,)
print " new stat: %s" % (newstat,)
st = time.time()
#win32
mon = conn.root.FileMonitor("c:\\Users\\username\\AppData\\Local\\temp\
\floop.bloop", on_file_changed)
#nix
#mon = conn.root.FileMonitor("/tmp/floop.bloop", on_file_changed)
print "Time to connect:",time.time()-st
</snip client>
When this is run over local host on a win32 system the time it takes
for the call to return is roughly 0.5 secs and this is a consistent
number.
However when the same code is run on a nix system the time taken can
vary wildly, in my tests this has been between 1 and 290 seconds!!
I have tested this across a variety of different *nix & win32 systems
using both python 2.5 & 2.6 with the same effect always happening
(win2k, xp, vista, ubuntu, gentoo, fedora, OS X).
So my question is obvious - what the heck is going on!!
My initial thoughts were something to do with the GIL, threads &
scheduling across multiple cores as my nix boxes all had more than one
core (I tested on 2, 4 and 8 cores) & the windows boxes were only
single cores, but I get the same results when I try a Linux VM with a
single core ? So I'm stumped :(
Can other people reproduce this behaviour, and if so any ideas on how
to fix it?
Many thanks
Rich