MemWeb/Python/Application/MemWeb.Threads.py

306 lines
11 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from threading import Thread
from time import sleep
if "MemWeb" not in globals():
class MemWeb:pass
class Anonymous(MemWeb.Abstracts.Common):
def __set_basic_data(self):
self.__timer = self.settings(("threads_timer", "timer"))
self.__sleeper = self.settings(("threads_sleeper", "sleeper", "threads_sleep", "sleep"))
self.__bucle = self.settings(("threads_bucle", "bucle"))
self.__start_now = self.settings(("threads_start_now", "start_now"))
self.__autostart = self.settings(("threads_autostart", "autostart"))
self.__default_key = self.settings(("threads_default_key", "default_key", "threads_key", "key"))
self.__show_add_ok = self.settings(("threads_show_add_ok_message", "show_ok_message"))
self.__show_add_error = self.settings(("threads_show_add_error_message", "show_error_message"))
self.__show_add_exception = self.settings(("threads_show_add_exception_message", "show_exception_message"))
self.__show_stop_ok = self.settings(("threads_show_stop_ok_message", "show_ok_message"))
self.__show_stop_error = self.settings(("threads_show_stop_error_message", "show_error_message"))
self.__show_stop_exception = self.settings(("threads_show_stop_exception_message", "show_exception_message"))
self.__show_remove_ok = self.settings(("threads_show_remove_ok_message", "show_ok_message"))
self.__show_remove_error = self.settings(("threads_show_remove_error_message", "show_error_message"))
self.__show_remove_exception = self.settings(("threads_show_remove_exception_message", "show_exception_message"))
self.__show_play_ok = self.settings(("threads_show_play_ok_message", "show_ok_message"))
self.__show_play_error = self.settings(("threads_show_play_error_message", "show_error_message"))
self.__show_play_exception = self.settings(("threads_show_play_exception_message", "show_exception_message"))
def __init__(self, mem_web, inputs = None):
super().__init__(mem_web, "threads")
self._print("info", "mem_web_threads_building")
self.__threads = []
self.__set_basic_data()
self._print("ok", "mem_web_threads_built")
def _start(self, end):
if self.__started:return
self.__set_basic_data()
end(0)
def _close(self, end):
if not self.__started:return
for i, thread in enumerate(self.__threads):
thread and not thread["deleted"] and self.remove(i)
end(0)
def __execute(self, thread):
while not thread["deleted"]:
if thread["working"]:
time = MemWeb.timestamp()
if time - thread["time"] >= thread["timer"]:
thread["callback"](thread)
thread["time"] = time
sleep(thread["sleeper"])
self.__threads[thread["i"]] = None
def add(self, callback, inputs = None, show_errors = None):
timer = MemWeb.get_value("timer", inputs, self.__timer)
sleeper = MemWeb.get_value("sleeper", inputs, self.__sleeper)
bucle = MemWeb.get_value("bucle", inputs, self.__bucle)
start_now = MemWeb.get_value("start_now", inputs, self.__start_now)
autostart = MemWeb.get_value("autostart", inputs, self.__autostart)
key = MemWeb.get_value("key", inputs, self.__default_key)
error = ((
((
1 << 0 if callback == None else
1 << 1 if not callable(callback) else
0) << 0) |
((
1 << 0 if timer == None else
1 << 1 if not isinstance(timer, float) else
1 << 2 if timer < 0 else
0) << 2) |
((
1 << 0 if sleeper == None else
1 << 1 if not isinstance(sleeper, float) else
1 << 2 if sleeper < 0 else
0) << 5) |
((
1 << 0 if bucle == None else
1 << 1 if not isinstance(bucle, bool) else
0) << 8) |
((
1 << 0 if start_now == None else
1 << 1 if not isinstance(start_now, bool) else
0) << 10) |
((
1 << 0 if autostart == None else
1 << 1 if not isinstance(autostart, bool) else
0) << 10) |
((
1 << 0 if key == None else
1 << 1 if not isinstance(key, str) else
1 << 2 if not key else
1 << 3 if not MemWeb.re_key.match(key) else
0) << 12) |
0) or (1 << 16 if sleeper > timer else 0)) << 1
has_show_errors = isinstance(show_errors, bool)
i = None
if not error:
thread = {
"callback" : callback,
"timer" : timer,
"sleeper" : sleeper / 1000.0,
"bucle" : bucle,
"start_now" : start_now,
"working" : autostart,
"time" : 0 if start_now else MemWeb.timestamp(),
"thread" : None,
"deleted" : False,
"i" : None,
"key" : key
}
i = 0
l = len(self.__threads)
try:
thread["thread"] = Thread(target = lambda:self.__execute(thread))
while i < l:
if self.__threads[i]:
break
i += 1
if i == l:
self.__threads.append(thread)
i = len(self.__threads) - 1
else:
self.__threads[i] = thread
thread["i"] = i
thread["thread"].start()
except Exception as exception:
self.exception(exception, self.__show_add_exception and "mem_web_threads_add_exception", {
"i" : i,
"key" : key
})
self.validate(
error,
(
"exception",
"callback_null",
"callback_not_function",
"timer_null",
"timer_not_number",
"timer_lower_0",
"sleeper_null",
"sleeper_not_number",
"sleeper_lower_0",
"bucle_null",
"bucle_not_bool",
"start_now_null",
"start_now_not_bool",
"autostart_null",
"autostart_not_bool",
"key_null",
"key_not_string",
"key_empty",
"key_bad_characters",
"sleeper_higher_timer"
),
{
"i" : i,
"key" : key
},
(show_errors if has_show_errors else self.__show_add_error) and "mem_web_threads_add_error",
(show_errors if has_show_errors else True) and self.__show_add_ok and "mem_web_threads_add_ok"
)
return (i, error)
def stop(self, i, show_errors = None):
error = (
1 << 0 if i == None else
1 << 1 if not isinstance(i, int) else
1 << 2 if i < 0 else
1 << 3 if i >= len(self.__threads) else
1 << 4 if not self.__threads[i] else
1 << 5 if self.__threads[i]["deleted"] else
1 << 6 if not self.__threads[i]["working"] else
0) << 1
has_show_errors = isinstance(show_errors, bool)
if not error:
self.__threads[i]["working"] = False
self.validate(
error,
(
"exception",
"i_null",
"i_not_integer",
"i_lower_0",
"i_too_high",
"thread_removed",
"thread_removing",
"thread_stopped"
),
{
"i" : i,
"key" : self.__threads[i]["key"] if i >= 0 and i < len(self.__threads) else None
},
(show_errors if has_show_errors else self.__show_stop_error) and "mem_web_threads_stop_error",
(show_errors if has_show_errors else True) and self.__show_stop_ok and "mem_web_threads_stop_ok"
)
return error
def play(self, i, show_errors = None):
error = (
1 << 0 if i == None else
1 << 1 if not isinstance(i, int) else
1 << 2 if i < 0 else
1 << 3 if i >= len(self.__threads) else
1 << 4 if not self.__threads[i] else
1 << 5 if self.__threads[i]["deleted"] else
1 << 6 if self.__threads[i]["working"] else
0) << 1
has_show_errors = isinstance(show_errors, bool)
if not error:
self.__threads[i]["working"] = True
self.validate(
error,
(
"exception",
"i_null",
"i_not_integer",
"i_lower_0",
"i_too_high",
"thread_removed",
"thread_removing",
"thread_already_working"
),
{
"i" : i,
"key" : self.__threads[i]["key"] if i >= 0 and i < len(self.__threads) else None
},
(show_errors if has_show_errors else self.__show_play_error) and "mem_web_threads_play_error",
(show_errors if has_show_errors else True) and self.__show_play_ok and "mem_web_threads_play_ok"
)
return error
def remove(self, i, show_errors = None):
error = (
1 << 0 if i == None else
1 << 1 if not isinstance(i, int) else
1 << 2 if i < 0 else
1 << 3 if i >= len(self.__threads) else
1 << 4 if not self.__threads[i] else
1 << 5 if self.__threads[i]["deleted"] else
0) << 1
has_show_errors = isinstance(show_errors, bool)
if not error:
self.__threads[i]["deleted"] = True
self.validate(
error,
(
"exception",
"i_null",
"i_not_integer",
"i_lower_0",
"i_too_high",
"thread_removed",
"thread_removing"
),
{
"i" : i,
"key" : self.__threads[i]["key"] if i >= 0 and i < len(self.__threads) else None
},
(show_errors if has_show_errors else self.__show_remove_error) and "mem_web_threads_remove_error",
(show_errors if has_show_errors else True) and self.__show_remove_ok and "mem_web_threads_remove_ok"
)
return error
MemWeb.Threads = Anonymous
del globals()["Anonymous"]