optimize worker

This commit is contained in:
bakatrouble 2021-03-20 16:21:06 +03:00
parent f397545412
commit b35d2ca251
2 changed files with 41 additions and 25 deletions

View File

@ -2,6 +2,7 @@ import logging
import traceback import traceback
from concurrent.futures.thread import ThreadPoolExecutor from concurrent.futures.thread import ThreadPoolExecutor
from multiprocessing.pool import ThreadPool from multiprocessing.pool import ThreadPool
from time import sleep
import sentry_sdk import sentry_sdk
from django.core.cache import cache from django.core.cache import cache
@ -15,50 +16,58 @@ from bots.models import TelegramBot
class Command(BaseCommand): class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
pool = ThreadPool(8) # pool = ThreadPool(8)
def error_handler(update: Update, ctx: CallbackContext): def error_handler(update: Update, ctx: CallbackContext):
sentry_sdk.capture_exception(ctx.error) sentry_sdk.capture_exception(ctx.error)
logging.exception('Exception while processing update', exc_info=ctx.error) logging.exception('Exception while processing update', exc_info=ctx.error)
initialized = False initialized = False
dispatchers = [] updaters = []
def check_updates(dispatcher): # def check_updates(dispatcher):
try: # try:
updates = dispatcher.bot.get_updates(dispatcher.last_update_id) # updates = dispatcher.bot.get_updates(dispatcher.last_update_id)
except TimedOut: # except TimedOut:
return # return
except TelegramError as e: # except TelegramError as e:
sentry_sdk.capture_exception(e) # sentry_sdk.capture_exception(e)
traceback.print_exc() # traceback.print_exc()
updates = [] # updates = []
#
for update in updates: # for update in updates:
pool.apply_async(dispatcher.process_update, (update,)) # pool.apply_async(dispatcher.process_update, (update,))
dispatcher.last_update_id = update.update_id + 1 # dispatcher.last_update_id = update.update_id + 1
while True: while True:
try: try:
if not initialized or cache.get('bots_reset'): if not initialized or cache.get('bots_reset'):
logging.warning('Reloading dispatchers') logging.warning('Reloading dispatchers')
dispatchers = [] for updater in updaters:
updater.stop()
updaters.clear()
for bot in TelegramBot.objects.filter(active=True): for bot in TelegramBot.objects.filter(active=True):
try: try:
dispatcher = bot.build_dispatcher(error_handler) updater = bot.build_updater(error_handler)
dispatcher.last_update_id = 0 updaters.append(updater)
dispatchers.append(dispatcher) updater.start_polling()
# dispatcher = bot.build_dispatcher(error_handler)
# dispatcher.last_update_id = 0
# dispatchers.append(dispatcher)
except TelegramError: except TelegramError:
pass pass
cache.delete('bots_reset') cache.delete('bots_reset')
initialized = True initialized = True
with ThreadPoolExecutor() as executor: # with ThreadPoolExecutor() as executor:
for dispatcher in dispatchers: # for dispatcher in dispatchers:
executor.submit(check_updates, dispatcher) # executor.submit(check_updates, dispatcher)
sleep(1)
except KeyboardInterrupt: except KeyboardInterrupt:
pool.terminate() for updater in updaters:
pool.join() updater.stop()
# pool.terminate()
# pool.join()
return return
except Exception as e: except Exception as e:
sentry_sdk.capture_exception(e) sentry_sdk.capture_exception(e)

View File

@ -4,7 +4,7 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
from telegram import Bot from telegram import Bot
from telegram.ext import Dispatcher from telegram.ext import Dispatcher, Updater
class TelegramBot(models.Model): class TelegramBot(models.Model):
@ -24,6 +24,13 @@ class TelegramBot(models.Model):
def get_bot(self): def get_bot(self):
return Bot(self.bot_token) return Bot(self.bot_token)
def build_updater(self, error_handler):
updater = Updater(self.bot_token)
updater.dispatcher.add_error_handler(error_handler)
updater.bot.get_me()
self.config.build_dispatcher(updater.dispatcher)
return updater
def build_dispatcher(self, error_handler): def build_dispatcher(self, error_handler):
bot = self.get_bot() bot = self.get_bot()
bot.get_me() bot.get_me()