|
40 | 40 | from bittensor.errors import SynapseDendriteNoneException
|
41 | 41 | from cursor.app.core.config import config
|
42 | 42 |
|
| 43 | + |
| 44 | +class FastAPIThreadedServer(uvicorn.Server): |
| 45 | + """ |
| 46 | + The ``FastAPIThreadedServer`` class is a specialized server implementation for the Axon server in the Bittensor network. |
| 47 | +
|
| 48 | + It extends the functionality of :func:`uvicorn.Server` to run the FastAPI application in a separate thread, allowing the Axon server to handle HTTP requests concurrently and non-blocking. |
| 49 | +
|
| 50 | + This class is designed to facilitate the integration of FastAPI with the Axon's asynchronous architecture, ensuring efficient and scalable handling of network requests. |
| 51 | +
|
| 52 | + Importance and Functionality |
| 53 | + Threaded Execution |
| 54 | + The class allows the FastAPI application to run in a separate thread, enabling concurrent handling of HTTP requests which is crucial for the performance and scalability of the Axon server. |
| 55 | +
|
| 56 | + Seamless Integration |
| 57 | + By running FastAPI in a threaded manner, this class ensures seamless integration of FastAPI's capabilities with the Axon server's asynchronous and multi-threaded architecture. |
| 58 | +
|
| 59 | + Controlled Server Management |
| 60 | + The methods start and stop provide controlled management of the server's lifecycle, ensuring that the server can be started and stopped as needed, which is vital for maintaining the Axon server's reliability and availability. |
| 61 | +
|
| 62 | + Signal Handling |
| 63 | + Overriding the default signal handlers prevents potential conflicts with the Axon server's main application flow, ensuring stable operation in various network conditions. |
| 64 | +
|
| 65 | + Use Cases |
| 66 | + Starting the Server |
| 67 | + When the Axon server is initialized, it can use this class to start the FastAPI application in a separate thread, enabling it to begin handling HTTP requests immediately. |
| 68 | +
|
| 69 | + Stopping the Server |
| 70 | + During shutdown or maintenance of the Axon server, this class can be used to stop the FastAPI application gracefully, ensuring that all resources are properly released. |
| 71 | +
|
| 72 | + Args: |
| 73 | + should_exit (bool): Flag to indicate whether the server should stop running. |
| 74 | + is_running (bool): Flag to indicate whether the server is currently running. |
| 75 | +
|
| 76 | + The server overrides the default signal handlers to prevent interference with the main application flow and provides methods to start and stop the server in a controlled manner. |
| 77 | + """ |
| 78 | + |
| 79 | + should_exit: bool = False |
| 80 | + is_running: bool = False |
| 81 | + |
| 82 | + def install_signal_handlers(self): |
| 83 | + """ |
| 84 | + Overrides the default signal handlers provided by ``uvicorn.Server``. This method is essential to ensure that the signal handling in the threaded server does not interfere with the main application's flow, especially in a complex asynchronous environment like the Axon server. |
| 85 | + """ |
| 86 | + pass |
| 87 | + |
| 88 | + @contextlib.contextmanager |
| 89 | + def run_in_thread(self): |
| 90 | + """ |
| 91 | + Manages the execution of the server in a separate thread, allowing the FastAPI application to run asynchronously without blocking the main thread of the Axon server. This method is a key component in enabling concurrent request handling in the Axon server. |
| 92 | +
|
| 93 | + Yields: |
| 94 | + None: This method yields control back to the caller while the server is running in the background thread. |
| 95 | + """ |
| 96 | + thread = threading.Thread(target=self.run, daemon=True) |
| 97 | + thread.start() |
| 98 | + try: |
| 99 | + while not self.started: |
| 100 | + time.sleep(1e-3) |
| 101 | + yield |
| 102 | + finally: |
| 103 | + self.should_exit = True |
| 104 | + thread.join() |
| 105 | + |
| 106 | + def _wrapper_run(self): |
| 107 | + """ |
| 108 | + A wrapper method for the :func:`run_in_thread` context manager. This method is used internally by the ``start`` method to initiate the server's execution in a separate thread. |
| 109 | + """ |
| 110 | + with self.run_in_thread(): |
| 111 | + while not self.should_exit: |
| 112 | + time.sleep(1e-3) |
| 113 | + |
| 114 | + def start(self): |
| 115 | + """ |
| 116 | + Starts the FastAPI server in a separate thread if it is not already running. This method sets up the server to handle HTTP requests concurrently, enabling the Axon server to efficiently manage |
| 117 | + incoming network requests. |
| 118 | +
|
| 119 | + The method ensures that the server starts running in a non-blocking manner, allowing the Axon server to continue its other operations seamlessly. |
| 120 | + """ |
| 121 | + if not self.is_running: |
| 122 | + self.should_exit = False |
| 123 | + thread = threading.Thread(target=self._wrapper_run, daemon=True) |
| 124 | + thread.start() |
| 125 | + self.is_running = True |
| 126 | + |
| 127 | + def stop(self): |
| 128 | + """ |
| 129 | + Signals the FastAPI server to stop running. This method sets the :func:`should_exit` flag to ``True``, indicating that the server should cease its operations and exit the running thread. |
| 130 | +
|
| 131 | + Stopping the server is essential for controlled shutdowns and resource management in the Axon server, especially during maintenance or when redeploying with updated configurations. |
| 132 | + """ |
| 133 | + if self.is_running: |
| 134 | + self.should_exit = True |
| 135 | + |
| 136 | + |
43 | 137 | class CortexAxon(bt.axon):
|
44 | 138 | def __init__(
|
45 | 139 | self,
|
|
0 commit comments