koi-net 1.1.0b7__tar.gz → 1.1.0b8__tar.gz

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.

Files changed (44) hide show
  1. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/PKG-INFO +1 -1
  2. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/pyproject.toml +1 -1
  3. koi_net-1.1.0b8/src/koi_net/actor.py +60 -0
  4. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/context.py +5 -0
  5. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/core.py +5 -7
  6. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/lifecycle.py +7 -6
  7. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/network/error_handler.py +1 -1
  8. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/network/graph.py +7 -7
  9. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/network/resolver.py +1 -1
  10. koi_net-1.1.0b7/src/koi_net/network/behavior.py +0 -42
  11. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/.github/workflows/publish-to-pypi.yml +0 -0
  12. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/.gitignore +0 -0
  13. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/LICENSE +0 -0
  14. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/README.md +0 -0
  15. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/examples/coordinator.py +0 -0
  16. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/examples/partial.py +0 -0
  17. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/requirements.txt +0 -0
  18. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/__init__.py +0 -0
  19. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/config.py +0 -0
  20. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/default_actions.py +0 -0
  21. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/effector.py +0 -0
  22. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/identity.py +0 -0
  23. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/network/__init__.py +0 -0
  24. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/network/event_queue.py +0 -0
  25. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/network/request_handler.py +0 -0
  26. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/network/response_handler.py +0 -0
  27. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/poller.py +0 -0
  28. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/processor/__init__.py +0 -0
  29. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/processor/default_handlers.py +0 -0
  30. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/processor/handler.py +0 -0
  31. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/processor/interface.py +0 -0
  32. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/processor/knowledge_object.py +0 -0
  33. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/processor/knowledge_pipeline.py +0 -0
  34. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/protocol/__init__.py +0 -0
  35. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/protocol/api_models.py +0 -0
  36. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/protocol/consts.py +0 -0
  37. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/protocol/edge.py +0 -0
  38. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/protocol/envelope.py +0 -0
  39. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/protocol/errors.py +0 -0
  40. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/protocol/event.py +0 -0
  41. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/protocol/node.py +0 -0
  42. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/protocol/secure.py +0 -0
  43. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/secure.py +0 -0
  44. {koi_net-1.1.0b7 → koi_net-1.1.0b8}/src/koi_net/server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: koi-net
3
- Version: 1.1.0b7
3
+ Version: 1.1.0b8
4
4
  Summary: Implementation of KOI-net protocol in Python
5
5
  Project-URL: Homepage, https://github.com/BlockScience/koi-net/
6
6
  Author-email: Luke Miller <luke@block.science>
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "koi-net"
7
- version = "1.1.0-beta.7"
7
+ version = "1.1.0-beta.8"
8
8
  description = "Implementation of KOI-net protocol in Python"
9
9
  authors = [
10
10
  {name = "Luke Miller", email = "luke@block.science"}
@@ -0,0 +1,60 @@
1
+ from logging import getLogger
2
+ from rid_lib.types import KoiNetNode
3
+ from rid_lib import RIDType
4
+ from koi_net.context import HandlerContext
5
+ from koi_net.protocol.api_models import ErrorResponse
6
+ from .protocol.event import Event, EventType
7
+
8
+
9
+ logger = getLogger(__name__)
10
+
11
+
12
+ class Actor:
13
+ ctx: HandlerContext
14
+
15
+ def __init__(self):
16
+ pass
17
+
18
+ def set_ctx(self, ctx: HandlerContext):
19
+ self.ctx = ctx
20
+
21
+ def handshake_with(self, target: KoiNetNode):
22
+ logger.debug(f"Initiating handshake with {target}")
23
+ self.ctx.event_queue.push_event_to(
24
+ Event.from_rid(
25
+ event_type=EventType.FORGET,
26
+ rid=self.ctx.identity.rid),
27
+ node=target
28
+ )
29
+
30
+ self.ctx.event_queue.push_event_to(
31
+ event=Event.from_bundle(
32
+ event_type=EventType.NEW,
33
+ bundle=self.ctx.effector.deref(self.ctx.identity.rid)),
34
+ node=target
35
+ )
36
+
37
+ self.ctx.event_queue.flush_webhook_queue(target)
38
+
39
+ def identify_coordinators(self):
40
+ return self.ctx.resolver.get_state_providers(KoiNetNode)
41
+
42
+ def catch_up_with(self, target: KoiNetNode, rid_types: list[RIDType] = []):
43
+ logger.debug(f"catching up with {target} on {rid_types or 'all types'}")
44
+
45
+ payload = self.ctx.request_handler.fetch_manifests(
46
+ node=target,
47
+ rid_types=rid_types
48
+ )
49
+ if type(payload) == ErrorResponse:
50
+ logger.debug("failed to reach node")
51
+ return
52
+
53
+ for manifest in payload.manifests:
54
+ if manifest.rid == self.ctx.identity.rid:
55
+ continue
56
+
57
+ self.ctx.handle(
58
+ manifest=manifest,
59
+ source=target
60
+ )
@@ -1,4 +1,6 @@
1
1
  from rid_lib.ext import Cache
2
+
3
+ from koi_net.network.resolver import NetworkResolver
2
4
  from .config import NodeConfig
3
5
  from .effector import Effector
4
6
  from .network.graph import NetworkGraph
@@ -28,6 +30,7 @@ class HandlerContext:
28
30
  event_queue: NetworkEventQueue
29
31
  graph: NetworkGraph
30
32
  request_handler: RequestHandler
33
+ resolver: NetworkResolver
31
34
  effector: Effector
32
35
  _processor: ProcessorInterface | None
33
36
 
@@ -39,6 +42,7 @@ class HandlerContext:
39
42
  event_queue: NetworkEventQueue,
40
43
  graph: NetworkGraph,
41
44
  request_handler: RequestHandler,
45
+ resolver: NetworkResolver,
42
46
  effector: Effector
43
47
  ):
