Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
704ee33f
Kaydet (Commit)
704ee33f
authored
Ara 16, 2012
tarafından
Anssi Kääriäinen
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #16679 -- Use caching to speed up signal sending
üst
507c0814
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
54 additions
and
24 deletions
+54
-24
signals.py
django/db/models/signals.py
+9
-8
dispatcher.py
django/dispatch/dispatcher.py
+45
-16
No files found.
django/db/models/signals.py
Dosyayı görüntüle @
704ee33f
...
@@ -2,15 +2,16 @@ from django.dispatch import Signal
...
@@ -2,15 +2,16 @@ from django.dispatch import Signal
class_prepared
=
Signal
(
providing_args
=
[
"class"
])
class_prepared
=
Signal
(
providing_args
=
[
"class"
])
pre_init
=
Signal
(
providing_args
=
[
"instance"
,
"args"
,
"kwargs"
])
pre_init
=
Signal
(
providing_args
=
[
"instance"
,
"args"
,
"kwargs"
]
,
use_caching
=
True
)
post_init
=
Signal
(
providing_args
=
[
"instance"
])
post_init
=
Signal
(
providing_args
=
[
"instance"
]
,
use_caching
=
True
)
pre_save
=
Signal
(
providing_args
=
[
"instance"
,
"raw"
,
"using"
,
"update_fields"
])
pre_save
=
Signal
(
providing_args
=
[
"instance"
,
"raw"
,
"using"
,
"update_fields"
],
post_save
=
Signal
(
providing_args
=
[
"instance"
,
"raw"
,
"created"
,
"using"
,
"update_fields"
])
use_caching
=
True
)
post_save
=
Signal
(
providing_args
=
[
"instance"
,
"raw"
,
"created"
,
"using"
,
"update_fields"
],
use_caching
=
True
)
pre_delete
=
Signal
(
providing_args
=
[
"instance"
,
"using"
])
pre_delete
=
Signal
(
providing_args
=
[
"instance"
,
"using"
]
,
use_caching
=
True
)
post_delete
=
Signal
(
providing_args
=
[
"instance"
,
"using"
])
post_delete
=
Signal
(
providing_args
=
[
"instance"
,
"using"
]
,
use_caching
=
True
)
post_syncdb
=
Signal
(
providing_args
=
[
"class"
,
"app"
,
"created_models"
,
"verbosity"
,
"interactive"
])
post_syncdb
=
Signal
(
providing_args
=
[
"class"
,
"app"
,
"created_models"
,
"verbosity"
,
"interactive"
]
,
use_caching
=
True
)
m2m_changed
=
Signal
(
providing_args
=
[
"action"
,
"instance"
,
"reverse"
,
"model"
,
"pk_set"
,
"using"
])
m2m_changed
=
Signal
(
providing_args
=
[
"action"
,
"instance"
,
"reverse"
,
"model"
,
"pk_set"
,
"using"
]
,
use_caching
=
True
)
django/dispatch/dispatcher.py
Dosyayı görüntüle @
704ee33f
...
@@ -10,6 +10,10 @@ def _make_id(target):
...
@@ -10,6 +10,10 @@ def _make_id(target):
if
hasattr
(
target
,
'__func__'
):
if
hasattr
(
target
,
'__func__'
):
return
(
id
(
target
.
__self__
),
id
(
target
.
__func__
))
return
(
id
(
target
.
__self__
),
id
(
target
.
__func__
))
return
id
(
target
)
return
id
(
target
)
NONE_ID
=
_make_id
(
None
)
# A marker for caching
NO_RECEIVERS
=
object
()
class
Signal
(
object
):
class
Signal
(
object
):
"""
"""
...
@@ -20,8 +24,7 @@ class Signal(object):
...
@@ -20,8 +24,7 @@ class Signal(object):
receivers
receivers
{ receriverkey (id) : weakref(receiver) }
{ receriverkey (id) : weakref(receiver) }
"""
"""
def
__init__
(
self
,
providing_args
=
None
,
use_caching
=
False
):
def
__init__
(
self
,
providing_args
=
None
):
"""
"""
Create a new signal.
Create a new signal.
...
@@ -33,6 +36,13 @@ class Signal(object):
...
@@ -33,6 +36,13 @@ class Signal(object):
providing_args
=
[]
providing_args
=
[]
self
.
providing_args
=
set
(
providing_args
)
self
.
providing_args
=
set
(
providing_args
)
self
.
lock
=
threading
.
Lock
()
self
.
lock
=
threading
.
Lock
()
self
.
use_caching
=
use_caching
# For convenience we create empty caches even if they are not used.
# A note about caching: if use_caching is defined, then for each
# distinct sender we cache the receivers that sender has in
# 'sender_receivers_cache'. The cache is cleaned when .connect() or
# .disconnect() is called and populated on send().
self
.
sender_receivers_cache
=
{}
def
connect
(
self
,
receiver
,
sender
=
None
,
weak
=
True
,
dispatch_uid
=
None
):
def
connect
(
self
,
receiver
,
sender
=
None
,
weak
=
True
,
dispatch_uid
=
None
):
"""
"""
...
@@ -106,6 +116,7 @@ class Signal(object):
...
@@ -106,6 +116,7 @@ class Signal(object):
break
break
else
:
else
:
self
.
receivers
.
append
((
lookup_key
,
receiver
))
self
.
receivers
.
append
((
lookup_key
,
receiver
))
self
.
sender_receivers_cache
=
{}
def
disconnect
(
self
,
receiver
=
None
,
sender
=
None
,
weak
=
True
,
dispatch_uid
=
None
):
def
disconnect
(
self
,
receiver
=
None
,
sender
=
None
,
weak
=
True
,
dispatch_uid
=
None
):
"""
"""
...
@@ -140,9 +151,10 @@ class Signal(object):
...
@@ -140,9 +151,10 @@ class Signal(object):
if
r_key
==
lookup_key
:
if
r_key
==
lookup_key
:
del
self
.
receivers
[
index
]
del
self
.
receivers
[
index
]
break
break
self
.
sender_receivers_cache
=
{}
def
has_listeners
(
self
,
sender
=
None
):
def
has_listeners
(
self
,
sender
=
None
):
return
bool
(
self
.
_live_receivers
(
_make_id
(
sender
)
))
return
bool
(
self
.
_live_receivers
(
sender
))
def
send
(
self
,
sender
,
**
named
):
def
send
(
self
,
sender
,
**
named
):
"""
"""
...
@@ -163,10 +175,10 @@ class Signal(object):
...
@@ -163,10 +175,10 @@ class Signal(object):
Returns a list of tuple pairs [(receiver, response), ... ].
Returns a list of tuple pairs [(receiver, response), ... ].
"""
"""
responses
=
[]
responses
=
[]
if
not
self
.
receivers
:
if
not
self
.
receivers
or
self
.
sender_receivers_cache
.
get
(
sender
)
is
NO_RECEIVERS
:
return
responses
return
responses
for
receiver
in
self
.
_live_receivers
(
_make_id
(
sender
)
):
for
receiver
in
self
.
_live_receivers
(
sender
):
response
=
receiver
(
signal
=
self
,
sender
=
sender
,
**
named
)
response
=
receiver
(
signal
=
self
,
sender
=
sender
,
**
named
)
responses
.
append
((
receiver
,
response
))
responses
.
append
((
receiver
,
response
))
return
responses
return
responses
...
@@ -195,12 +207,12 @@ class Signal(object):
...
@@ -195,12 +207,12 @@ class Signal(object):
receiver.
receiver.
"""
"""
responses
=
[]
responses
=
[]
if
not
self
.
receivers
:
if
not
self
.
receivers
or
self
.
sender_receivers_cache
.
get
(
sender
)
is
NO_RECEIVERS
:
return
responses
return
responses
# Call each receiver with whatever arguments it can accept.
# Call each receiver with whatever arguments it can accept.
# Return a list of tuple pairs [(receiver, response), ... ].
# Return a list of tuple pairs [(receiver, response), ... ].
for
receiver
in
self
.
_live_receivers
(
_make_id
(
sender
)
):
for
receiver
in
self
.
_live_receivers
(
sender
):
try
:
try
:
response
=
receiver
(
signal
=
self
,
sender
=
sender
,
**
named
)
response
=
receiver
(
signal
=
self
,
sender
=
sender
,
**
named
)
except
Exception
as
err
:
except
Exception
as
err
:
...
@@ -209,26 +221,43 @@ class Signal(object):
...
@@ -209,26 +221,43 @@ class Signal(object):
responses
.
append
((
receiver
,
response
))
responses
.
append
((
receiver
,
response
))
return
responses
return
responses
def
_live_receivers
(
self
,
sender
key
):
def
_live_receivers
(
self
,
sender
):
"""
"""
Filter sequence of receivers to get resolved, live receivers.
Filter sequence of receivers to get resolved, live receivers.
This checks for weak references and resolves them, then returning only
This checks for weak references and resolves them, then returning only
live receivers.
live receivers.
"""
"""
none_senderkey
=
_make_id
(
None
)
receivers
=
None
if
self
.
use_caching
:
receivers
=
self
.
sender_receivers_cache
.
get
(
sender
)
# We could end up here with NO_RECEIVERS even if we do check this case in
# .send() prior to calling _live_receivers() due to concurrent .send() call.
if
receivers
is
NO_RECEIVERS
:
return
[]
if
receivers
is
None
:
with
self
.
lock
:
senderkey
=
_make_id
(
sender
)
receivers
=
[]
receivers
=
[]
for
(
receiverkey
,
r_senderkey
),
receiver
in
self
.
receivers
:
for
(
receiverkey
,
r_senderkey
),
receiver
in
self
.
receivers
:
if
r_senderkey
==
none_senderkey
or
r_senderkey
==
senderkey
:
if
r_senderkey
==
NONE_ID
or
r_senderkey
==
senderkey
:
receivers
.
append
(
receiver
)
if
self
.
use_caching
:
if
not
receivers
:
self
.
sender_receivers_cache
[
sender
]
=
NO_RECEIVERS
else
:
# Note, we must cache the weakref versions.
self
.
sender_receivers_cache
[
sender
]
=
receivers
non_weak_receivers
=
[]
for
receiver
in
receivers
:
if
isinstance
(
receiver
,
WEAKREF_TYPES
):
if
isinstance
(
receiver
,
WEAKREF_TYPES
):
# Dereference the weak reference.
# Dereference the weak reference.
receiver
=
receiver
()
receiver
=
receiver
()
if
receiver
is
not
None
:
if
receiver
is
not
None
:
receivers
.
append
(
receiver
)
non_weak_
receivers
.
append
(
receiver
)
else
:
else
:
receivers
.
append
(
receiver
)
non_weak_
receivers
.
append
(
receiver
)
return
receivers
return
non_weak_
receivers
def
_remove_receiver
(
self
,
receiver
):
def
_remove_receiver
(
self
,
receiver
):
"""
"""
...
@@ -246,8 +275,8 @@ class Signal(object):
...
@@ -246,8 +275,8 @@ class Signal(object):
# after we delete some items
# after we delete some items
for
idx
,
(
r_key
,
_
)
in
enumerate
(
reversed
(
self
.
receivers
)):
for
idx
,
(
r_key
,
_
)
in
enumerate
(
reversed
(
self
.
receivers
)):
if
r_key
==
key
:
if
r_key
==
key
:
del
self
.
receivers
[
last_idx
-
idx
]
del
self
.
receivers
[
last_idx
-
idx
]
self
.
sender_receivers_cache
=
{}
def
receiver
(
signal
,
**
kwargs
):
def
receiver
(
signal
,
**
kwargs
):
"""
"""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment