Frank Millman wrote:
Dave Angel wrote:
Any time I see multiple lists like that which have to stay in synch, I think code-smell.


I don't think it is that bad, but I agree there is always room for
improvement.

Why not let the EVT's be passed as strings, and avoid the whole mapping to integers and mapping back detail? And name the methods involved in a way that you can directly translate the string to the method name?


There is some merit in this. At present I am writing the server and the
client, and copy/paste the list of constants, so they are guaranteed to stay
in sync. (Maybe I should import it instead - even more fool-proof [the fool
being me, of course]).

However, it may happen that I want to open it up to 3rd-party clients in the
future, in which case I would have to publish some sort of API. It would
make more sense to identify the messages by a meaningful name rather than an
integer.

And yes, I could then use 'getattr' to retrieve the corresponding method on
the server side.

I've built such pairs of programs (not in Python), and studied the tradeoffs of various methods of coupling. Cut & Paste is probably the worst way to do it. Manual error is easy to creep in, where one copy is updated, and somebody neglects to update the other. It's especially bad if the item order matters, as it does for enums and for your xlist() example.

Shared code works okay (have a module that both ends import). But it assumes both ends are built and ship and install on a consistent basis. Not too hard when it's a single product on a single machine. But if the two ends are on separate machines, especially separated by the Internet, you have to deal with version consistency problems. If there's a time shift as well (file format), then you're stuck at that level. Check the version, and either insist on exact match, or have a way to adapt to whichever end reports the earlier version. Make no mistake, there will be new versions, and you'll have to deal with it.

Shared data is about the same, but can sometimes be more flexibly interpreted. It also can have the advantage of being able to have multiple simultaneous versions on the same machine. For the Internet case, picture a server that has to be able to serve several clients, each running different versions. And it's tougher for corruption (accidental or malicious) to do serious damage. I wouldn't want to do an import over the Internet live connection.

Best is if the necessary data is passed between the two ends during initialization, and both ends know how to make that data describe the protocol they'll use. That can work as long as there's a notion of a session, and preferably if the session is two-way. In the case of file formats, it means you have this data in the header of the file.

Sometimes for bandwidth reasons, you just want to transmit a version string, and not the entire table implied by that string. Just realize the increased risks involved.

Probably the easiest way to stay in synch is if each message is self-describing. To me that screams "text" for the id's. It makes the message a bit larger, and you have to decide if it's worth it. The overhead could very well be lost in the noise of packeting, in any tcp/ip protocol.

Note that all these have very gray boundaries. And that underneath it all, it's all just data.
Barring that, make a single "structure" which lists the event names and method names in matched pairs, and derive whatever lists and dictionaries you actually need from that one structure. And that structure should be shared between client and server code, perhaps as a text file that they both parse. Or as a stream that's passed from one to the other during startup. That way, consistency between them can be regulated (with version string in the file, for example)


I'm not sure how that would work. On the client side, I need to respond to a
'button-clicked' event from the gui system by sending an EVT_BUTTON_CLICKED
message to the server. In other words it is hard-coded into the client
program. I don't know how that would work if I read in a list of
message-types at startup.


Show me a sample client event handler, and maybe I can suggest how to encode it. For example in wxPython, events are encoded with an event object. You could have the event send the object's type-string as an event ID. No lookup at all. And in fact, one event handler then might handle several of the events for a given widget, or even for multiple ones. I guess it's not that simple, since you frequently have to pass other information, such as the state of the Ctrl-key, or the mouse position on the screen, which is not directly encoded in the event type.
DaveA


Thanks for the input - it is always good to have some fresh ideas.

Frank



--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to