Commit 6fb24587 authored by Kento HASEGAWA's avatar Kento HASEGAWA
Browse files

Add support for stopping solver

parent df06c088
Loading
Loading
Loading
Loading
+3 −23
Changes for roles/solver.py: 3 added lines, 23 removed lines.
Original line number Diff line number Diff line
@@ -6,23 +6,6 @@ import sys
import time
import threading

class StoppableThread(threading.Thread):

    def __init__(self, target, args=()):
        super(StoppableThread, self).__init__(target=target, args=args)
        self._status = 'running'
    def stop(self):
        if self.is_running():
            self._status = 'stopping'
    def stopped(self):
        self._status = 'stopped'
    def is_running(self):
        return (self._status == 'running')
    def is_stopping(self):
        return (self._status == 'stopping')
    def is_stopped(self):
        return (self._status == 'stopped')

class Solver(object):

    def __init__(self, config):
@@ -42,7 +25,6 @@ class Solver(object):
        start_time = time.time()
        solution = self.solver.solve(params)
        end_time = time.time()
        self.thread.stopped()

        elapsed_time = end_time - start_time

@@ -74,7 +56,8 @@ class Solver(object):

        if self.thread is None:
            print("I: Solver started")
            self.thread = StoppableThread(target=self.solve, args=(params, ))
            # self.thread = StoppableThread(target=self.solve, args=(params, ))
            self.thread = threading.Thread(name='solver', target=self.solve, args=(params, ), daemon=True)
            self.thread.start()
            return {'status': 'started'}
        else:
@@ -83,10 +66,7 @@ class Solver(object):
    def stop_solver(self):

        if self.thread is not None:
            if self.thread.is_running():
                self.thread.stop()
                self.thread.join(0.1)
                self.thread = None
            self.solver.stop()
        
        return {'status': 'stopped'}

+78 −2
Changes for solvers/SampleSolver/main.py: 78 added lines, 2 removed lines.
Original line number Diff line number Diff line
import os
import subprocess

proc = None
stop_flag = False

def stop():
    global proc
    global stop_flag

    stop_flag = True
    if not proc is None:
        proc.terminate()
        print('stopped')

def solve(params):
    print("This is a sample solver.")
    return {'solution': 'aaa!'}
    global proc
    global stop_flag

    stop_flag = False

    # 必要な変数があるか確認
    assert('problem' in params)
    assert('timeout' in params)

    problem = params['problem']
    timeout = params['timeout']

    print(problem)
    
    # ソルバを実行するためのコマンドを指定
    command = f'sleep 100'
    cmds = command.split()

    if stop_flag:return {
        'status': 'stopped',
        'solution': '',
        }

    # ソルバを実行する準備
    proc = subprocess.Popen(
        cmds,
        stderr=subprocess.PIPE,
        stdout=subprocess.PIPE
    )

    print(' === start waiting === ')
    # ソルバを実行,タイムアウトしたらTimeoutExpiredになる
    try:
        outs, errs = proc.communicate(timeout=timeout)
        status = 'done'
    except subprocess.TimeoutExpired:
        proc.kill()
        outs, errs = proc.communicate()
        status = 'timeout'
    finally:
        returncode = proc.returncode
        outs = outs.decode()
        errs = errs.decode()
    
    # 解けたか解けなかったかによってstatusを適当なものに設定する
    # return
    if returncode == 0:
        if outs.startswith('SIZE'):
            status = 'done'
            solution = outs
        else:
            status = 'failed'
            solution = outs
    else:
        status = 'failed'
        solution = ''

    # 答えを返す
    return {
        'status': status,
        'solution': solution,
        # 'elapsed_time': 0.0 # 必要ならば足す,無ければシステム側で自動算出
        }

def main(params):
    solve(a)