Made redis storage a singleton in order to reduce number of connections

This commit is contained in:
M1ha 2019-01-23 17:01:10 +05:00
parent ed3b3909ef
commit 75fcdeeec0
3 changed files with 32 additions and 3 deletions

View File

@ -11,12 +11,13 @@ import logging
from typing import Any, Optional, List, Tuple
import os
from six import with_metaclass
from statsd.defaults.django import statsd
from .configuration import config
from .exceptions import ConfigurationError, RedisLockTimeoutError
from .redis import redis_zadd
from .utils import check_pid, get_subclasses
from .utils import check_pid, get_subclasses, SingletonMeta
logger = logging.getLogger('django-clickhouse')
@ -143,7 +144,7 @@ class Storage:
raise NotImplemented()
class RedisStorage(Storage):
class RedisStorage(with_metaclass(SingletonMeta, Storage)):
"""
Fast in-memory storage made on bases of redis and redis-py library.
Requires:

View File

@ -259,3 +259,15 @@ def exec_multi_arg_func(func: Callable, split_args: Iterable[Any], *args, thread
q.put(([s] + list(args), kwargs))
return exec_in_parallel(func, q, threads_count=threads_count)
class SingletonMeta(type):
"""
Realises singleton pattern
"""
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)
return cls._instances[cls]

View File

@ -3,9 +3,11 @@ from queue import Queue
import pytz
from django.test import TestCase
from six import with_metaclass
from django_clickhouse.models import ClickHouseSyncModel
from django_clickhouse.utils import get_tz_offset, format_datetime, lazy_class_import, int_ranges, exec_in_parallel
from django_clickhouse.utils import get_tz_offset, format_datetime, lazy_class_import, int_ranges, exec_in_parallel, \
SingletonMeta
class GetTZOffsetTest(TestCase):
@ -99,3 +101,17 @@ class TestExecInParallel(TestCase):
with self.assertRaises(TypeError):
exec_in_parallel(_test_func, q)
class TestSingletonMeta(TestCase):
def test_singleton(self):
class Single(with_metaclass(SingletonMeta)):
def __init__(self):
self.test = 1
a = Single()
a.test += 1
b = Single()
self.assertEqual(a, b)
self.assertEqual(2, b.test)