diff --git a/gmcapsule/init.py b/gmcapsule/init.py

index decc1d8..7a98b98 100644

--- a/gmcapsule/init.py

+++ b/gmcapsule/init.py

@@ -508,11 +508,16 @@ class Config:

 """



 def __init__(self, config_path):

+ self.config_path = config_path

+ self.reload()

+

+ def reload(self):

     self.ini = configparser.ConfigParser()

- if os.path.exists(config_path):

- self.ini.read(config_path)

+ if os.path.exists(self.config_path):

+ print('Configuration:', self.config_path)

+ self.ini.read(self.config_path)

     else:

- print(config_path, 'not found -- using defaults')

+ print(self.config_path, 'not found -- using defaults')



 def hostnames(self):

     """

diff --git a/gmcapsule/gemini.py b/gmcapsule/gemini.py

index ecddbeb..a7026a0 100644

--- a/gmcapsule/gemini.py

+++ b/gmcapsule/gemini.py

@@ -11,6 +11,7 @@ import socket

import threading

import queue

import re

+import signal

import time

from pathlib import Path

from urllib.parse import urlparse

@@ -659,22 +660,25 @@ class Worker(threading.Thread):

         return





+_server_instance = None

+

+def _restart_workers(signum, frame):

+ if signum == signal.SIGHUP:

+ _server_instance.restart_workers()

+

+

class Server:

 def __init__(self, cfg):

+ global _server_instance

+ assert _server_instance is None

+ _server_instance = self

     #mp.set_start_method('spawn')

+ self.cfg = cfg

+ self.address = cfg.address()

+ self.port = cfg.port()



- hostname_or_hostnames = cfg.hostnames()

     cert_path = cfg.certs_dir() / 'cert.pem'

     key_path = cfg.certs_dir() / 'key.pem'

- address = cfg.address()

- port = cfg.port()

- session_id = f'GmCapsule:{cfg.port()}'.encode('utf-8')

- num_threads = cfg.num_threads()

-

- self.hostnames = [hostname_or_hostnames] \

- if type(hostname_or_hostnames) == str else hostname_or_hostnames

- self.address = address

- self.port = port



     if not os.path.exists(cert_path):

         raise Exception("certificate file not found: " + str(cert_path))

@@ -685,22 +689,32 @@ class Server:

     self.context.use_certificate_file(str(cert_path))

     self.context.use_privatekey_file(str(key_path))

     self.context.set_verify(SSL.VERIFY_PEER, verify_callback)

- if session_id:

- if type(session_id) != bytes:

- raise Exception("session_id type must be bytes")

- self.context.set_session_id(session_id)

+

+ session_id = f'GmCapsule:{cfg.port()}'.encode('utf-8')

+ #if type(session_id) != bytes:

+ # raise Exception("session_id type must be bytes")

+ self.context.set_session_id(session_id)



     # Spawn the worker threads.

     self.shutdown_event = threading.Event()

     self.workers = []

     self.work_queue = queue.Queue()

- for worker_id in range(max(num_threads, 1)):

- worker = Worker(worker_id, cfg, self.work_queue, self.shutdown_event)

- self.workers.append(worker)

+ self.create_workers(cfg)



     self.sock = None

     self.sv_conn = None



+ def restart_workers(self):

+ """

+ Restarts workers with an updated configuration. The server socket or

+ TLS configuration are not modified, even if the values have changed

+ in the configuration file.

+ """

+ self.stop_workers()

+ self.cfg.reload()

+ self.create_workers(self.cfg)

+ self.start_workers()

+

 def run(self):

     attempts = 60

     print(f'Opening port {self.port}...')

@@ -720,14 +734,12 @@ class Server:

             print('...')

     print(f'Server started on port {self.port}')



- PARALLELIZE = True

-

- if PARALLELIZE:

- for worker in self.workers:

- worker.start()

- print(len(self.workers), 'worker(s) started')

+ self.start_workers()



- snapshot = None

+ try:

+ signal.signal(signal.SIGHUP, _restart_workers)

+ except ValueError:

+ print('Restarting with SIGHUP not supported')



     while True:

         stream = None

@@ -735,11 +747,6 @@ class Server:

             stream, from_addr = self.sv_conn.accept()

             stream._socket.settimeout(10)

             self.work_queue.put((stream, from_addr))

-

- if not PARALLELIZE:

- self.work_queue.put((None, None)) # single iteration only

- self.workers[0].run()

-

             del stream

             del from_addr

         except KeyboardInterrupt:

@@ -756,11 +763,27 @@ class Server:

     self.sock = None



     # Stop all workers.

- self.shutdown_event.set()

- if PARALLELIZE:

- for i in range(len(self.workers)):

- self.work_queue.put((None, None))

- for worker in self.workers:

- worker.join()

+ self.stop_workers()



     print('Done')

+

+ def create_workers(self, cfg):

+ self.shutdown_event.clear()

+ for worker_id in range(max(cfg.num_threads(), 1)):

+ worker = Worker(worker_id, cfg, self.work_queue, self.shutdown_event)

+ self.workers.append(worker)

+

+ def start_workers(self):

+ for worker in self.workers:

+ worker.start()

+ print(len(self.workers), 'worker(s) started')

+

+ def stop_workers(self):

+ self.shutdown_event.set()

+ n = len(self.workers)

+ for _ in range(n):

+ self.work_queue.put((None, None))

+ for worker in self.workers:

+ worker.join()

+ self.workers = []

+ print(n, 'worker(s) stopped')

Proxy Information
Original URL
gemini://git.skyjake.fi/gmcapsule/main/pcdiff/6ac505666d0d67bd9bfa608111105253b6d7f907
Status Code
Success (20)
Meta
text/plain
Capsule Response Time
29.209557 milliseconds
Gemini-to-HTML Time
2.006785 milliseconds

This content has been proxied by September (ba2dc).