koi-net 1.0.0b11__py3-none-any.whl → 1.0.0b13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of koi-net might be problematic. Click here for more details.
- koi_net/config.py +95 -0
- koi_net/core.py +125 -125
- koi_net/identity.py +41 -69
- koi_net/network/graph.py +127 -127
- koi_net/network/interface.py +275 -275
- koi_net/network/request_handler.py +148 -148
- koi_net/network/response_handler.py +58 -58
- koi_net/processor/default_handlers.py +162 -162
- koi_net/processor/handler.py +59 -59
- koi_net/processor/interface.py +302 -298
- koi_net/processor/knowledge_object.py +122 -122
- koi_net/protocol/api_models.py +46 -46
- koi_net/protocol/consts.py +6 -6
- koi_net/protocol/edge.py +20 -20
- koi_net/protocol/event.py +50 -50
- koi_net/protocol/helpers.py +24 -24
- koi_net/protocol/node.py +16 -16
- {koi_net-1.0.0b11.dist-info → koi_net-1.0.0b13.dist-info}/METADATA +1 -1
- koi_net-1.0.0b13.dist-info/RECORD +25 -0
- {koi_net-1.0.0b11.dist-info → koi_net-1.0.0b13.dist-info}/licenses/LICENSE +21 -21
- koi_net-1.0.0b11.dist-info/RECORD +0 -24
- {koi_net-1.0.0b11.dist-info → koi_net-1.0.0b13.dist-info}/WHEEL +0 -0
koi_net/processor/interface.py
CHANGED
|
@@ -1,298 +1,302 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
import queue
|
|
3
|
-
import threading
|
|
4
|
-
from typing import Callable
|
|
5
|
-
from rid_lib.core import RID, RIDType
|
|
6
|
-
from rid_lib.ext import Bundle, Cache, Manifest
|
|
7
|
-
from rid_lib.types.koi_net_edge import KoiNetEdge
|
|
8
|
-
from rid_lib.types.koi_net_node import KoiNetNode
|
|
9
|
-
from ..identity import NodeIdentity
|
|
10
|
-
from ..network import NetworkInterface
|
|
11
|
-
from ..protocol.event import Event, EventType
|
|
12
|
-
from
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
self.
|
|
50
|
-
self.
|
|
51
|
-
self.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
logger.debug("Attempting to
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
logger.debug("Attempting to
|
|
187
|
-
bundle = self.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
logger.debug("
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if
|
|
194
|
-
logger.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
kobj.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
logger.info(f"
|
|
208
|
-
self.cache.
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
logger.
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
logger.debug("
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
kobj
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
logger.
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
_kobj = KnowledgeObject.
|
|
290
|
-
elif
|
|
291
|
-
_kobj = KnowledgeObject.
|
|
292
|
-
elif
|
|
293
|
-
_kobj =
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
1
|
+
import logging
|
|
2
|
+
import queue
|
|
3
|
+
import threading
|
|
4
|
+
from typing import Callable, Generic
|
|
5
|
+
from rid_lib.core import RID, RIDType
|
|
6
|
+
from rid_lib.ext import Bundle, Cache, Manifest
|
|
7
|
+
from rid_lib.types.koi_net_edge import KoiNetEdge
|
|
8
|
+
from rid_lib.types.koi_net_node import KoiNetNode
|
|
9
|
+
from ..identity import NodeIdentity
|
|
10
|
+
from ..network import NetworkInterface
|
|
11
|
+
from ..protocol.event import Event, EventType
|
|
12
|
+
from ..config import Config
|
|
13
|
+
from .handler import (
|
|
14
|
+
KnowledgeHandler,
|
|
15
|
+
HandlerType,
|
|
16
|
+
STOP_CHAIN,
|
|
17
|
+
StopChain
|
|
18
|
+
)
|
|
19
|
+
from .knowledge_object import (
|
|
20
|
+
KnowledgeObject,
|
|
21
|
+
KnowledgeSource,
|
|
22
|
+
KnowledgeEventType
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ProcessorInterface():
|
|
29
|
+
"""Provides access to this node's knowledge processing pipeline."""
|
|
30
|
+
|
|
31
|
+
config: Config
|
|
32
|
+
cache: Cache
|
|
33
|
+
network: NetworkInterface
|
|
34
|
+
identity: NodeIdentity
|
|
35
|
+
handlers: list[KnowledgeHandler]
|
|
36
|
+
kobj_queue: queue.Queue[KnowledgeObject]
|
|
37
|
+
use_kobj_processor_thread: bool
|
|
38
|
+
worker_thread: threading.Thread | None = None
|
|
39
|
+
|
|
40
|
+
def __init__(
|
|
41
|
+
self,
|
|
42
|
+
config: Config,
|
|
43
|
+
cache: Cache,
|
|
44
|
+
network: NetworkInterface,
|
|
45
|
+
identity: NodeIdentity,
|
|
46
|
+
use_kobj_processor_thread: bool,
|
|
47
|
+
default_handlers: list[KnowledgeHandler] = []
|
|
48
|
+
):
|
|
49
|
+
self.config = config
|
|
50
|
+
self.cache = cache
|
|
51
|
+
self.network = network
|
|
52
|
+
self.identity = identity
|
|
53
|
+
self.use_kobj_processor_thread = use_kobj_processor_thread
|
|
54
|
+
self.handlers: list[KnowledgeHandler] = default_handlers
|
|
55
|
+
self.kobj_queue = queue.Queue()
|
|
56
|
+
|
|
57
|
+
if self.use_kobj_processor_thread:
|
|
58
|
+
self.worker_thread = threading.Thread(
|
|
59
|
+
target=self.kobj_processor_worker,
|
|
60
|
+
daemon=True
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
def add_handler(self, handler: KnowledgeHandler):
|
|
64
|
+
self.handlers.append(handler)
|
|
65
|
+
|
|
66
|
+
def register_handler(
|
|
67
|
+
self,
|
|
68
|
+
handler_type: HandlerType,
|
|
69
|
+
rid_types: list[RIDType] | None = None,
|
|
70
|
+
source: KnowledgeSource | None = None,
|
|
71
|
+
event_types: list[KnowledgeEventType] | None = None
|
|
72
|
+
):
|
|
73
|
+
"""Assigns decorated function as handler for this processor."""
|
|
74
|
+
def decorator(func: Callable) -> Callable:
|
|
75
|
+
handler = KnowledgeHandler(func, handler_type, rid_types, source, event_types)
|
|
76
|
+
self.add_handler(handler)
|
|
77
|
+
return func
|
|
78
|
+
return decorator
|
|
79
|
+
|
|
80
|
+
def call_handler_chain(
|
|
81
|
+
self,
|
|
82
|
+
handler_type: HandlerType,
|
|
83
|
+
kobj: KnowledgeObject
|
|
84
|
+
) -> KnowledgeObject | StopChain:
|
|
85
|
+
"""Calls handlers of provided type, chaining their inputs and outputs together.
|
|
86
|
+
|
|
87
|
+
The knowledge object provided when this function is called will be passed to the first handler. A handler may return one of three types:
|
|
88
|
+
- `KnowledgeObject` - to modify the knowledge object for the next handler in the chain
|
|
89
|
+
- `None` - to keep the same knowledge object for the next handler in the chain
|
|
90
|
+
- `STOP_CHAIN` - to stop the handler chain and immediately exit the processing pipeline
|
|
91
|
+
|
|
92
|
+
Handlers will only be called in the chain if their handler and RID type match that of the inputted knowledge object.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
for handler in self.handlers:
|
|
96
|
+
if handler_type != handler.handler_type:
|
|
97
|
+
continue
|
|
98
|
+
|
|
99
|
+
if handler.rid_types and type(kobj.rid) not in handler.rid_types:
|
|
100
|
+
continue
|
|
101
|
+
|
|
102
|
+
if handler.source and handler.source != kobj.source:
|
|
103
|
+
continue
|
|
104
|
+
|
|
105
|
+
if handler.event_types and kobj.event_type not in handler.event_types:
|
|
106
|
+
continue
|
|
107
|
+
|
|
108
|
+
logger.debug(f"Calling {handler_type} handler '{handler.func.__name__}'")
|
|
109
|
+
resp = handler.func(self, kobj.model_copy())
|
|
110
|
+
|
|
111
|
+
# stops handler chain execution
|
|
112
|
+
if resp is STOP_CHAIN:
|
|
113
|
+
logger.debug(f"Handler chain stopped by {handler.func.__name__}")
|
|
114
|
+
return STOP_CHAIN
|
|
115
|
+
# kobj unmodified
|
|
116
|
+
elif resp is None:
|
|
117
|
+
continue
|
|
118
|
+
# kobj modified by handler
|
|
119
|
+
elif isinstance(resp, KnowledgeObject):
|
|
120
|
+
kobj = resp
|
|
121
|
+
logger.debug(f"Knowledge object modified by {handler.func.__name__}")
|
|
122
|
+
else:
|
|
123
|
+
raise ValueError(f"Handler {handler.func.__name__} returned invalid response '{resp}'")
|
|
124
|
+
|
|
125
|
+
return kobj
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def process_kobj(self, kobj: KnowledgeObject) -> None:
|
|
129
|
+
"""Sends provided knowledge obejct through knowledge processing pipeline.
|
|
130
|
+
|
|
131
|
+
Handler chains are called in between major events in the pipeline, indicated by their handler type. Each handler type is guaranteed to have access to certain knowledge, and may affect a subsequent action in the pipeline. The five handler types are as follows:
|
|
132
|
+
- RID - provided RID; if event type is `FORGET`, this handler decides whether to delete the knowledge from the cache by setting the normalized event type to `FORGET`, otherwise this handler decides whether to validate the manifest (and fetch it if not provided).
|
|
133
|
+
- Manifest - provided RID, manifest; decides whether to validate the bundle (and fetch it if not provided).
|
|
134
|
+
- Bundle - provided RID, manifest, contents (bundle); decides whether to write knowledge to the cache by setting the normalized event type to `NEW` or `UPDATE`.
|
|
135
|
+
- Network - provided RID, manifest, contents (bundle); decides which nodes (if any) to broadcast an event about this knowledge to. (Note, if event type is `FORGET`, the manifest and contents will be retrieved from the local cache, and indicate the last state of the knowledge before it was deleted.)
|
|
136
|
+
- Final - provided RID, manifests, contents (bundle); final action taken after network broadcast.
|
|
137
|
+
|
|
138
|
+
The pipeline may be stopped by any point by a single handler returning the `STOP_CHAIN` sentinel. In that case, the process will exit immediately. Further handlers of that type and later handler chains will not be called.
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
logger.debug(f"Handling {kobj!r}")
|
|
142
|
+
kobj = self.call_handler_chain(HandlerType.RID, kobj)
|
|
143
|
+
if kobj is STOP_CHAIN: return
|
|
144
|
+
|
|
145
|
+
if kobj.event_type == EventType.FORGET:
|
|
146
|
+
bundle = self.cache.read(kobj.rid)
|
|
147
|
+
if not bundle:
|
|
148
|
+
logger.debug("Local bundle not found")
|
|
149
|
+
return
|
|
150
|
+
|
|
151
|
+
# the bundle (to be deleted) attached to kobj for downstream analysis
|
|
152
|
+
logger.debug("Adding local bundle (to be deleted) to knowledge object")
|
|
153
|
+
kobj.manifest = bundle.manifest
|
|
154
|
+
kobj.contents = bundle.contents
|
|
155
|
+
|
|
156
|
+
else:
|
|
157
|
+
# attempt to retrieve manifest
|
|
158
|
+
if not kobj.manifest:
|
|
159
|
+
logger.debug("Manifest not found")
|
|
160
|
+
if kobj.source == KnowledgeSource.External:
|
|
161
|
+
logger.debug("Attempting to fetch remote manifest")
|
|
162
|
+
manifest = self.network.fetch_remote_manifest(kobj.rid)
|
|
163
|
+
|
|
164
|
+
elif kobj.source == KnowledgeSource.Internal:
|
|
165
|
+
logger.debug("Attempting to read manifest from cache")
|
|
166
|
+
bundle = self.cache.read(kobj.rid)
|
|
167
|
+
if bundle:
|
|
168
|
+
manifest = bundle.manifest
|
|
169
|
+
else:
|
|
170
|
+
manifest = None
|
|
171
|
+
return
|
|
172
|
+
|
|
173
|
+
if not manifest:
|
|
174
|
+
logger.debug("Failed to find manifest")
|
|
175
|
+
return
|
|
176
|
+
|
|
177
|
+
kobj.manifest = manifest
|
|
178
|
+
|
|
179
|
+
kobj = self.call_handler_chain(HandlerType.Manifest, kobj)
|
|
180
|
+
if kobj is STOP_CHAIN: return
|
|
181
|
+
|
|
182
|
+
# attempt to retrieve bundle
|
|
183
|
+
if not kobj.bundle:
|
|
184
|
+
logger.debug("Bundle not found")
|
|
185
|
+
if kobj.source == KnowledgeSource.External:
|
|
186
|
+
logger.debug("Attempting to fetch remote bundle")
|
|
187
|
+
bundle = self.network.fetch_remote_bundle(kobj.rid)
|
|
188
|
+
|
|
189
|
+
elif kobj.source == KnowledgeSource.Internal:
|
|
190
|
+
logger.debug("Attempting to read bundle from cache")
|
|
191
|
+
bundle = self.cache.read(kobj.rid)
|
|
192
|
+
|
|
193
|
+
if not bundle:
|
|
194
|
+
logger.debug("Failed to find bundle")
|
|
195
|
+
return
|
|
196
|
+
|
|
197
|
+
if kobj.manifest != bundle.manifest:
|
|
198
|
+
logger.warning("Retrieved bundle contains a different manifest")
|
|
199
|
+
|
|
200
|
+
kobj.manifest = bundle.manifest
|
|
201
|
+
kobj.contents = bundle.contents
|
|
202
|
+
|
|
203
|
+
kobj = self.call_handler_chain(HandlerType.Bundle, kobj)
|
|
204
|
+
if kobj is STOP_CHAIN: return
|
|
205
|
+
|
|
206
|
+
if kobj.normalized_event_type in (EventType.UPDATE, EventType.NEW):
|
|
207
|
+
logger.info(f"Writing to cache: {kobj!r}")
|
|
208
|
+
self.cache.write(kobj.bundle)
|
|
209
|
+
|
|
210
|
+
elif kobj.normalized_event_type == EventType.FORGET:
|
|
211
|
+
logger.info(f"Deleting from cache: {kobj!r}")
|
|
212
|
+
self.cache.delete(kobj.rid)
|
|
213
|
+
|
|
214
|
+
else:
|
|
215
|
+
logger.debug("Normalized event type was never set, no cache or network operations will occur")
|
|
216
|
+
return
|
|
217
|
+
|
|
218
|
+
if type(kobj.rid) in (KoiNetNode, KoiNetEdge):
|
|
219
|
+
logger.debug("Change to node or edge, regenerating network graph")
|
|
220
|
+
self.network.graph.generate()
|
|
221
|
+
|
|
222
|
+
kobj = self.call_handler_chain(HandlerType.Network, kobj)
|
|
223
|
+
if kobj is STOP_CHAIN: return
|
|
224
|
+
|
|
225
|
+
if kobj.network_targets:
|
|
226
|
+
logger.debug(f"Broadcasting event to {len(kobj.network_targets)} network target(s)")
|
|
227
|
+
else:
|
|
228
|
+
logger.debug("No network targets set")
|
|
229
|
+
|
|
230
|
+
for node in kobj.network_targets:
|
|
231
|
+
self.network.push_event_to(kobj.normalized_event, node)
|
|
232
|
+
if not self.network.flush_webhook_queue(node):
|
|
233
|
+
logger.warning("Dropping unresponsive node")
|
|
234
|
+
self.handle(rid=node, event_type=EventType.FORGET)
|
|
235
|
+
|
|
236
|
+
kobj = self.call_handler_chain(HandlerType.Final, kobj)
|
|
237
|
+
|
|
238
|
+
def flush_kobj_queue(self):
|
|
239
|
+
"""Flushes all knowledge objects from queue and processes them.
|
|
240
|
+
|
|
241
|
+
NOTE: ONLY CALL THIS METHOD IN SINGLE THREADED NODES, OTHERWISE THIS WILL CAUSE RACE CONDITIONS.
|
|
242
|
+
"""
|
|
243
|
+
if self.use_kobj_processor_thread:
|
|
244
|
+
logger.warning("You are using a worker thread, calling this method can cause race conditions!")
|
|
245
|
+
|
|
246
|
+
while not self.kobj_queue.empty():
|
|
247
|
+
kobj = self.kobj_queue.get()
|
|
248
|
+
logger.debug(f"Dequeued {kobj!r}")
|
|
249
|
+
|
|
250
|
+
try:
|
|
251
|
+
self.process_kobj(kobj)
|
|
252
|
+
finally:
|
|
253
|
+
self.kobj_queue.task_done()
|
|
254
|
+
logger.debug("Done")
|
|
255
|
+
|
|
256
|
+
def kobj_processor_worker(self, timeout=0.1):
|
|
257
|
+
while True:
|
|
258
|
+
try:
|
|
259
|
+
kobj = self.kobj_queue.get(timeout=timeout)
|
|
260
|
+
logger.debug(f"Dequeued {kobj!r}")
|
|
261
|
+
|
|
262
|
+
try:
|
|
263
|
+
self.process_kobj(kobj)
|
|
264
|
+
finally:
|
|
265
|
+
self.kobj_queue.task_done()
|
|
266
|
+
logger.debug("Done")
|
|
267
|
+
|
|
268
|
+
except queue.Empty:
|
|
269
|
+
pass
|
|
270
|
+
|
|
271
|
+
except Exception as e:
|
|
272
|
+
logger.warning(f"Error processing kobj: {e}")
|
|
273
|
+
|
|
274
|
+
def handle(
|
|
275
|
+
self,
|
|
276
|
+
rid: RID | None = None,
|
|
277
|
+
manifest: Manifest | None = None,
|
|
278
|
+
bundle: Bundle | None = None,
|
|
279
|
+
event: Event | None = None,
|
|
280
|
+
kobj: KnowledgeObject | None = None,
|
|
281
|
+
event_type: KnowledgeEventType = None,
|
|
282
|
+
source: KnowledgeSource = KnowledgeSource.Internal
|
|
283
|
+
):
|
|
284
|
+
"""Queues provided knowledge to be handled by processing pipeline.
|
|
285
|
+
|
|
286
|
+
Knowledge may take the form of an RID, manifest, bundle, event, or knowledge object (with an optional event type for RID, manifest, or bundle objects). All objects will be normalized into knowledge objects and queued. If `flush` is `True`, the queue will be flushed immediately after adding the new knowledge.
|
|
287
|
+
"""
|
|
288
|
+
if rid:
|
|
289
|
+
_kobj = KnowledgeObject.from_rid(rid, event_type, source)
|
|
290
|
+
elif manifest:
|
|
291
|
+
_kobj = KnowledgeObject.from_manifest(manifest, event_type, source)
|
|
292
|
+
elif bundle:
|
|
293
|
+
_kobj = KnowledgeObject.from_bundle(bundle, event_type, source)
|
|
294
|
+
elif event:
|
|
295
|
+
_kobj = KnowledgeObject.from_event(event, source)
|
|
296
|
+
elif kobj:
|
|
297
|
+
_kobj = kobj
|
|
298
|
+
else:
|
|
299
|
+
raise ValueError("One of 'rid', 'manifest', 'bundle', 'event', or 'kobj' must be provided")
|
|
300
|
+
|
|
301
|
+
self.kobj_queue.put(_kobj)
|
|
302
|
+
logger.debug(f"Queued {_kobj!r}")
|