Threading to processing on the server... FAR too easy.
Something is wrong; someone has pulled a fast one on me, I swear, because switching my TCP server over from threading to processing (forking) was ridiculously simple.
All I did (aside from changing the class names themselves) was swapping ThreadingMixIn with ForkingMixIn for my TCPServer extension class… and holy crap, it runs perfectly. Watched top to see the processes get spawned, ran a few different clients and connected happily.
Holy crap. :)
Granted, this has nothing to handle concurrency at the moment (all the actual work beyond setting up the server to accept connections has been on the client side), but I’ve already largely wrapped my head around doing that with processing/multiprocessing, so that won’t be such a major undertaking.
This isn’t a huge accomplishment in terms of deliverables or anything, but it’s pretty cool to see something major like this just up and work.
Multiproc woes
Well, I think I’ve figured out the infuriating problems I’ve been butting my head against with multiprocessing.
Turns out I can send and update objects and get them back with the changes intact, and I can send and update lists with the same kind of success… but I can’t send and update a list of objects, update the objects, and expect to get them back with their state updated.
So it looks like my ideal scenario of having a simple execution stack containing (among other things) a map object that tracks its tiles as a list is not going to work. I do think I can still use the stack for menus; if I’m recalling correctly (it was late last night), I can modify an object and update it by copying, modifying and replacing it in its list (which is stupid, inefficient and maddening, but works).
I’d like to see if processing or parallelpython can handle this scenario… but I’ve already burned so much time figuring it out in multiprocessing that I’m not too thrilled with the idea of trying to abandon it.
Either way… I did manage to get the input process passing commands to the top element of the execution stack, it just didn’t work as expected because of multiprocessing’s apparently-undocumented restriction on how many nested levels of data (about… one) you can depend on sharing between processes.
Multiprocess command input
Well, this multiprocessing crap ROCKS, but man does it make things… interesting.
After wrestling with a serialization issue, I realized I can’t keep a lock as an instance variable on an object I need to pass between processes; I should have figure that out sooner, but I had written it to work with threading, which doesn’t have this particular quirk.
Now I’m working on getting a sensible method of passing events out of the input thread and determining where best to process them; I knew it’d be a little hairy, but it looks like I either made some questionable decisions early on about where to implement things or just did so with the (now forgotten) intention of moving them later on, because I’m left wondering whether actor movement should really be handled by actors themselves or by the maps they are associated with, and how much graphical information the actor should keep about itself — it needs to track its own sprite sheet, but as far as rendering, I think I need to introduce a generic processor in the GUI thread to handle this.
So at this point I’m largely working on juggling code to put things in places that make sense, with the objective of successfully passing commands from the input thread to the GUI thread in a way that correctly and efficiently invokes the required functionality, and (when necessary) passes it back to the server as well.
