From 97a9ad6c726d9d3c8a36908720d0a02d3e7d7240 Mon Sep 17 00:00:00 2001 From: nhyun400 Date: Thu, 27 Apr 2023 15:57:47 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B5=AC=EB=8F=85=EC=9E=90=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EB=B0=9C=EC=86=A1=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/damination.py | 63 +++++++++++++++++------- app/dockerfile => dockerfile | 4 +- app/requirements.txt => requirements.txt | 0 3 files changed, 46 insertions(+), 21 deletions(-) rename app/dockerfile => dockerfile (91%) rename app/requirements.txt => requirements.txt (100%) diff --git a/app/damination.py b/app/damination.py index a585afe..371ed7e 100644 --- a/app/damination.py +++ b/app/damination.py @@ -9,7 +9,7 @@ import configparser from pydantic import BaseModel from datetime import datetime -from aiohttp import ClientSession +import aiohttp class StatusEndpointFilter(logging.Filter): def filter(self, record): @@ -79,10 +79,12 @@ class Donate(BaseModel): class DaminationAPI(): def __init__(self): + self.WIDGET_IDS = WIDGET_IDS self.queue = asyncio.Queue() self.fetch_tasks = [] self.stop_event = asyncio.Event() self.subscribers = {} + self.session = aiohttp.ClientSession() def add_subscriber(self, widget_id: str, url: str) -> bool: @@ -108,8 +110,8 @@ class DaminationAPI(): 현재 설정된 모든 위젯 ID 목록을 반환합니다. """ - logger.debug(f"get widget {WIDGET_IDS}") - return WIDGET_IDS + logger.debug(f"get widget {self.WIDGET_IDS}") + return self.WIDGET_IDS def add_widget_id(self, widget_id:str): """ @@ -118,7 +120,7 @@ class DaminationAPI(): """ try: - WIDGET_IDS.append(widget_id) + self.WIDGET_IDS.append(widget_id) logger.debug(f"add widget {widget_id}") except Exception as e: @@ -132,8 +134,8 @@ class DaminationAPI(): """ try: - if widget_id in WIDGET_IDS: - widget = WIDGET_IDS.pop(WIDGET_IDS.index(widget_id)) + if widget_id in self.WIDGET_IDS: + widget = self.WIDGET_IDS.pop(self.WIDGET_IDS.index(widget_id)) logger.debug(f"delete widget {widget}") return widget @@ -217,7 +219,7 @@ class DaminationAPI(): self.stop_event.clear() # 추가: 중단 이벤트를 초기화합니다. - for widget_id in WIDGET_IDS: + for widget_id in self.WIDGET_IDS: task = asyncio.create_task(self.fetch_alerts(self.queue, widget_id)) self.fetch_tasks.append(task) @@ -239,7 +241,7 @@ class DaminationAPI(): widget_id: 추가할 위젯 ID """ - if widget_id not in WIDGET_IDS: + if widget_id not in self.WIDGET_IDS: self.add_widget_id(widget_id) task = asyncio.create_task(self.fetch_alerts(self.queue, widget_id)) self.fetch_tasks.append(task) @@ -252,8 +254,8 @@ class DaminationAPI(): 주어진 widget_id를 위젯 ID 목록에서 제거하고 알림을 가져오는 작업을 중단합니다. widget_id: 제거할 위젯 ID """ - if widget_id in WIDGET_IDS: - index = WIDGET_IDS.index(widget_id) + if widget_id in self.WIDGET_IDS: + index = self.WIDGET_IDS.index(widget_id) self.remove_widget_id(widget_id) fetch_task = self.fetch_tasks.pop(index) fetch_task.cancel() @@ -273,16 +275,39 @@ class DaminationAPI(): else: return None + def get_subscribers(self, widget_id: str) -> list: + """ + 주어진 widget_id에 해당하는 구독자 목록을 반환합니다. + widget_id: 구독자 목록을 얻을 위젯 ID + """ - async def notify_subscribers(self, widget_id: str, donate): - if widget_id not in self.subscribers: - return - - for subscriber_url in self.subscribers[widget_id]: - async with ClientSession() as session: - await session.post(subscriber_url, json=donate) - - logger.info(f"send to subscriber({widget_id}: {donate})") + if widget_id in self.subscribers: + return self.subscribers[widget_id] + else: + return [] + + async def notify_subscribers(self, widget_id, donate): + """ + 주어진 widget_id에 해당하는 모든 구독자들에게 알림을 전송합니다. + widget_id: 알림을 보낼 구독자들의 위젯 ID + donate: 전송할 알림 데이터 + """ + subscribers = self.get_subscribers(widget_id) + tasks = [self.notify_subscriber(self.session, subscriber_url, donate) for subscriber_url in subscribers] # 변경: 기존 클래스 세션 사용 + await asyncio.gather(*tasks) + + async def notify_subscriber(self, session, subscriber_url, donate): + """ + 주어진 구독자에게 알림을 전송합니다. + session: aiohttp ClientSession 객체 + subscriber_url: 알림을 받을 구독자의 URL + donate: 전송할 알림 데이터 + """ + async with session.post(subscriber_url, json=donate) as response: + if response.status // 100 == 2: + logger.info(f"Successfully sent notification to {subscriber_url}.") + else: + logger.error(f"Failed to send notification to {subscriber_url} with status code {response.status}.") async def run(self): diff --git a/app/dockerfile b/dockerfile similarity index 91% rename from app/dockerfile rename to dockerfile index cdaf161..14e1935 100644 --- a/app/dockerfile +++ b/dockerfile @@ -11,7 +11,7 @@ RUN apk --no-cache add tzdata && \ COPY ./requirements.txt / RUN pip install --no-cache-dir -r requirements.txt -COPY . /app +COPY ./app /app WORKDIR /app EXPOSE 80 @@ -20,4 +20,4 @@ HEALTHCHECK --interval=5s --timeout=3s --start-period=10s --retries=3 \ CMD curl --fail http://localhost/status || exit 1 -CMD ["python", "damination.py"] +CMD ["python", "main.py"] diff --git a/app/requirements.txt b/requirements.txt similarity index 100% rename from app/requirements.txt rename to requirements.txt