Optimizing algo, changing args names

This commit is contained in:
Alexis Delhaie
2020-10-06 21:56:55 +02:00
parent 61ae5317a0
commit c525fdd305
4 changed files with 65 additions and 51 deletions

2
.gitignore vendored
View File

@@ -136,3 +136,5 @@ dmypy.json
# Cython debug symbols # Cython debug symbols
cython_debug/ cython_debug/
.vscode

View File

@@ -4,6 +4,8 @@ import queue
import os import os
import sys import sys
console = None
def get_available_threads(): def get_available_threads():
if sys.platform == 'win32': if sys.platform == 'win32':
return (int)(os.environ['NUMBER_OF_PROCESSORS']) return (int)(os.environ['NUMBER_OF_PROCESSORS'])
@@ -12,7 +14,6 @@ def get_available_threads():
SIZE = get_available_threads() SIZE = get_available_threads()
q = queue.Queue() q = queue.Queue()
not_finished = True
class ProducerThread(threading.Thread): class ProducerThread(threading.Thread):
def __init__(self, threads): def __init__(self, threads):
@@ -20,7 +21,6 @@ class ProducerThread(threading.Thread):
self.threads = threads self.threads = threads
def run(self): def run(self):
global not_finished
try: try:
i = 0 i = 0
while i < len(self.threads): while i < len(self.threads):
@@ -29,31 +29,48 @@ class ProducerThread(threading.Thread):
i += 1 i += 1
while q.qsize() > 0: while q.qsize() > 0:
time.sleep(0.1) time.sleep(0.1)
except: except Exception as e:
pass console.print("[red]Error[/]: {}".format(e), style="bold")
not_finished = False
class ConsumerThread(threading.Thread): class ConsumerThread(threading.Thread):
def __init__(self): def __init__(self):
super(ConsumerThread,self).__init__() super(ConsumerThread,self).__init__()
self.alive = True
def stop(self):
self.alive = False
def run(self): def run(self):
while not_finished: while self.alive:
if q.qsize() > 0: try:
t = q.get() if q.qsize() > 0:
t.start() t = q.get(False)
t.join() t.start()
if t.is_alive():
t.join(t.timeout)
except queue.Empty as e:
pass
except Exception as e:
console.print("[orange3]Warning[/]: {}".format(e), style="bold")
def start(threads): def start(threads):
process(threads, get_available_threads())
def start_custom_limit(threads, limit):
process(threads, limit)
def process(threads, limit):
p = ProducerThread(threads) p = ProducerThread(threads)
p.start() p.start()
consumers = [] consumers = []
for _ in range(get_available_threads()): for _ in range(limit):
c = ConsumerThread() c = ConsumerThread()
consumers.append(c) consumers.append(c)
c.start() c.start()
p.join() p.join()
for c in consumers: for c in consumers:
c.join() c.stop()
for c in consumers:
if c.is_alive():
c.join()

View File

