Software Design Lecture Notes Fall 2004 More Tips on Chatters and Rooms ------------------------------- A Chatter is both a Gui and a RemoteObject, which means that it needs to run both mainloop and requestLoop. But with only one thread, you can't run both at the same time. That's why RemoteObject has an alternative method named threadLoop that creates a new Thread and runs stoppableLoop in the background. You can run both loops concurrently like this: chat = Chatter() chat.setup() chat.join_room(room_name) chat.threadLoop() chat.mainloop() If you create a Chatter, you have to run requestLoop or threadLoop. Otherwise when the Room tries to call back, it will hang for a while trying to talk to an object that's not listening. To make my Room more robust, I modified it so that it creates a new thread every time it contacts a Chatter. That way if one Chatter misbehaves, it doesn't slow down the others. Here's what it looks like: run_in_thread(chatter.display_message, message) You should have a copy of run_in_thread somewhere, but here it is again: def run_in_thread(function, *args): thread = Thread(target=function, args=args) thread.start() return thread Debugging --------- Debugging distributed programs is hard. Here are some tips that might help. 1) I suggest writing Room and Chatter in separate files and running them in separate windows. 2) try statements are useful for handling predictable errors, but they can make you lose information if an unexpected error happens inside an except clause, you can get information about what happened by calling sys.exc_info(). It returns a tuple, so the usual way to call it is: (type, value, traceback) = sys.exc_info() type is the type of Exception value is additional information about the Exception traceback is information about where the Exception occurred You can run this example in an interpreter: import sys try: 1/0 except: (type, value, traceback) = sys.exc_info() print type print value print traceback 3) If an error occurs when you are running an remote method, the Exception is packaged and sent back over the network to the client. So if you see an exception while you are running Chatter, the exception may have occurred while executing code in Room! 4) If you are having a hard time getting Chatter to work, try writing a simpler program like RoomClient that just a) looks up a Room, but doesn't join, and b) invokes send_message on the Room That way you can debug the Chatter-Room communication without having a working Chatter. 5) Be nimble in your approach to debugging. Remember that there are three ways to debug: a) collect more data b) think about the data you have c) examine the code If you are stuck in just one of these modes, make a deliberate effort to shift to another. In my observations, (b) and (c) tend to get short shrift.