AnP/Python/Models/AIPoolRequestsModel.py

92 lines
2.9 KiB
Python

#!/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]