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
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
60 additions
and
30 deletions
+60
-30
signals.py
django/db/models/signals.py
+9
-8
dispatcher.py
django/dispatch/dispatcher.py
+51
-22
No files found.
django/db/models/signals.py
Dosyayı görüntüle @
704ee33f
...
...
@@ -2,15 +2,16 @@ from django.dispatch import Signal
class_prepared
=
Signal
(
providing_args
=
[
"class"
])
pre_init
=
Signal
(
providing_args
=
[
"instance"
,
"args"
,
"kwargs"
])
post_init
=
Signal
(
providing_args
=
[
"instance"
])
pre_init
=
Signal
(
providing_args
=
[
"instance"
,
"args"
,
"kwargs"
]
,
use_caching
=
True
)
post_init
=
Signal
(
providing_args
=
[
"instance"
]
,
use_caching
=
True
)
pre_save
=
Signal
(
providing_args
=
[
"instance"
,
"raw"
,
"using"
,
"update_fields"
])
post_save
=
Signal
(
providing_args
=
[
"instance"
,
"raw"
,
"created"
,
"using"
,
"update_fields"
])
pre_save
=
Signal
(
providing_args
=
[
"instance"
,
"raw"
,
"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"
])
post_delete
=
Signal
(
providing_args
=
[
"instance"
,
"using"
])
pre_delete
=
Signal
(
providing_args
=
[
"instance"
,
"using"
]
,
use_caching
=
True
)
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):
if
hasattr
(
target
,
'__func__'
):
return
(
id
(
target
.
__self__
),
id
(
target
.
__func__
))
return
id
(
target
)
NONE_ID
=
_make_id
(
None
)
# A marker for caching
NO_RECEIVERS
=
object
()
class
Signal
(
object
):
"""
...
...
@@ -20,8 +24,7 @@ class Signal(object):
receivers
{ receriverkey (id) : weakref(receiver) }
"""
def
__init__
(
self
,
providing_args
=
None
):
def
__init__
(
self
,
providing_args
=
None
,
use_caching
=
False
):
"""
Create a new signal.
...
...
@@ -33,6 +36,13 @@ class Signal(object):
providing_args
=
[]
self
.
providing_args
=
set
(
providing_args
)
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
):
"""
...
...
@@ -106,6 +116,7 @@ class Signal(object):
break
else
:
self
.
receivers
.
append
((
lookup_key
,
receiver
))
self
.
sender_receivers_cache
=
{}
def
disconnect
(
self
,
receiver
=
None
,
sender
=
None
,
weak
=
True
,
dispatch_uid
=
None
):
"""
...
...
@@ -140,9 +151,10 @@ class Signal(object):
if
r_key
==
lookup_key
:
del
self
.
receivers
[
index
]
break
self
.
sender_receivers_cache
=
{}
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
):
"""
...
...
@@ -163,10 +175,10 @@ class Signal(object):
Returns a list of tuple pairs [(receiver, response), ... ].
"""
responses
=
[]
if
not
self
.
receivers
:
if
not
self
.
receivers
or
self
.
sender_receivers_cache
.
get
(
sender
)
is
NO_RECEIVERS
:
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
)
responses
.
append
((
receiver
,
response
))
return
responses
...
...
@@ -195,12 +207,12 @@ class Signal(object):
receiver.
"""
responses
=
[]
if
not
self
.
receivers
:
if
not
self
.
receivers
or
self
.
sender_receivers_cache
.
get
(
sender
)
is
NO_RECEIVERS
:
return
responses
# Call each receiver with whatever arguments it can accept.
# 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
:
response
=
receiver
(
signal
=
self
,
sender
=
sender
,
**
named
)
except
Exception
as
err
:
...
...
@@ -209,26 +221,43 @@ class Signal(object):
responses
.
append
((
receiver
,
response
))
return
responses
def
_live_receivers
(
self
,
sender
key
):
def
_live_receivers
(
self
,
sender
):
"""
Filter sequence of receivers to get resolved, live receivers.
This checks for weak references and resolves them, then returning only
live receivers.
"""
none_senderkey
=
_make_id
(
None
)
receivers
=
[]
for
(
receiverkey
,
r_senderkey
),
receiver
in
self
.
receivers
:
if
r_senderkey
==
none_senderkey
or
r_senderkey
==
senderkey
:
if
isinstance
(
receiver
,
WEAKREF_TYPES
):
# Dereference the weak reference.
receiver
=
receiver
()
if
receiver
is
not
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
=
[]
for
(
receiverkey
,
r_senderkey
),
receiver
in
self
.
receivers
:
if
r_senderkey
==
NONE_ID
or
r_senderkey
==
senderkey
:
receivers
.
append
(
receiver
)
else
:
receivers
.
append
(
receiver
)
return
receivers
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
):
# Dereference the weak reference.
receiver
=
receiver
()
if
receiver
is
not
None
:
non_weak_receivers
.
append
(
receiver
)
else
:
non_weak_receivers
.
append
(
receiver
)
return
non_weak_receivers
def
_remove_receiver
(
self
,
receiver
):
"""
...
...
@@ -246,8 +275,8 @@ class Signal(object):
# after we delete some items
for
idx
,
(
r_key
,
_
)
in
enumerate
(
reversed
(
self
.
receivers
)):
if
r_key
==
key
:
del
self
.
receivers
[
last_idx
-
idx
]
del
self
.
receivers
[
last_idx
-
idx
]
self
.
sender_receivers_cache
=
{}
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