Changes between Version 8 and Version 9 of DjangoSpecifications/Core/Threading
- Timestamp:
- Apr 13, 2008, 11:16:17 AM (17 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
DjangoSpecifications/Core/Threading
v8 v9 14 14 See #1442 and http://groups.google.com/group/django-developers/browse_thread/thread/905f79e350525c95 for threading discussions. 15 15 16 == Proposal==16 == Globals == 17 17 18 Instead of ad-hoc solutions like the one proposed in #5632, there should be a locking module that can be reused. 18 There are three types of globals: 19 1. read-only globals that are never assigned to (THREAD-SAFE), 20 1. globals assigned to in a function by using the `global` keyword (NOT THREAD-SAFE), 21 1. global mutable data structures (lists and dictionaries, also instances) that are assigned to at module level but whose elements are modified in functions and that are accessed without using the `global` keyword (NOT THREAD-SAFE unless never modified). 19 22 20 Five types of locking primitives could be implemented: 21 * Django-wide global locks 22 * module-level locks 23 * class-level locks 24 * instance-level locks 25 * function-level locks 23 We won't deal with read-only globals. `grep` in Django source finds the following other globals. 26 24 27 I don't see any use for a Django-wide lock. Module-level lock is needed for sessions. Class-level locks seem appropriate for models. 28 Template loader can use a function-level lock. 25 === Globals accessed with the `global` keyword === 29 26 30 '''FIXME: module and class level locks missing.'''31 The implementation is a modified copy of http://www.phyast.pitt.edu/~micheles/python/documentation.html and should perhaps reside in `django.utils.locking`:32 27 {{{ 33 from django.utils._threading_local import RLock 34 35 def getattr_(obj, name, default_thunk): 36 "Similar to .setdefault in dictionaries." 37 try: 38 return getattr(obj, name) 39 except AttributeError: 40 default = default_thunk() 41 setattr(obj, name, default) 42 return default 43 44 def locked(func, *args, **kw): 45 lock = getattr_(func, "__lock", RLock) 46 lock.acquire() 47 try: 48 result = func(*args, **kw) 49 finally: 50 lock.release() 51 return result 28 $ grep -r '^[[:space:]]*global ' django/ | egrep -v '(\.svn|\.html|\.css|\.pyc|doctest)' | sort | uniq 52 29 }}} 53 30 54 === Database model locking === 31 yields the following results 55 32 56 All functions that have `.alters_data = True` should be wrapped with a locked block. 33 {{{ 34 django/contrib/sites/models.py: global SITE_CACHE 35 django/core/management/__init__.py: global _commands 36 django/template/context.py: global _standard_context_processors 37 django/template/__init__.py: global invalid_var_format_string 38 django/template/loader.py: global template_source_loaders 39 django/utils/translation/trans_real.py: global _accepted 40 django/utils/translation/trans_real.py: global _active 41 django/utils/translation/trans_real.py: global _default, _active 42 django/utils/translation/trans_real.py: global _translations 43 django/utils/translation/trans_real.py: global _translations 44 }}} 57 45 58 == Notes==46 === Global dictionaries === 59 47 60 Once older python version support will be dropped in distant future, locking should be implemented with `with`: http://docs.python.org/lib/with-locks.html 61 62 Although this sounds like a horrible hack, perhaps a portable wrapper around `mmap.mmap` can be used for emulating shared memory. 48 === Global lists ===