I have made a time based event loop based server that every so many times a second, handles all Pyro4 input, executes server commands for a curtain amount of calculations (as too many will hurt the "fps" of the server) and then start the loop again.
Here is the code for the server at the moment:
#server.py import select import socket import Pyro4 import time import stackless PollingRate = 1. / 60 CalculationsPerPoll = 10000 # how many stackless calculations to make per poll class inter(object): def test(self): # scheduel task for later stackless.tasklet(self.test2)() def test2(self): print "DOING TEST AS SOON AS POSSIBLE BUT NOT IMMEDIATELY" class Server(object): def __init__(self): self.ServerIP = [ip for ip in socket.gethostbyname_ex(socket.gethostname()) if not ip.startswith("127.")] self.Interface = inter() self.daemon = Pyro4.core.Daemon(host=self.ServerIP, port=5050) self.InterfaceURI = self.daemon.register(self.Interface, "Interface") def pyro_callback(self): while True: # for as long as the pyro socket triggers, dispatch events s, _, _ = select.select(self.daemon.sockets, , , 0.01) if s: print "EVENT" self.daemon.events(s) else: # no more events, stop the loop, we'll get called again soon anyway break def start(self): print print ">>| Server Started" events = [self.pyro_callback] # run eventloop inbetween PollingRate intervals while time.sleep(PollingRate) == None: # handle events every poll, most likely scheduling them for the next part for event in events: event() # maybe do some other events per frame/poll here # execute stackless tasklets in order until CalculationsPerPoll are done then loop again t = stackless.run(CalculationsPerPoll, totaltimeout=True) if t is not None: t.insert() if __name__ == "__main__": server = Server() server.start()
Note: you will need stackless python and pyro4 to test this but its not hard to get set up at all.
Now the server and loop runs fine on its own when run but my client test shows the problem i am having.
#client.py import Pyro4 import time import socket serverIP = [ip for ip in socket.gethostbyname_ex(socket.gethostname()) if not ip.startswith("127.")] print "GETTING INTERFACE PROXY" Interface = Pyro4.Proxy("PYRO:Interface@" + serverIP + ":" + str(5050)) Interface._pyroOneway.add("test") print "USING INTERFACE" Interface.test2() print "CALLING THE FUNCTION DIRECTLY WORKED" print "NOW SCHEDULE THE FUNCTION FOR THE SERVER TO DO IT LATER" Interface.test1() print "INTERFACE USED"
Now the server works fine when calling just "Interface.test2()" which directly executes a command.
However if one calls "Interface.test()" the server crashes but does not provide a traceback to determine why.
All the "test()" function does is schedule "test2()" to be done by the stackless part of the main server loop:
t = stackless.run(CalculationsPerPoll, totaltimeout=True) if t is not None: t.insert()
But at some point, i am guessing at the above code, it comes crashing down with no indication as to why.
Has anyone worked with this kind of thing or experienced this behavior before or know how to solve this?