add openjtalk worker pkg
This commit is contained in:
103
text/pyopenjtalk_worker/worker_server.py
Normal file
103
text/pyopenjtalk_worker/worker_server.py
Normal file
@@ -0,0 +1,103 @@
|
||||
import pyopenjtalk
|
||||
import socket
|
||||
import select
|
||||
|
||||
|
||||
from .worker_common import (
|
||||
ConnectionClosedException,
|
||||
RequestType,
|
||||
receive_data,
|
||||
send_data,
|
||||
)
|
||||
|
||||
from common.log import logger
|
||||
|
||||
# To make it as fast as possible
|
||||
# Probably faster than calling getattr every time
|
||||
_PYOPENJTALK_FUNC_DICT = {
|
||||
"run_frontend": pyopenjtalk.run_frontend,
|
||||
"make_label": pyopenjtalk.make_label,
|
||||
"mecab_dict_index": pyopenjtalk.mecab_dict_index,
|
||||
"update_global_jtalk_with_user_dict": pyopenjtalk.update_global_jtalk_with_user_dict,
|
||||
"unset_user_dict": pyopenjtalk.unset_user_dict,
|
||||
}
|
||||
|
||||
|
||||
class WorkerServer:
|
||||
def __init__(self) -> None:
|
||||
self.client_count: int = 0
|
||||
self.quit: bool = False
|
||||
|
||||
def handle_request(self, request):
|
||||
request_type = None
|
||||
try:
|
||||
request_type = RequestType(request.get("request-type"))
|
||||
except Exception:
|
||||
return {
|
||||
"success": False,
|
||||
"reason": "request-type is invalid",
|
||||
}
|
||||
|
||||
if request_type:
|
||||
if request_type == RequestType.STATUS:
|
||||
response = {
|
||||
"success": True,
|
||||
"client-count": self.client_count,
|
||||
}
|
||||
elif request_type == RequestType.QUIT_SERVER:
|
||||
self.quit = True
|
||||
response = {"success": True}
|
||||
elif request_type == RequestType.PYOPENJTALK:
|
||||
func_name = request.get("func")
|
||||
assert isinstance(func_name, str)
|
||||
func = _PYOPENJTALK_FUNC_DICT[func_name]
|
||||
args = request.get("args")
|
||||
kwargs = request.get("kwargs")
|
||||
assert isinstance(args, list)
|
||||
assert isinstance(kwargs, dict)
|
||||
ret = func(*args, **kwargs)
|
||||
response = {"success": True, "return": ret}
|
||||
else:
|
||||
# NOT REACHED
|
||||
response = request
|
||||
|
||||
return response
|
||||
|
||||
def start_server(self, port: int):
|
||||
logger.info("start pyopenjtalk worker server")
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
|
||||
server_socket.bind((socket.gethostname(), port))
|
||||
server_socket.listen()
|
||||
sockets = [server_socket]
|
||||
while True:
|
||||
ready_sockets, _, _ = select.select(sockets, [], [], 0.1)
|
||||
for sock in ready_sockets:
|
||||
if sock is server_socket:
|
||||
logger.info("new client connected")
|
||||
client_socket, _ = server_socket.accept()
|
||||
sockets.append(client_socket)
|
||||
self.client_count += 1
|
||||
else:
|
||||
# client
|
||||
try:
|
||||
request = receive_data(sock)
|
||||
except ConnectionClosedException as e:
|
||||
sock.close()
|
||||
sockets.remove(sock)
|
||||
self.client_count -= 1
|
||||
logger.info("close connection")
|
||||
continue
|
||||
|
||||
logger.debug(f"receive request: {request}")
|
||||
|
||||
response = self.handle_request(request)
|
||||
logger.debug(f"send response: {response}")
|
||||
try:
|
||||
send_data(sock, response)
|
||||
except Exception:
|
||||
logger.warning(
|
||||
"an exception occurred during sending responce"
|
||||
)
|
||||
if self.quit:
|
||||
logger.info("quit pyopenjtalk worker server")
|
||||
return
|
||||
Reference in New Issue
Block a user