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