44
48
  self.identity = identity
@@ -47,6 +51,7 @@ class HandlerContext:
47
51
  self.event_queue = event_queue
48
52
  self.graph = graph
49
53
  self.request_handler = request_handler
54
+ self.resolver = resolver
50
55
  self.effector = effector
51
56
  self._processor = None
52
57
 
@@ -7,7 +7,7 @@ from .network.graph import NetworkGraph
7
7
  from .network.request_handler import RequestHandler
8
8
  from .network.response_handler import ResponseHandler
9
9
  from .network.error_handler import ErrorHandler
10
- from .network.behavior import Actor
10
+ from .actor import Actor
11
11
  from .processor.interface import ProcessorInterface
12
12
  from .processor import default_handlers
13
13
  from .processor.handler import KnowledgeHandler
@@ -110,11 +110,7 @@ class NodeInterface(Generic[T]):
110
110
  effector=self.effector
111
111
  )
112
112
 
113
- self.actor = (ActorOverride or Actor)(
114
- identity=self.identity,
115
- effector=self.effector,
116
- event_queue=self.event_queue
117
- )
113
+ self.actor = (ActorOverride or Actor)()
118
114
 
119
115
  # pull all handlers defined in default_handlers module
120
116
  if handlers is None:
@@ -137,6 +133,7 @@ class NodeInterface(Generic[T]):
137
133
  event_queue=self.event_queue,
138
134
  graph=self.graph,
139
135
  request_handler=self.request_handler,
136
+ resolver=self.resolver,
140
137
  effector=self.effector
141
138
  )
142
139
 
@@ -167,6 +164,8 @@ class NodeInterface(Generic[T]):
167
164
  self.effector.set_resolver(self.resolver)
168
165
  self.effector.set_action_context(self.action_context)
169
166
 
167
+ self.actor.set_ctx(self.handler_context)
168
+
170
169
  self.lifecycle = (NodeLifecycleOverride or NodeLifecycle)(
171
170
  config=self.config,
172
171
  identity=self.identity,
@@ -174,7 +173,6 @@ class NodeInterface(Generic[T]):
174
173
  processor=self.processor,
175
174
  effector=self.effector,
176
175
  actor=self.actor,
177
- handler_context=self.handler_context,
178
176
  use_kobj_processor_thread=use_kobj_processor_thread
179
177
  )
180
178
 
@@ -1,9 +1,9 @@
1
1
  import logging
2
2
  from contextlib import contextmanager, asynccontextmanager
3
3
 
4
- from koi_net.context import HandlerContext
4
+ from rid_lib.types import KoiNetNode
5
5
 
6
- from .network.behavior import Actor
6
+ from .actor import Actor
7
7
  from .effector import Effector
8
8
  from .config import NodeConfig
9
9
  from .processor.interface import ProcessorInterface
@@ -28,7 +28,6 @@ class NodeLifecycle:
28
28
  processor: ProcessorInterface,
29
29
  effector: Effector,
30
30
  actor: Actor,
31
- handler_context: HandlerContext,
32
31
  use_kobj_processor_thread: bool
33
32
  ):
34
33
  self.config = config
@@ -37,7 +36,6 @@ class NodeLifecycle:
37
36
  self.processor = processor
38
37
  self.effector = effector
39
38
  self.actor = actor
40
- self.handler_context = handler_context
41
39
  self.use_kobj_processor_thread = use_kobj_processor_thread
42
40
 
43
41
  @contextmanager
@@ -89,8 +87,11 @@ class NodeLifecycle:
89
87
  logger.debug(f"I don't have any neighbors, reaching out to first contact {self.config.koi_net.first_contact.rid!r}")
