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