Coverage for an_website / emoji_chat / pub_sub_provider.py: 48.000%

25 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-24 18:51 +0000

1# This program is free software: you can redistribute it and/or modify 

2# it under the terms of the GNU Affero General Public License as 

3# published by the Free Software Foundation, either version 3 of the 

4# License, or (at your option) any later version. 

5# 

6# This program is distributed in the hope that it will be useful, 

7# but WITHOUT ANY WARRANTY; without even the implied warranty of 

8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

9# GNU Affero General Public License for more details. 

10# 

11# You should have received a copy of the GNU Affero General Public License 

12# along with this program. If not, see <https://www.gnu.org/licenses/>. 

13 

14"""A provider of the Redis PubSub class.""" 

15 

16 

17import logging 

18from collections.abc import Collection 

19from dataclasses import dataclass 

20from typing import Any, Final 

21 

22from redis.asyncio.client import PubSub, Redis 

23 

24from .. import EVENT_REDIS 

25 

26LOGGER: Final = logging.getLogger(__name__) 

27 

28 

29@dataclass(slots=True) 

30class PubSubProvider: 

31 """Provide a PubSub object.""" 

32 

33 channels: Collection[str] 

34 settings: dict[str, Any] 

35 worker: int | None 

36 _ps: PubSub | None = None 

37 _redis: Redis[str] | None = None 

38 

39 async def __call__(self) -> PubSub: 

40 """Get PubSub object.""" 

41 if not self.settings.get("REDIS"): 

42 LOGGER.error("Redis not available on worker %s", self.worker) 

43 

44 await EVENT_REDIS.wait() 

45 

46 redis: Redis[str] = self.settings["REDIS"] 

47 

48 if self._ps: 

49 if self._redis == redis: 

50 return self._ps 

51 LOGGER.info( 

52 "Closing old PubSub connection on worker %s", self.worker 

53 ) 

54 await self._ps.close() 

55 

56 self._ps = redis.pubsub() 

57 self._redis = redis 

58 await self._ps.subscribe(*self.channels) 

59 return self._ps