Is crawling the stack "bad"? Why?
Russell Warren
russandheather at gmail.com
Mon Feb 25 10:33:19 EST 2008
> How about a dictionary indexed by by the thread name.
Ok... a functional implementation doing precisely that is at the
bottom of this (using thread.get_ident), but making it possible to
hand around this info cleanly seems a bit convoluted. Have I made it
more complicated than I need to? There must be a better way? It sure
is a heck of a lot less straightforward than having a reasonably tight
CrawlUpStackToGetClientIP function call. But then nothing is more
straightforward than a simple goto, either...
So I ask again, what is wrong with crawling the stack?
> What happens if you want to switch to pypy?
If it doesn't work if I decide to switch implementations for some
reason, I just fix it when my unit tests tell me it is busted. No?
Aren't there also python implementations that don't have threadign in
them that would file using thread.get_ident? Seems hard to satisfy
all implementations.
> the threading.local class seems defined for that purpose, not that I've ever
> used it ;)
I hadn't heard of that... it seems very useful, but in this case I
think it just saves me the trouble of making a stash dictionary...
unless successive calls to threading.local return the same instance?
I'll have to try that, too.
---
import xmlrpclib, threading, sys, thread
from SimpleXMLRPCServer import SimpleXMLRPCServer, \
SimpleXMLRPCRequestHandler
class RpcContainer(object):
def __init__(self):
self._Handlers = {} #keys = thread IDs, values=requestHandlers
def _GetRpcClientIP(self):
connection = self._Handlers[thread.get_ident()].connection
ip = connection.getpeername()[0]
return ip
def WhatIsMyIP(self):
return "Your IP is: %s" % self._GetRpcClientIP()
class ThreadCapableRequestHandler(SimpleXMLRPCRequestHandler):
def do_POST(self, *args, **kwargs):
#make the handler available to the RPCs, indexed by threadID...
self.server.RpcContainer._Handlers[thread.get_ident()] = self
SimpleXMLRPCRequestHandler.do_POST(self, *args, **kwargs)
class MyXMLRPCServer(SimpleXMLRPCServer):
def __init__(self, RpcContainer, *args, **kwargs):
self.RpcContainer = RpcContainer
SimpleXMLRPCServer.__init__(self, *args, **kwargs)
class DaemonicServerLaunchThread(threading.Thread):
def __init__(self, RpcServer, **kwargs):
threading.Thread.__init__(self, **kwargs)
self.setDaemon(1)
self.server = RpcServer
def run(self):
self.server.serve_forever()
container = RpcContainer()
rpcServer = MyXMLRPCServer( \
RpcContainer = container,
addr = ("", 12390),
requestHandler = ThreadCapableRequestHandler,
logRequests = False)
rpcServer.register_function(container.WhatIsMyIP)
slt = DaemonicServerLaunchThread(rpcServer)
slt.start()
sp = xmlrpclib.ServerProxy("http://localhost:12390")
print sp.WhatIsMyIP()
More information about the Python-list
mailing list