#!/usr/bin/env python3 # -*- coding: utf-8 -*- from typing import Callable, Self from threading import Thread, Lock from Models.AIResponseModel import AIResponseModel from Abstracts.AIInterpretersAbstract import AIInterpretersAbstract from Utils.Common import Common class AIPoolRequestsItemsModel: def __init__(self:Self, key:str, interpreter:AIInterpretersAbstract, session:int|None, message:str, callback:Callable[[int, AIResponseModel], None], orders:list[str] = [] ) -> None: self.key:str = key self.interpreter:AIInterpretersAbstract = interpreter self.session:int|None = session self.message:str = message self.callback:Callable[[int, AIResponseModel], None] = callback self.orders:list[str] = orders class AIPoolRequestsModel: def __init__(self:Self) -> None: self.pool:dict[int, AIPoolRequestsItemsModel] = {} self.iterations:int = 0 self.maximum_iterations:int = 1 self.i:int = 0 self.j:int = 0 self.__lock:Lock = Lock() def add(self:Self, interpreter:AIInterpretersAbstract, session:int|None, message:str, callback:Callable[[int, AIResponseModel], None], orders:list[str] = [] ) -> int: id:int with self.__lock: self.i += 1 id = self.i self.pool[self.i] = AIPoolRequestsItemsModel( interpreter.key, interpreter, session, message, callback, orders ) self.execute() return id def __next(self:Self, callback:Callable[[int, AIResponseModel], None], session:int, response:AIResponseModel) -> None: Common.execute(callback, session, response) if response.done or not response.ok: with self.__lock: self.iterations -= 1 self.execute() def __execute(self:Self) -> None: item:AIPoolRequestsItemsModel|None = None with self.__lock: if len(self.pool) and self.iterations != self.maximum_iterations and self.i != self.j: self.iterations += 1 self.j = min(self.pool.keys()) item:AIPoolRequestsItemsModel = self.pool[self.j] del self.pool[self.j] item and item.interpreter.request( item.session, item.message, item.orders, lambda session, response: self.__next(item.callback, session, response) ) def execute(self:Self) -> None: Thread(target = self.__execute).start() def cancel(self:Self, ids:int|list[int]) -> None: with self.__lock: for id in Common.get_keys(ids): if id in self.pool: del self.pool[id] def remove(self:Self, key:str) -> None: with self.__lock: for id, item in list(self.pool.items()): if item.key == key: del self.pool[id]