tags:

views:

83

answers:

1

So I'm creating a django app that allows a user to add a new line of text to an existing group of text lines. However I don't want multiple users adding lines to the same group of text lines concurrently. So I created a BoolField isBeingEdited that is set to True once a user decides to append a specific group. Once the Bool is True no one else can append the group until the edit is submitted, whereupon the Bool is set False again. Works alright, unless someone decides to make an edit then changes their mind or forgets about it, etc. I want isBeingEdited to flip back to False after 10 minutes or so. Is this a job for cron, or is there something easier out there? Any suggestions?

+4  A: 

Change the boolean to a "lock time"

  1. To lock the model, set the Lock time to the current time.
  2. To unlock the model, set the lock time to None
  3. Add an "is_locked" method. That method returns "not locked" if the current time is more than 10 minutes after the lock time.

This gives you your timeout without Cron and without regular hits into the DB to check flags and unset them. Instead, the time is only checked if you are interest in wieither this model is locked. A Cron would likely have to check all models.

from django.db import models
from datetime import datetime, timedelta
# Create your models here.
class yourTextLineGroup(models.Model):
    # fields go here    
    lock_time = models.DateTimeField(null=True)
    locked_by = models.ForeignKey()#Point me to your user model

    def lock(self):
        if self.is_locked(): #and code here to see if current user is not locked_by user
            #exception / bad return value here
            pass

        self.lock_time = datetime.now()

    def unlock(self):
        self.lock_time = None

    def is_locked(self):
        return self.lock_time and datetime.now() - self.lock_time < timedelta(minutes=10)

Code above assumes that the caller will call the save method after calling lock or unlock.

Tom Leys
wouldn't the is_locked method still hit the db to check Lock time and then hit it again to change it to None, or am I missing something? (I'm not too knowledgeable in the realm of methods). Also, got an example? (I think i get it, but maybe not)
kow
The DB will still be hit. But a cron job would have to hit the db on a regular basis even if no locks were being set or used. This method will only hit the DB on demand, while the locks are in use.
Tom Leys
didn't work til i changed "self.lock_time - datetime.now()" to "datetime.now() - self.lock_time" in the is_locked method, but now it's A+
kow
Cool! I've made the fix in my code above.
Tom Leys