Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm new to web programming. I'm more experienced and comfortable with client-side code. Recently, I've been dabbling in web programming through Python's Google App Engine. I ran into some difficulty while trying to write some simple apps for the purposes of learning, mainly involving how to maintain some kind of consistent universally-accessible state for the application.

I tried to write a simple queueing management system, the kind you would expect to be used in a small clinic, or at a cafeteria. Typically, this is done with hardware. You take a number from a ticketing machine, and when your number is displayed or called you approach the counter for service. Alternatively, you could be given a small pager, which will beep or vibrate when it is your turn to receive service. The former is somewhat better in that you have an idea of how many people are still ahead of you in the queue.

In this situation, the global state is the last number in queue, which needs to be updated whenever a request is made to the server. I'm not sure how to best to store and maintain this value in a GAE context.

The solution I thought of was to keep the value in the Datastore, attempt to query it during a ticket request, update the value, and then re-store it with put. My problem is that I haven't figured out how to lock the resource so that other requests do not check the value while it is in the middle of being updated. I am concerned that I may end up ticket requests that have the same queue number. Also, the whole solution feels awkward to me. I was wondering if there was a more natural way to accomplish this without having to go through the Datastore.

Can anyone with more experience in this domain provide some advice on how to approach the design of the above application?

share|improve this question
2  
Good job recognizing the dangers of multithreading spot on. You need a lock, every multithreading language has a way of doing this. I don't know pythons but a lock is usually placed around a block of code and that block only allows one thread at a time. other terms for locks are mutex (mutually exclusive) and semaphore. some languages don't have blocks for this and require you to manually make a shared resource grab or wait for availability then release at the end of of your mutex so the next waiting thread can accomplish it's grab. –  Jimmy Hoffa Dec 5 '12 at 18:48
add comment

1 Answer

  • Each ticket request is logged in a ticket database table that stores the unique ID of the request and the time on which the request was made.
  • Whenever it is time to service a new request, fetch the first row from the ticket database table, ordered by request time.
  • Delete the row from the database.

If the last two steps are run as a single transaction, you'll be able to have multiple agents servicing requests simultaneously without treading on each others' toes.

I'm not sure how Google AppEngine's data store works, but any decent database should give you:

  • Automatic IDs that are guaranteed to be unique;
  • Transactional queries that can lock rows required by that transaction.
share|improve this answer
    
His problem is around multiple updaters, and your solution just offloads atomicity to the db, which is valid but not what's being asked for. –  Jimmy Hoffa Dec 5 '12 at 18:55
    
True, but the question was "how to approach the design of the above application" rather than "I've finalised my design but now need to handle mutexes in Python". I think this design eliminates the mutex problem and is more powerful (it can answer questions such as "how many requests are in the queue?", "how long is the average wait to be served?", etc). A useful variation would be to add a "served by" column to the DB, rather than deleting rows, which would allow tracking of the most efficient/least efficient servers. –  Ant Dec 5 '12 at 19:05
    
I agree queueing through the DB and offloading threading troubles to it is a completely valid and oft used approach. Though if you know Python it would be nice to hear a simple explanation of the pythonic approach to mutexes since that's what he asked about, in addition to the overarching concept of using the DB's multi-threading management so you don't have to manage it yourself. –  Jimmy Hoffa Dec 5 '12 at 19:11
1  
Its more than valid, its the only solution that would scale to multiple instances, or, multiple servers. –  James Anderson Jan 15 '13 at 9:09
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.