import importlib import json import os import requests import sys import time import threading from collections import OrderedDict class Solver(object): def __init__(self, config): self.type = 'solver' self.host = config['host'] self.address = config['address'] self.name = config['name'] self.solver = importlib.import_module(f"solvers.{config['solver']}") self.queue = OrderedDict() self.status = 'Ready' # self.thread = None self.thread = threading.Thread(name='solver', target=self.solver_thread, daemon=True) self.thread.start() def __del__(self): self.stop_solver() def __repr__(self): return "Solver" def solver_thread(self): while True: if len(self.queue) > 0: print("I: Solver started") self.status = 'running' _, params = self.queue.popitem(last=False) self.solve(params) else: self.status = 'ready' time.sleep(0.5) def solve(self, params): start_time = time.time() solution = self.solver.solve(params) end_time = time.time() elapsed_time = end_time - start_time if not 'elapsed_time' in solution: solution['elapsed_time'] = elapsed_time self.submit_solution(params, solution) # self.thread = None return True def post(self, path, data): response = requests.post( f'http://{self.host}/api/{path}', json.dumps(data), headers={'Content-Type': 'application/json'}) print(f"I: Post to {self.host}, API Cmd: {path}") return response def submit_solution(self, params, solution): data = { 'request_id': params['request_id'], 'problem': params['name'], 'worker': self.address } data.update(solution) self.post('problem/solution', data) def start_solver(self, params): # if self.thread is None: # print("I: Solver started") # self.thread = threading.Thread(name='solver', target=self.solve, args=(params, ), daemon=True) # self.thread.start() # return {'status': 'started'} # else: # return {'status': 'busy'} print("I: Problem queued") _id = params['request_id'] self.queue[_id] = params return {'status': 'queued'} def stop_solver(self): if self.thread is not None: self.solver.stop() return {'status': 'stopped'} def call_api(self, method, cmd, params): if cmd == 'role': return {'role': self.type} elif cmd == 'solve': return self.start_solver(params) elif cmd == 'stop': return self.stop_solver() elif cmd == 'status': return self.status else: return None