0 Replies - 1062 Views - Last Post: 18 March 2012 - 09:10 AM Rate Topic: -----

#1 Nekroze  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 170
  • Joined: 08-May 11

Threaded server event loop?

Posted 18 March 2012 - 09:10 AM

Using Pyro4 i have made a server for a game i am trying to make, i need to do curtain things multiple times a second as well as handle client input and execute client commands while remaining responsive.

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())[2] if not ip.startswith("127.")][0]
		
		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())[2] if not ip.startswith("127.")][0]

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?

Is This A Good Question/Topic? 0
  • +

Page 1 of 1