views:

38

answers:

2

I am new to network programming but old to Python. I have a simple blotter program that is to be used on multiple client computers. The blotter works two ways, it can show and update the information in the database. To avoid any blotters showing old data, how can I make all blotters re-fetch information from the database as soon as another blotter has updated some data in the database?

I would rather like to avoid complexity in setting up some client-server protocol. Is it possible to create some form of client-only protocol where a simple refresh message is passed along straight to the other blotters when they need to update their information?

A: 

You could use triggers. When an information is updated send a signal (is up to you choose how, maybe just an udp packet) to all blotters that will update their information consequentially. Postgresql could be scripted using python.

mg
A: 

To receive messages (e.g. the UDP package suggested by the other poster or an http request), the clients would have to run a basic server on the client machine. You could use the Python xmlrpc module for example. However, a local firewall may block the inward communication.

The easiest solution, if the number of clients is moderate, will be to frequently poll the database for changes: add a column "last modification time" to your drawing table and have the clients check this field. This way the clients can find out whether they need to reload the drawing without wasting too many resources.

Edit: The last modification field could either be actively updated by the client that made a change to the drawing, or automatically updated by a database trigger.

Jojo
One question, can I run a socket server (I assume that is what you are referring to) on each client (computer)? Won't I have to have one socket server, and then many possible socket clients?
c00kiemonster
Servers listen on a socket for incoming connections, clients make these connections. Of course, you can implement a single server in Python and connect to it from each client repeatedly to see if there is a message from another client, but you can do the same with the database. To avoid the frequent connections, you need a different architecture: your drawing application instances listen for incoming connections and update their drawing if they receive a message to do so. At start-up they have to subscribe to the news feed, for example by adding their address to a database table.
Jojo
In your implementation, also consider what happens if a client is down or unreachable and the messages cannot be delivered. Maybe that's why the other poster suggested UDP (instead of TCD). However, note that UDP packages can get lost. I would go with the "last modification time" solution unless there are very good reasons against it.
Jojo
The last modified solution is probably the slickest, but it also involves polling, i.e., data isn't updated realtime and there will be a lot of unnecessary queries to the database. I don't mind the code overhead of the socket solution. Is it easiest done with sockets, or should I look towards other frameworks such as Twisted? Are there any nice code examples out there?
c00kiemonster
In this particular application, sockets will be easy as the messages are very short. Have a look at http://wiki.python.org/moin/UdpCommunication , run the receiver loop in a separate thread (it blocks while waiting) and send a redraw event to your GUI instead of printing the message. Optionally, answer the server that you got the message and have the server repeat the message every 20ms because UDP packages can get lost. (After a second without answer, the server should then assume that the client was closed.)
Jojo
To avoid unnecessary redrawing because of the repeated messages, you can still check a "last modified" field after receiving a UDP package. That is, you now only ask the database whether a redraw is necessary if you received a UDP package.
Jojo
That's awesome. I managed to get one of those multicast examples to work. And you are right, it's is definitely best to implement both ways, i.e., a multicast refresh ping of sorts and then a last modified check.
c00kiemonster