マルチスレッド用にconcurrent.future.ThredPoolExecutorを使用しています。いくつかのhttpサービスを実行しています。サーバーがダウンしたときに実行を一時停止し、サーバーを起動してから実行を再開するようにスレッドを制御したかったのです。
サーバーがダウンするトリガーは、特定の場所でファイルが利用可能かどうかを確認しているため、実行を一時停止する必要があります。
そのため、concurrent.futures.Executor.shutdown() は、現在保留中のフューチャーの実行が完了したときに、使用しているすべてのリソースを解放する必要があることをエグゼキューターに通知します。
しかし、executor の shutdown() メソッドを使用すると、すぐにスレッドをシャットダウンするのではなく、実行全体が終了した後に shutdown() を呼び出します。
実際、concurren.future で一時停止と再開が見つからなかったため、shutdown() メソッドを呼び出しています。別の方法として、スレッドの実行が終了したら、リストから URL を削除しています。残りのリストを渡して同じメソッドを呼び出すことができるようにします。
コードは次のとおりです。
import concurrent.futures
import urllib.request
import os.path
import datetime
import sys
import pathlib
from errno import ENOENT, EACCES, EPERM
import time
import threading
listOfFilesFromDirectory = []
webroot = settings.configuration.WEBSERVER_WEBROOT
WEBSERVER_PORT = settings.configuration.WEBSERVER_PORT
shutdown = False
def class myclass:
#populating the list with the urls from a file
def triggerMethod(path):
try:
for line in open(path):
listOfFilesFromDirectory.append(line)
except IOError as err:
if err.errno == ENOENT:
#logging.critical("document.txt file is missing")
print("document.txt file is missing")
elif err.errno in (EACCES, EPERM):
#logging.critical("You are not allowed to read document.txt")
print("You are not allowed to read document.txt")
else:
raise
# calling this method to stop the threads and restart after a sleep of 100 secs, as the list will always have the urls that were not executed.
def stopExecutor(executor):
filePath = "C:\logs\serverStopLog.txt"
while not shutdown:
time.sleep(5)
if os.path.isfile(filePath):
executor.shutdown( )
time.sleep(100)
runRegressionInMultipleThreads( )
break
def load_url(url, timeout):
conn = urllib.request.urlopen('http://localhost:' + WEBSERVER_PORT + "/" + url, timeout = timeout)
return conn.info()
def trigegerFunc( ):
# We can use a with statement to ensure threads are cleaned up promptly
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
# Start the load operations and mark each future with its URL
future_to_url = {executor.submit(load_url, url, 60): url for url in listOfFilesFromDirectory}
t = threading.Thread(target=stopExecutor, args=(executor))
t.start()
for future in concurrent.futures.as_completed(future_to_url):
url = future_to_url[future]
try:
data = future.result()
except Exception as exc:
print('%r generated an exception: %s' % (url, exc))
listOfFilesFromDirectory.remove(url)
else:
if data:
if "200" in data:
listOfFilesFromDirectory.remove(url)
else:
listOfFilesFromDirectory.remove(url)
else:
listOfFilesFromDirectory.remove(url)
shutdown = True
t.join()
triggerMethod("C:\inetpub\wwwroot")
trigegerFunc()