@@ -13,8 +13,9 @@ import thread
import basic_producer_consumer import basic_producer_consumer
console = Console(highlight=False) console = Console(highlight=False)
VERSION = "1.4" VERSION = "1.4.1"
thread.console = console thread.console = console
basic_producer_consumer.console = console
def main(): def main():
if ((len(sys.argv) >= 2) and (("--help" in sys.argv) or ("/?" in sys.argv))): if ((len(sys.argv) >= 2) and (("--help" in sys.argv) or ("/?" in sys.argv))):
@@ -28,29 +29,34 @@ def main():
options = Options() options = Options()
options.host = get_args("-h", True, 1001, 1002) options.host = get_args("-h", True, 1001, 1002)
options.allow_ssl = get_flag("--ssl") options.allow_ssl = get_flag("--ssl")
options.port = int(get_args("--port", False, 1003, 1004, "80")) options.port = int(get_args("--port", False, 1003, 1004, ("80", "443")[options.allow_ssl]))
options.path = get_args("-p", False, 1005, 1006, "/") options.path = get_args("-p", False, 1005, 1006, "/")
options.thread_number = int(get_args("-t", False, 1007, 1008, "5")) options.request_number = int(get_args("-r", False, 1007, 1008, "5"))
options.timeout = int(get_args("-tm", False, 1009, 1010, "10")) options.limit = int(get_args("--thread-count", False, 1007, 1008, "1500"))
options.timeout = int(get_args("--timeout", False, 1009, 1010, "10"))
options.one_by_one = get_flag("--one-by-one") options.one_by_one = get_flag("--one-by-one")
options.ignore_available_threads = get_flag("--ignore-available-threads") options.no_limit = get_flag("--no-limit")
options.self_signed = get_flag("--allow-self-signed") options.self_signed = get_flag("--allow-self-signed")
options.headers = get_headers() options.headers = get_headers()
if options.one_by_one and options.ignore_available_threads: if options.no_limit and (options.request_number < options.limit):
console.print("[red]Error[/]: ambigous arguments, --one-by-one and --ignore-available-threads cannot be in the same command", style="bold") console.print("[orange3]Warning[/]: Too much thread, starting only {} threads".format(options.request_number), style="bold")
options.limit = options.request_number
if options.one_by_one and options.no_limit:
console.print("[red]Error[/]: ambigous arguments, --one-by-one and --no-limit cannot be in the same command", style="bold")
return return
start(options) start(options)
def start(options): def start(options):
thread_array = [] thread_array = []
for i in range(0, options.thread_number): for i in range(0, options.request_number):
thread_array.append(StressThread(options, i, VERSION)) thread_array.append(StressThread(options, i, VERSION))
if options.one_by_one: if options.one_by_one:
start_one_by_one(thread_array) start_one_by_one(thread_array)
elif options.ignore_available_threads: elif options.no_limit:
start_all(thread_array) basic_producer_consumer.start_custom_limit(thread_array, options.limit)
else: else:
basic_producer_consumer.start(thread_array) basic_producer_consumer.start(thread_array)
show_stat(thread_array, (options.timeout * 1000)) show_stat(thread_array, (options.timeout * 1000))
@@ -60,19 +66,6 @@ def start_one_by_one(threads):
for t in threads: for t in threads:
t.run() t.run()
# Start all requests in the same time
def start_all(threads):
for t in threads:
started = False
while not started:
try:
t.start()
started = True
except:
time.sleep(1)
for t in threads:
t.join()
def show_stat(tArray, timeoutInMs): def show_stat(tArray, timeoutInMs):
total, succeeded = [0, 0] total, succeeded = [0, 0]
Tmax, Tmin, Tavg = [0, timeoutInMs, 0] Tmax, Tmin, Tavg = [0, timeoutInMs, 0]
@@ -107,19 +100,20 @@ def show_help():
console.print(" py main.py -h www.google.fr -p / -t 10") console.print(" py main.py -h www.google.fr -p / -t 10")
console.print("") console.print("")
console.print("Available arguments:") console.print("Available arguments:")
console.print(" -h host The server IP or domain name") console.print(" -h host The server IP or domain name")
console.print(" -p path The path of the HTTP resource") console.print(" -p path The path of the HTTP resource")
console.print(" --port port The server HTTP port") console.print(" -r <number_of_request> Number of request")
console.print(" -t thread Number of threads") console.print(" --port port The server HTTP port")
console.print(" -tm second Timeout of the request") console.print(" --timeout <seconds> Timeout of the request")
console.print(" --one-by-one Send request one by one") console.print(" --thread-count <number_of_threads> Number of request")
console.print(" --ignore-available-threads Ignore physical number of threads and start all request in the same time") console.print(" --one-by-one Send request one by one")
console.print(" --ssl Use HTTPS/SSL") console.print(" --no-limit Disable CPU physical threads limit")
console.print(" --allow-self-signed Allow self signed SSL certificate") console.print(" --ssl Use HTTPS/SSL")
console.print(" --header key=value Send a custom header (To add several headers, add several times the argument --header)") console.print(" --allow-self-signed Allow self signed SSL certificate")
console.print(" --header \"key=value\" Send a custom header (To add several headers, add several times the argument --header)")
console.print(" --help") console.print(" --help")
console.print(" /? Show this page") console.print(" /? Show this page")
console.print(" --version Get information about the application and the system") console.print(" --version Get information about the application and the system")
def show_author(): def show_author():
console.print("[bold]Basic HTTP Stress test[/]") console.print("[bold]Basic HTTP Stress test[/]")

View File

@@ -7,10 +7,11 @@ class Options:
self.allow_ssl = False self.allow_ssl = False
self.port = 80 self.port = 80
self.path = "/" self.path = "/"
self.thread_number = 5 self.request_number = 5
self.limit = 1500
self.timeout = 10 self.timeout = 10
self.one_by_one = False self.one_by_one = False
self.ignore_available_threads = False self.no_limit = False
self.self_signed = False self.self_signed = False
self.headers = {} self.headers = {}