Skip to content

Commit 3857f10

Browse files
committed
refactored effector to work similar to the processing pipeline, accepts a list of deref handlers, made public key overwrite warning more specific, gave effector deref handlers access to handler context, readded post init injection to effector
1 parent 56fe7e3 commit 3857f10

File tree

5 files changed

+57
-66
lines changed

5 files changed

+57
-66
lines changed

src/koi_net/assembler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class NodeContainer(Protocol):
4141
"""Dummy 'shape' for node containers built by assembler."""
4242
entrypoint = EntryPoint
4343

44-
class NodeAssembler(metaclass=BuildOrderer):
44+
class NodeAssembler(metaclass=BuildOrderer):
4545
def __new__(self) -> NodeContainer:
4646
"""Returns assembled node container."""
4747
return self._build()

src/koi_net/config/core.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ def generate_rid_cascade(self):
101101
log.debug(f"Node RID set to {self.koi_net.node_rid}")
102102

103103
if self.koi_net.node_profile.public_key != pub_key.to_der():
104+
if self.koi_net.node_profile.public_key:
105+
log.warning("New private key overwriting old public key!")
106+
104107
self.koi_net.node_profile.public_key = pub_key.to_der()
105-
log.warning("New private key overwrote old public key!")
106108

107109
return self

src/koi_net/core.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class BaseNode(NodeAssembler):
5050
basic_network_output_filter,
5151
forget_edge_on_node_deletion
5252
]
53+
deref_handlers = []
5354
cache = lambda config: Cache(
5455
directory_path=config.koi_net.cache_directory_path)
5556
identity = NodeIdentity
@@ -61,8 +62,8 @@ class BaseNode(NodeAssembler):
6162
sync_manager = SyncManager
6263
response_handler = ResponseHandler
6364
resolver = NetworkResolver
64-
effector = Effector
6565
handler_context = HandlerContext
66+
effector = Effector
6667
pipeline = KnowledgePipeline
6768
kobj_worker = KnowledgeProcessingWorker
6869
event_worker = EventProcessingWorker

src/koi_net/effector.py

Lines changed: 41 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,33 @@
1-
import structlog
1+
from dataclasses import dataclass
22
from typing import Callable
33
from enum import StrEnum
4+
5+
import structlog
46
from rid_lib.ext import Cache, Bundle
57
from rid_lib.core import RID, RIDType
68
from rid_lib.types import KoiNetNode
9+
10+
from .processor.context import HandlerContext
711
from .network.resolver import NetworkResolver
812
from .processor.kobj_queue import KobjQueue
9-
from .identity import NodeIdentity
1013

1114
log = structlog.stdlib.get_logger()
1215

13-
14-
class ActionContext:
15-
"""Provides action handlers access to other subsystems."""
16+
@dataclass
17+
class DerefHandler:
18+
func: Callable[[HandlerContext, RID], Bundle | None]
19+
rid_types: tuple[RIDType]
1620

17-
identity: NodeIdentity
18-
19-
def __init__(
20-
self,
21-
identity: NodeIdentity,
22-
):
23-
self.identity = identity
21+
def __call__(self, ctx: HandlerContext, rid: RID) -> Bundle | None:
22+
return self.func(ctx, rid)
2423

24+
@classmethod
25+
def create(cls, rid_types: tuple[RIDType]):
26+
def decorator(func: Callable) -> DerefHandler:
27+
handler = cls(func, rid_types)
28+
return handler
29+
return decorator
30+
2531

2632
class BundleSource(StrEnum):
2733
CACHE = "CACHE"
@@ -33,50 +39,23 @@ class Effector:
3339
cache: Cache
3440
resolver: NetworkResolver
3541
kobj_queue: KobjQueue
36-
action_context: ActionContext
37-
_action_table: dict[
38-
type[RID],
39-
Callable[
40-
[ActionContext, RID],
41-
Bundle | None
42-
]
43-
] = dict()
42+
handler_context: HandlerContext
4443

4544
def __init__(
4645
self,
4746
cache: Cache,
4847
resolver: NetworkResolver,
4948
kobj_queue: KobjQueue,
50-
identity: NodeIdentity
49+
handler_context: HandlerContext,
50+
deref_handlers: list[DerefHandler]
5151
):
5252
self.cache = cache
5353
self.resolver = resolver
5454
self.kobj_queue = kobj_queue
55-
self.action_context = ActionContext(identity)
56-
self._action_table = self.__class__._action_table.copy()
57-
58-
@classmethod
59-
def register_default_action(cls, rid_type: RIDType):
60-
def decorator(func: Callable) -> Callable:
61-
cls._action_table[rid_type] = func
62-
return func
63-
return decorator
64-
65-
def register_action(self, rid_type: RIDType):
66-
"""Registers a new dereference action for an RID type.
55+
self.handler_context = handler_context
56+
self.deref_handlers = deref_handlers
6757

68-
Example:
69-
This function should be used as a decorator on an action function::
70-
71-
@node.register_action(KoiNetNode)
72-
def deref_koi_net_node(ctx: ActionContext, rid: KoiNetNode):
73-
# return a Bundle or None
74-
return
75-
"""
76-
def decorator(func: Callable) -> Callable:
77-
self._action_table[rid_type] = func
78-
return func
79-
return decorator
58+
self.handler_context.set_effector(self)
8059