90
88
 
91
89
  self.actor.handshake_with(self.config.koi_net.first_contact.rid)
92
-
93
-
90
+
91
+ for coordinator in self.actor.identify_coordinators():
92
+ self.actor.catch_up_with(coordinator, rid_types=[KoiNetNode])
93
+
94
+
94
95
  def stop(self):
95
96
  """Stops a node, call this method last.
96
97
 
@@ -3,7 +3,7 @@ from koi_net.protocol.errors import ErrorType
3
3
  from koi_net.protocol.event import EventType
4
4
  from rid_lib.types import KoiNetNode
5
5
  from ..processor.interface import ProcessorInterface
6
- from ..network.behavior import Actor
6
+ from ..actor import Actor
7
7
 
8
8
  logger = getLogger(__name__)
9
9
 
@@ -57,15 +57,15 @@ class NetworkGraph:
57
57
  """Returns edges this node belongs to.
58
58
 
59
59
  All edges returned by default, specify `direction` to restrict to incoming or outgoing edges only."""
60
-
60
+
61
61
  edges = []
62
62
  if direction != "in" and self.dg.out_edges:
63
63
  out_edges = self.dg.out_edges(self.identity.rid)
64
- edges.extend([e for e in out_edges])
64
+ edges.extend(out_edges)
65
65
 
66
66
  if direction != "out" and self.dg.in_edges:
67
67
  in_edges = self.dg.in_edges(self.identity.rid)
68
- edges.extend([e for e in in_edges])
68
+ edges.extend(in_edges)
69
69
 
70
70
  edge_rids = []
71
71
  for edge in edges:
@@ -87,7 +87,7 @@ class NetworkGraph:
87
87
 
88
88
  All neighboring nodes returned by default, specify `direction` to restrict to neighbors connected by incoming or outgoing edges only."""
89
89
 
90
- neighbors = []
90
+ neighbors = set()
91
91
  for edge_rid in self.get_edges(direction):
92
92
  edge_bundle = self.cache.read(edge_rid)
93
93
 
@@ -96,7 +96,7 @@ class NetworkGraph:
96
96
  continue
97
97
 
98
98
  edge_profile = edge_bundle.validate_contents(EdgeProfile)
99
-
99
+
100
100
  if status and edge_profile.status != status:
101
101
  continue
102
102
 
@@ -104,9 +104,9 @@ class NetworkGraph:
104
104
  continue
105
105
 
106
106
  if edge_profile.target == self.identity.rid:
107
- neighbors.append(edge_profile.source)
107
+ neighbors.add(edge_profile.source)
108
108
  elif edge_profile.source == self.identity.rid:
109
- neighbors.append(edge_profile.target)
109
+ neighbors.add(edge_profile.target)
110
110
 
111
111
  return list(neighbors)
112
112
 
@@ -49,7 +49,7 @@ class NetworkResolver:
49
49
  def get_state_providers(self, rid_type: RIDType) -> list[KoiNetNode]:
50
50
  """Returns list of node RIDs which provide state for the specified RID type."""
51
51
 
52
- logger.debug(f"Looking for state providers of '{rid_type}'")
52
+ logger.debug(f"Looking for state providers of {rid_type}")
53
53
  provider_nodes = []
54
54
  for node_rid in self.cache.list_rids(rid_types=[KoiNetNode]):
55
55
  if node_rid == self.identity.rid:
@@ -1,42 +0,0 @@
1
- from logging import getLogger
2
- from rid_lib.types import KoiNetNode
3
- from ..protocol.event import Event, EventType
4
- from ..identity import NodeIdentity
5
- from ..effector import Effector
6
- from ..network.event_queue import NetworkEventQueue
7
-
8
- logger = getLogger(__name__)
9
-
10
-
11
- class Actor:
12
- identity: NodeIdentity
13
- effector: Effector
14
- event_queue: NetworkEventQueue
15
-
16
- def __init__(
17
- self,
18
- identity: NodeIdentity,
19
- effector: Effector,
20
- event_queue: NetworkEventQueue
21
- ):
22
- self.identity = identity
23
- self.effector = effector
24
- self.event_queue = event_queue
25
-
26
- def handshake_with(self, target: KoiNetNode):
27
- logger.debug(f"Initiating handshake with {target}")
28
- self.event_queue.push_event_to(
29
- Event.from_rid(
30
- event_type=EventType.FORGET,
31
- rid=self.identity.rid),
32
- node=target
33
- )
34
-
35
- self.event_queue.push_event_to(
36
- event=Event.from_bundle(
37
- event_type=EventType.NEW,
38
- bundle=self.effector.deref(self.identity.rid)),
39
- node=target
40
- )
41
-
42
- self.event_queue.flush_webhook_queue(target)
File without changes
File without changes
File without changes
File without changes
File without changes