Проблема с запуском и остановкой «httpserver» несколько раз в PythonPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Проблема с запуском и остановкой «httpserver» несколько раз в Python

Сообщение Anonymous »

У меня есть Httpserver в Python Who Who's Work, чтобы изменить переменную статуса между состояниями. Суть моей проблемы в том, что сервер запускается и останавливается один раз или (иногда) дважды, но не больше раз. Похоже, что сервер не запускается в последующее время, хотя я не уверен, почему. Пожалуйста, смотрите мой код: < /p>

Код: Выделить всё

from typing import Tuple, Type, Optional
import requests
import logging
import threading
import time
from enum import Enum
from http.server import HTTPServer, BaseHTTPRequestHandler
from socketserver import BaseServer

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

class Status(Enum):
START_STATE = 0
END_STATE = 1

class StatusTracker:
# pure abstract class. Has the "status" property. that is it. Implemented by UserOfHttpServer below.

def __init__(self):
self._status = Status.START_STATE

@property
def status(self):
return self._status

@status.setter
def status(self, newStatus):
self._status = newStatus

class HttpHandler(BaseHTTPRequestHandler):
"""Simple request handler -- churns the statusTracker.status variable. """

def __init__(self, request, client_address: Tuple[str, int], server: BaseServer, StatusTracker):
self.statusTracker: Optional[StatusTracker] = StatusTracker
super().__init__(request=request, client_address=client_address, server=server)

def do_GET(self):
logger.debug(f"handling GET request: {self.path}")

self.send_response(200)

if self.path.endswith('/'):
# mini landing page for browser
self.send_header("Content-type", "text/html")
self.end_headers()

landing = f"""
Request: {self.path}

Listening to  Callback Notifications.


"""
self.wfile.write(landing.strip().encode("utf-8"))
return

# otherwise we send plain text only
self.send_header("Content-type", "text/plain")
self.end_headers()
logger.info(f"HTTPServer received request: \"{self.path}\".  ")

if self.path == '/favicon.ico':
# dont know what this is, but it seems I need to handle and ignore
#   https://stackoverflow.com/a/65528815/3059024
return

if self.path.endswith("/test_connection"):
response_content = f"HttpServer is running and responsive"
self.wfile.write(response_content.encode())
return

elif self.path.endswith("/start_state"):
self.statusTracker.status = Status.START_STATE

elif self.path.endswith("/end_state"):
self.statusTracker.status = Status.END_STATE

else:
logger.warning(f"unhandled request: \"{self.path}\"")

class MyHttpServer(HTTPServer):
"""The server itself"""

def __init__(self, address: Tuple[str, int], handler: Type[HttpHandler],
StatusTracker: Optional[StatusTracker] = None):
self.allow_reuse_address = True
self.allow_reuse_port = True
self.statusTracker = StatusTracker
super(MyHttpServer, self).__init__(address, handler)

self.serverThread: threading.Thread
self.serverStartedEvent: threading.Event = threading.Event()
self.serverFinishedEvent: threading.Event = threading.Event()

def finish_request(self, request, client_address) -> None:
assert self.statusTracker is not None
self.RequestHandlerClass(request, client_address, self, self.statusTracker)  # type: ignore

def serve_forever(self, poll_interval: float = -1) -> None:
try:
super().serve_forever(poll_interval)
except Exception as e:
logger.error(str(e))
self.shutdownFromNewThread()

def serveInNewThread(self) -> threading.Thread:
logger.info(f"Starting server on \"{self.server_address}")
self.serverThread = threading.Thread(target=self.serve_forever, name="HttpServerThread")
self.serverThread.start()

try:
response = requests.get(f"http://{self.server_address[0]}:{self.server_address[1]}/test_connection",
timeout=5)
response.raise_for_status()  # Raise an exception for non-2xx status codes
logger.critical(response.text)
self.serverStartedEvent.set()
self.serverFinishedEvent.clear()
return self.serverThread
except requests.exceptions.RequestException as e:
if "timed out" in str(e):
raise ConnectionError(f"Could not start and connect to HttpServer. Error message: \"{e}\"")
else:
raise e

def shutdown(self) -> None:
logger.info("called shutdown")
super().shutdown()
logger.info(f"Finished shutdown")
# make sure server thread has finished
isServerThreadStillRunning = self.serverThread.is_alive()
while isServerThreadStillRunning:
logger.info(f"Is  server thread still alive?: {self.serverThread.is_alive()}")
time.sleep(0.1)
isServerThreadStillRunning = self.serverThread.is_alive()
self.serverFinishedEvent.set()
self.serverStartedEvent.clear()

