Update redis, and implement a custom channel layer to send datetime/decimal objects
This commit is contained in:
parent
9a7deb5e2a
commit
95e658d05b
3 changed files with 47 additions and 2 deletions
|
@ -148,7 +148,7 @@ CACHES = {
|
|||
|
||||
CHANNEL_LAYERS = {
|
||||
"default": {
|
||||
"BACKEND": "channels_redis.core.RedisChannelLayer",
|
||||
"BACKEND": "shared.channels.ChannelLayer",
|
||||
"CONFIG": {
|
||||
"hosts": [
|
||||
(
|
||||
|
|
|
@ -5,7 +5,7 @@ psycopg2<2.8
|
|||
|
||||
# Redis
|
||||
django-redis-cache==3.0.*
|
||||
redis~=2.10.6
|
||||
redis==3.5.*
|
||||
channels-redis==3.4.*
|
||||
|
||||
# ASGI protocol and HTTP server
|
||||
|
|
45
shared/channels.py
Normal file
45
shared/channels.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
import datetime
|
||||
import random
|
||||
from decimal import Decimal
|
||||
|
||||
import msgpack
|
||||
from channels_redis.core import RedisChannelLayer
|
||||
|
||||
|
||||
def encode_kf(obj):
|
||||
if isinstance(obj, Decimal):
|
||||
return {"__decimal__": True, "as_str": str(obj)}
|
||||
elif isinstance(obj, datetime.datetime):
|
||||
return {"__datetime__": True, "as_str": obj.strftime("%Y%m%dT%H:%M:%S.%f")}
|
||||
return obj
|
||||
|
||||
|
||||
def decode_kf(obj):
|
||||
if "__decimal__" in obj:
|
||||
obj = Decimal(obj["as_str"])
|
||||
elif "__datetime__" in obj:
|
||||
obj = datetime.datetime.strptime(obj["as_str"], "%Y%m%dT%H:%M:%S.%f")
|
||||
return obj
|
||||
|
||||
|
||||
class ChannelLayer(RedisChannelLayer):
|
||||
def serialize(self, message):
|
||||
"""Serializes to a byte string."""
|
||||
value = msgpack.packb(message, default=encode_kf, use_bin_type=True)
|
||||
|
||||
if self.crypter:
|
||||
value = self.crypter.encrypt(value)
|
||||
|
||||
# As we use an sorted set to expire messages
|
||||
# we need to guarantee uniqueness, with 12 bytes.
|
||||
random_prefix = random.getrandbits(8 * 12).to_bytes(12, "big")
|
||||
return random_prefix + value
|
||||
|
||||
def deserialize(self, message):
|
||||
"""Deserializes from a byte string."""
|
||||
# Removes the random prefix
|
||||
message = message[12:]
|
||||
|
||||
if self.crypter:
|
||||
message = self.crypter.decrypt(message, self.expiry + 10)
|
||||
return msgpack.unpackb(message, object_hook=decode_kf, raw=False)
|
Loading…
Reference in a new issue