8160
def _try_cache(self, rid: RID) -> tuple[Bundle, BundleSource] | None:
8261
bundle = self.cache.read(rid)
@@ -87,26 +66,27 @@ def _try_cache(self, rid: RID) -> tuple[Bundle, BundleSource] | None:
8766
else:
8867
log.debug("Cache miss")
8968
return None
90-
69+
9170
def _try_action(self, rid: RID) -> tuple[Bundle, BundleSource] | None:
92-
if type(rid) not in self._action_table:
93-
log.debug("No action available")
71+
action = None
72+
for handler in self.deref_handlers:
73+
if type(rid) not in handler.rid_types:
74+
continue
75+
action = handler
76+
break
77+
78+
if not action:
79+
log.debug("No action found")
9480
return None
9581

96-
log.debug("Action available")
97-
func = self._action_table[type(rid)]
98-
bundle = func(
99-
ctx=self.action_context,
100-
rid=rid
101-
)
82+
bundle = action(ctx=self.handler_context, rid=rid)
10283

10384
if bundle:
10485
log.debug("Action hit")
10586
return bundle, BundleSource.ACTION
10687
else:
10788
log.debug("Action miss")
10889
return None
109-
11090

11191
def _try_network(self, rid: RID) -> tuple[Bundle, KoiNetNode] | None:
11292
bundle, source = self.resolver.fetch_remote_bundle(rid)
@@ -118,13 +98,13 @@ def _try_network(self, rid: RID) -> tuple[Bundle, KoiNetNode] | None:
11898
log.debug("Network miss")
11999
return None
120100

121-
122101
def deref(
123102
self,
124103
rid: RID,
125104
refresh_cache: bool = False,
126105
use_network: bool = False,
127-
handle_result: bool = True
106+
handle_result: bool = True,
107+
write_through: bool = False
128108
) -> Bundle | None:
129109
"""Dereferences an RID.
130110
@@ -136,7 +116,7 @@ def deref(
136116
rid: RID to dereference
137117
refresh_cache: skips cache read when `True`
138118
use_network: enables fetching from other nodes when `True`
139-
handle_result: handles resulting bundle with knowledge pipeline when `True`
119+
handle_result: sends resulting bundle to kobj queue when `True`
140120
"""
141121

142122
log.debug(f"Dereferencing {rid!r}")
@@ -159,6 +139,9 @@ def deref(
159139
bundle=bundle,
160140
source=source if type(source) is KoiNetNode else None
161141
)
142+
143+
if write_through:
144+
self.kobj_queue.q.join()
162145

163146
# TODO: refactor for general solution, param to write through to cache before continuing
164147
# like `self.processor.kobj_queue.join()``

src/koi_net/processor/context.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1+
from typing import TYPE_CHECKING
12
from rid_lib.ext import Cache
23

3-
from koi_net.effector import Effector
4-
from koi_net.network.resolver import NetworkResolver
4+
from ..network.resolver import NetworkResolver
55
from ..config.core import NodeConfig
66
from ..network.graph import NetworkGraph
77
from ..network.event_queue import EventQueue
88
from ..network.request_handler import RequestHandler
99
from ..identity import NodeIdentity
1010
from .kobj_queue import KobjQueue
1111

12+
if TYPE_CHECKING:
13+
from ..effector import Effector
14+
1215

1316
class HandlerContext:
1417
"""Context object provides knowledge handlers access to other components."""
@@ -21,7 +24,7 @@ class HandlerContext:
2124
graph: NetworkGraph
2225
request_handler: RequestHandler
2326
resolver: NetworkResolver
24-
effector: Effector
27+
effector: "Effector"
2528

2629
def __init__(
2730
self,
@@ -32,8 +35,7 @@ def __init__(
3235
kobj_queue: KobjQueue,
3336
graph: NetworkGraph,
3437
request_handler: RequestHandler,
35-
resolver: NetworkResolver,
36-
effector: Effector
38+
resolver: NetworkResolver
3739
):
3840
self.identity = identity
3941
self.config = config
@@ -43,4 +45,7 @@ def __init__(
4345
self.graph = graph
4446
self.request_handler = request_handler
4547
self.resolver = resolver
48+
49+
def set_effector(self, effector: "Effector"):
50+
"""Post initialization injection of effector component."""
4651
self.effector = effector

0 commit comments

Comments
 (0)