def shutdownFromNewThread(self):
thread = threading.Thread(target=self.shutdown, name="ShutdownHttpServerThread")
thread.start()
self.serverFinishedEvent.wait()

class UserOfMyHttpServer:
# implements the ServerStatus interface

def __init__(self, port: int):
self.port = port

self._status = Status.START_STATE
self.statusStartStateEvent: threading.Event = threading.Event()
self.statusStartStateEvent.set()

self.statusEndStateEvent: threading.Event = threading.Event()

# keep order
self.events = [self.statusStartStateEvent, self.statusEndStateEvent]

# FYI no http:// is needed with local host. Might be with a normal address...
self.httpServer: MyHttpServer = MyHttpServer(
("localhost", self.port), HttpHandler, self
)

self.httpServerThread = self.httpServer.serveInNewThread()
x = 4

def shutdown(self):
# but the  server is not yet shutdown.  We need to do so.
self.httpServer.shutdownFromNewThread()
# and wait for it to signal.

# note: Do not try to turn off  http server from within the server
if self.httpServer.serverStartedEvent.is_set() and not self.httpServer.serverFinishedEvent.is_set():
self.httpServer.serverFinishedEvent.wait()

@property
def status(self):
return self._status

@status.setter
def status(self, value):
logger.debug(f"{self.__class__.__name__} status changed from {self._status} to {value}")
self.events[self._status.value].clear()
self._status = value
self.events[self._status.value].set()

< /code>
и код, чтобы проверить его и продемонстрировать проблему. < /p>

def createUserOfHttpServer(port) -> UserOfMyHttpServer:
"""Make the instance of UserOfMyHttpServer"""
user = UserOfMyHttpServer(port)

logger.info("waiting for server start event")
user.httpServer.serverStartedEvent.wait()
logger.info("server has started")
return user

def shutdownUserOfServer(userOfServer: UserOfMyHttpServer):
"""Shutdown the instance of UserOfMyHttpServer"""
userOfServer.shutdown()

logger.info("waiting for server ending event")
userOfServer.httpServer.serverFinishedEvent.wait()
logger.info("server has finished")

def startAndStopServer():
# start and stop the server
logger.info("Attempt start and stop")
user = createUserOfHttpServer(1234)
shutdownUserOfServer(user)
logger.info("Start and stop successful")

def test_startAndStopOnce():
startAndStopServer()

def test_startAndStopTwice():
startAndStopServer()
startAndStopServer()

def test_startAndStop_3():
for i in range(3):
startAndStopServer()

Вы увидите здесь, что StartandStopserver работает один раз, а иногда и дважды. Но (для меня) 3 или более раз повышает ConnectionError из нижней части myhttpserver.serveinnewthread из -за времени.
except requests.exceptions.RequestException as e:
if "timed out" in str(e):
> raise ConnectionError(f"Could not start and connect to HttpServer. Error message: \"{e}\"")
E ConnectionError: Could not start and connect to HttpServer. Error message: "HTTPConnectionPool(host='127.0.0.1', port=1234): Read timed out. (read timeout=5)"
< /code>
Может ли кто -нибудь помочь получить этот код для прохождения «многократного начального теста» и в целом иметь какие -либо предложения для того, чтобы сделать этот код более надежным? Заранее спасибо!

Подробнее здесь: https://stackoverflow.com/questions/764 ... -in-python
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Com.sun.net.httpserver.HttpServer не работает при использовании специальной службы исполнителя
    Anonymous » » в форуме JAVA
    0 Ответы
    22 Просмотры
    Последнее сообщение Anonymous
  • Производительность com.sun.net.httpserver.httpserver и httpurlconnection?
    Anonymous » » в форуме JAVA
    0 Ответы
    3 Просмотры
    Последнее сообщение Anonymous
  • Почему существует разница между запуском MAME из оболочки и запуском его как подпроцесса Python?
    Anonymous » » в форуме Python
    0 Ответы
    26 Просмотры
    Последнее сообщение Anonymous
  • Проблема с запуском RNN и запуском пакета torchsummary.
    Anonymous » » в форуме Python
    0 Ответы
    74 Просмотры
    Последнее сообщение Anonymous
  • Как скачать пакет com.sun.net.httpserver?
    Гость » » в форуме JAVA
    0 Ответы
    13 Просмотры
    Последнее сообщение Гость

Вернуться в «Python»