﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
32708	Django cron file lock breaks with django 3.2	François Dailloux	nobody	"Hello everyone !

After I upgraded django to 3.2, I noticed that I had the following error popping up

`django.db.utils.OperationalError: FATAL:  sorry, too many clients already`

I then inspected the postgresql connections, and my processes, and it turned out, that was my django cron jobs that were running multiple times at the same time, thus opening more connections than necessary. 



[Django cron has a lock mecanism to avoid this,](https://github.com/Tivix/django-cron/blob/v0.5.1/django_cron/backends/lock/file.py) that uses the lock function from django : 
` from django.core.files import locks`

But in django3.2 with latest django_cron version, that check totally fails and we can run a cron multiple times.  I looked up a bit the code to see what's the issue. 

In django 3.2 [the code for that lock function is ](https://github.com/django/django/blob/main/django/core/files/locks.py)



{{{
        def lock(f, flags):
            try:
                fcntl.flock(_fd(f), flags)
                return True
            except BlockingIOError:
                return False

        def unlock(f):
            fcntl.flock(_fd(f), fcntl.LOCK_UN)
            return True
}}}


So  BlockingIOError are catched, and the function then returns false. 

[This changes the behavior from 3.1.7 : ](https://github.com/django/django/blob/stable/3.1.x/django/core/files/locks.py)


{{{

        def lock(f, flags):
            ret = fcntl.flock(_fd(f), flags)
            return ret == 0

        def unlock(f):
            ret = fcntl.flock(_fd(f), fcntl.LOCK_UN)
            return ret == 0


}}}


in previous behaviour, checking for «ret==0» was indeed useless, because when flock fails, it raises a IOError, 

But in 3.1, the lock function didn't catch the error, and django_cron made good use of that behaviour. 

Edit: that problem was spotted at code review but ignored : 

[ https://github.com/django/django/pull/13410#discussion_r624988346]

have a good day !"	Bug	closed	File uploads/storage	3.2	Normal	invalid	file lock, too many connections, django_cron	Hasan Ramezani	Unreviewed	0	0	0	0	0	0
