views:

250

answers:

3

Hi,

I'm using Django to create registration/payment application for a limited number of products. I want to create a timer so that when a user chooses to purchase a product, that product will then displayed as "already taken". But, if the user the user does not go through with the purchase and the timer runs out, the product goes back to status "available". If the user completes the purchase, the timer should cancel, leaving the product's status permanently as "already taken".

I've tried using python's dictionary to instantiate python Timer objects of the fly, but about 30% of the time, I get a "key error" when it's time to cancel the Timer.

Please. Could someone give me an idea on the proper way to do this in Django?

Thanks very much!

Mark

+1  A: 

You should not use some in-process/memory timer objects since your django app can run in multiple processes...

I suggest create this "timers" in database (like "expire" datetime field for your product model) and use cron job that will mark expired objects to be available

Pydev UA
Thanks for your help!
Mark
A: 

Fork it. Have your model use three states for a product: available, taken, and purchased. When a user initiates an action that marks the product as taken, spawn a new process that will mark the product to available in 3 minutes if it is not purchased.

geowa4
Brilliant! Worked like a charm. Thanks very much for your help.
Mark
-1 Relying on the persistence of in-memory webserver processes for maintaining data integrity is a terrible idea for a web app. Not to mention the waste of memory...
Carl Meyer
Carl, rethinking the situation, I understand how this is not a full proof plan. However, considering the budget and time constraints, as well as the small scale of the project, I have to leave it as is. But next time, I will go with plan #3.
Mark
hey Carl, maybe i should have been more clear. i was not suggesting that the process keep that in memory. The three states are in the model (in the database). You update the model to be `taken`. then you spawn a *new* process that will update the model to be `available` in 3 minutes (what i meant by "Fork it"). **nothing** is in memory.
geowa4
+3  A: 

I would not use a timer for such situation because it can give some complexity. What will happen to your timers if the process is restarted. That't the case with some internet providers who restart the process on a regular basis. Maybe you are facing a similar situation.

I would add a 'taken_time' datetimefield to your table to know when the product is taken and use it in order to know if the product is available or not

The list of available products would be filled with the 'available' products and the 'taken' if their 'taken_time' is lower that (current time - accepted delay)

I think you don't really need to change the status with an external process as long as you manage it correctly in your business logic.

I hope it helps

PS: Sorry for my english! Quite late in France now and difficult for me to find simple way to explain my view :-)

luc
This answer, not the "accepted" answer, is "the proper way to do this in Django.".
Carl Meyer
Thank you Luc for your help. Considering my situation, I had to go with plan#1, but this is a great idea that I will definitely use in the future. Thanks again!
Mark