|
1 | | -"""ZeroMQ Broker Server - standalone message broker. |
| 1 | +"""ZeroMQ Broker Server. |
2 | 2 |
|
3 | | -This module is completely independent of AiiDA and can be used as a standalone |
4 | | -message broker server. It handles: |
| 3 | +Can be started as a standalone message broker process. It handles: |
5 | 4 | - Task queue management with persistence |
6 | 5 | - Request/reply routing for RPC |
7 | 6 | - Broadcast distribution |
8 | 7 | """ |
9 | 8 |
|
10 | 9 | from __future__ import annotations |
11 | 10 |
|
| 11 | +import json |
12 | 12 | import logging |
13 | | -import threading |
14 | 13 | import time |
15 | 14 | from collections import deque |
16 | 15 | from pathlib import Path |
17 | 16 | from typing import Any, Callable |
18 | 17 |
|
19 | 18 | import zmq |
20 | 19 |
|
21 | | -from aiida.brokers.utils import YAML_DECODER, YAML_ENCODER |
22 | | - |
23 | 20 | from .protocol import MessageType, decode_message, encode_message |
24 | 21 | from .queue import PersistentQueue |
25 | 22 |
|
@@ -54,8 +51,8 @@ def __init__( |
54 | 51 | :param encoder: Function to encode messages (default: yaml.dump) |
55 | 52 | :param decoder: Function to decode messages (default: yaml.load) |
56 | 53 | """ |
57 | | - encoder = encoder if encoder is not None else YAML_ENCODER |
58 | | - decoder = decoder if decoder is not None else YAML_DECODER |
| 54 | + encoder = encoder if encoder is not None else json.dumps |
| 55 | + decoder = decoder if decoder is not None else json.loads |
59 | 56 | self._storage_path = Path(storage_path) |
60 | 57 | self._sockets_path = Path(sockets_path) |
61 | 58 |
|
@@ -96,7 +93,21 @@ def __init__( |
96 | 93 |
|
97 | 94 | # Server state |
98 | 95 | self._running = False |
99 | | - self._lock = threading.Lock() |
| 96 | + |
| 97 | + # Message type -> handler mapping (built once, not per message) |
| 98 | + self._handlers: dict[str, Callable] = { |
| 99 | + MessageType.TASK.value: self._handle_task, |
| 100 | + MessageType.TASK_RESPONSE.value: self._handle_task_response, |
| 101 | + MessageType.TASK_ACK.value: self._handle_task_ack, |
| 102 | + MessageType.TASK_NACK.value: self._handle_task_nack, |
| 103 | + MessageType.RPC.value: self._handle_rpc, |
| 104 | + MessageType.RPC_RESPONSE.value: self._handle_rpc_response, |
| 105 | + MessageType.BROADCAST.value: self._handle_broadcast, |
| 106 | + MessageType.SUBSCRIBE_TASK.value: self._handle_subscribe_task, |
| 107 | + MessageType.SUBSCRIBE_RPC.value: self._handle_subscribe_rpc, |
| 108 | + MessageType.UNSUBSCRIBE_TASK.value: self._handle_unsubscribe_task, |
| 109 | + MessageType.UNSUBSCRIBE_RPC.value: self._handle_unsubscribe_rpc, |
| 110 | + } |
100 | 111 |
|
101 | 112 | @property |
102 | 113 | def storage_path(self) -> Path: |
@@ -257,22 +268,7 @@ def _handle_router_message(self) -> None: |
257 | 268 | _LOGGER.warning('Message missing type field') |
258 | 269 | return |
259 | 270 |
|
260 | | - # Route by message type |
261 | | - handlers: dict[str, Any] = { |
262 | | - MessageType.TASK.value: self._handle_task, |
263 | | - MessageType.TASK_RESPONSE.value: self._handle_task_response, |
264 | | - MessageType.TASK_ACK.value: self._handle_task_ack, |
265 | | - MessageType.TASK_NACK.value: self._handle_task_nack, |
266 | | - MessageType.RPC.value: self._handle_rpc, |
267 | | - MessageType.RPC_RESPONSE.value: self._handle_rpc_response, |
268 | | - MessageType.BROADCAST.value: self._handle_broadcast, |
269 | | - MessageType.SUBSCRIBE_TASK.value: self._handle_subscribe_task, |
270 | | - MessageType.SUBSCRIBE_RPC.value: self._handle_subscribe_rpc, |
271 | | - MessageType.UNSUBSCRIBE_TASK.value: self._handle_unsubscribe_task, |
272 | | - MessageType.UNSUBSCRIBE_RPC.value: self._handle_unsubscribe_rpc, |
273 | | - } |
274 | | - |
275 | | - handler = handlers.get(msg_type) |
| 271 | + handler = self._handlers.get(msg_type) |
276 | 272 | if handler: |
277 | 273 | handler(identity, msg) |
278 | 274 | else: |
|
0 commit comments