flwr 1.25.0__py3-none-any.whl → 1.26.0__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.
- flwr/__init__.py +1 -1
- flwr/app/__init__.py +4 -1
- flwr/app/message_type.py +29 -0
- flwr/app/metadata.py +5 -2
- flwr/app/user_config.py +19 -0
- flwr/cli/app.py +37 -19
- flwr/cli/app_cmd/publish.py +25 -75
- flwr/cli/app_cmd/review.py +18 -69
- flwr/cli/auth_plugin/auth_plugin.py +5 -10
- flwr/cli/auth_plugin/noop_auth_plugin.py +1 -2
- flwr/cli/auth_plugin/oidc_cli_plugin.py +38 -38
- flwr/cli/build.py +15 -28
- flwr/cli/config/__init__.py +21 -0
- flwr/cli/config/ls.py +71 -0
- flwr/cli/config_migration.py +297 -0
- flwr/cli/config_utils.py +63 -156
- flwr/cli/constant.py +71 -0
- flwr/cli/federation/__init__.py +0 -2
- flwr/cli/federation/ls.py +256 -64
- flwr/cli/flower_config.py +429 -0
- flwr/cli/install.py +23 -62
- flwr/cli/log.py +23 -37
- flwr/cli/login/login.py +29 -63
- flwr/cli/ls.py +28 -58
- flwr/cli/new/new.py +9 -29
- flwr/cli/pull.py +19 -37
- flwr/cli/run/run.py +85 -93
- flwr/cli/run_utils.py +1 -1
- flwr/cli/stop.py +32 -73
- flwr/cli/supernode/ls.py +25 -57
- flwr/cli/supernode/register.py +31 -80
- flwr/cli/supernode/unregister.py +24 -70
- flwr/cli/typing.py +200 -0
- flwr/cli/utils.py +160 -275
- flwr/client/grpc_rere_client/connection.py +3 -3
- flwr/client/grpc_rere_client/grpc_adapter.py +1 -1
- flwr/client/message_handler/message_handler.py +2 -1
- flwr/client/mod/centraldp_mods.py +1 -1
- flwr/client/mod/localdp_mod.py +1 -1
- flwr/client/mod/secure_aggregation/secaggplus_mod.py +1 -1
- flwr/client/run_info_store.py +2 -1
- flwr/clientapp/client_app.py +2 -1
- flwr/common/__init__.py +3 -2
- flwr/common/args.py +5 -5
- flwr/common/config.py +12 -17
- flwr/common/constant.py +3 -16
- flwr/common/context.py +2 -1
- flwr/common/exit/exit.py +4 -4
- flwr/common/exit/exit_code.py +6 -0
- flwr/common/grpc.py +2 -1
- flwr/common/logger.py +1 -1
- flwr/common/message.py +1 -1
- flwr/common/retry_invoker.py +13 -5
- flwr/common/secure_aggregation/ndarrays_arithmetic.py +5 -2
- flwr/common/serde.py +7 -5
- flwr/common/telemetry.py +1 -1
- flwr/common/typing.py +4 -3
- flwr/compat/client/app.py +6 -9
- flwr/compat/client/grpc_client/connection.py +2 -1
- flwr/compat/common/constant.py +29 -0
- flwr/compat/server/app.py +1 -1
- flwr/proto/clientappio_pb2.py +2 -2
- flwr/proto/clientappio_pb2_grpc.py +104 -88
- flwr/proto/clientappio_pb2_grpc.pyi +140 -80
- flwr/proto/federation_pb2.py +5 -3
- flwr/proto/federation_pb2.pyi +32 -2
- flwr/proto/run_pb2.py +5 -13
- flwr/proto/run_pb2.pyi +0 -57
- flwr/proto/serverappio_pb2.py +2 -2
- flwr/proto/serverappio_pb2_grpc.py +138 -207
- flwr/proto/serverappio_pb2_grpc.pyi +189 -155
- flwr/proto/simulationio_pb2.py +2 -2
- flwr/proto/simulationio_pb2_grpc.py +62 -90
- flwr/proto/simulationio_pb2_grpc.pyi +95 -55
- flwr/server/app.py +6 -13
- flwr/server/compat/grid_client_proxy.py +2 -1
- flwr/server/grid/grpc_grid.py +5 -5
- flwr/server/serverapp/app.py +11 -4
- flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +1 -1
- flwr/server/superlink/fleet/grpc_rere/node_auth_server_interceptor.py +13 -12
- flwr/server/superlink/fleet/message_handler/message_handler.py +6 -5
- flwr/server/superlink/linkstate/__init__.py +2 -2
- flwr/server/superlink/linkstate/in_memory_linkstate.py +2 -10
- flwr/server/superlink/linkstate/linkstate.py +2 -21
- flwr/server/superlink/linkstate/linkstate_factory.py +16 -8
- flwr/server/superlink/linkstate/{sqlite_linkstate.py → sql_linkstate.py} +432 -534
- flwr/server/superlink/linkstate/utils.py +49 -2
- flwr/server/superlink/serverappio/serverappio_servicer.py +1 -33
- flwr/server/superlink/simulation/simulationio_servicer.py +0 -19
- flwr/server/utils/validator.py +1 -1
- flwr/server/workflow/default_workflows.py +2 -1
- flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +1 -1
- flwr/serverapp/strategy/bulyan.py +7 -1
- flwr/serverapp/strategy/dp_fixed_clipping.py +9 -1
- flwr/serverapp/strategy/fedavg.py +1 -1
- flwr/serverapp/strategy/fedxgb_cyclic.py +1 -1
- flwr/simulation/ray_transport/ray_client_proxy.py +2 -6
- flwr/simulation/run_simulation.py +3 -12
- flwr/simulation/simulationio_connection.py +3 -3
- flwr/{common → supercore}/address.py +7 -33
- flwr/supercore/app_utils.py +2 -1
- flwr/supercore/constant.py +24 -2
- flwr/supercore/corestate/{sqlite_corestate.py → sql_corestate.py} +19 -23
- flwr/supercore/credential_store/__init__.py +33 -0
- flwr/supercore/credential_store/credential_store.py +34 -0
- flwr/supercore/credential_store/file_credential_store.py +76 -0
- flwr/{common → supercore}/date.py +0 -11
- flwr/supercore/ffs/disk_ffs.py +1 -1
- flwr/supercore/object_store/object_store_factory.py +14 -6
- flwr/supercore/object_store/{sqlite_object_store.py → sql_object_store.py} +115 -117
- flwr/supercore/sql_mixin.py +315 -0
- flwr/supercore/state/__init__.py +15 -0
- flwr/supercore/state/alembic/__init__.py +15 -0
- flwr/supercore/state/alembic/env.py +103 -0
- flwr/supercore/state/alembic/script.py.mako +43 -0
- flwr/supercore/state/alembic/utils.py +239 -0
- flwr/supercore/state/alembic/versions/__init__.py +15 -0
- flwr/supercore/state/alembic/versions/rev_2026_01_28_initialize_migration_of_state_tables.py +200 -0
- flwr/supercore/state/schema/README.md +121 -0
- flwr/supercore/state/schema/__init__.py +15 -0
- flwr/supercore/state/schema/corestate_tables.py +36 -0
- flwr/supercore/state/schema/linkstate_tables.py +152 -0
- flwr/supercore/state/schema/objectstore_tables.py +90 -0
- flwr/supercore/superexec/run_superexec.py +2 -2
- flwr/supercore/utils.py +36 -1
- flwr/superlink/federation/federation_manager.py +2 -2
- flwr/superlink/federation/noop_federation_manager.py +8 -6
- flwr/superlink/servicer/control/control_servicer.py +19 -17
- flwr/supernode/cli/flower_supernode.py +2 -1
- flwr/supernode/runtime/run_clientapp.py +14 -14
- flwr/supernode/servicer/clientappio/clientappio_servicer.py +10 -8
- flwr/supernode/start_client_internal.py +10 -6
- {flwr-1.25.0.dist-info → flwr-1.26.0.dist-info}/METADATA +7 -5
- {flwr-1.25.0.dist-info → flwr-1.26.0.dist-info}/RECORD +137 -116
- flwr/cli/federation/show.py +0 -318
- flwr/common/pyproject.py +0 -42
- flwr/supercore/sqlite_mixin.py +0 -159
- /flwr/{common → supercore}/version.py +0 -0
- {flwr-1.25.0.dist-info → flwr-1.26.0.dist-info}/WHEEL +0 -0
- {flwr-1.25.0.dist-info → flwr-1.26.0.dist-info}/entry_points.txt +0 -0
flwr/server/grid/grpc_grid.py
CHANGED
|
@@ -28,7 +28,6 @@ from flwr.common.constant import (
|
|
|
28
28
|
SERVERAPPIO_API_DEFAULT_CLIENT_ADDRESS,
|
|
29
29
|
SUPERLINK_NODE_ID,
|
|
30
30
|
ErrorCode,
|
|
31
|
-
MessageType,
|
|
32
31
|
)
|
|
33
32
|
from flwr.common.grpc import create_channel, on_channel_state_change
|
|
34
33
|
from flwr.common.inflatable import (
|
|
@@ -50,7 +49,7 @@ from flwr.common.inflatable_utils import (
|
|
|
50
49
|
)
|
|
51
50
|
from flwr.common.logger import log, warn_deprecated_feature
|
|
52
51
|
from flwr.common.message import make_message, remove_content_from_message
|
|
53
|
-
from flwr.common.retry_invoker import
|
|
52
|
+
from flwr.common.retry_invoker import make_simple_grpc_retry_invoker, wrap_stub
|
|
54
53
|
from flwr.common.serde import message_to_proto, run_from_proto
|
|
55
54
|
from flwr.common.typing import Run
|
|
56
55
|
from flwr.proto.appio_pb2 import ( # pylint: disable=E0611
|
|
@@ -69,6 +68,7 @@ from flwr.proto.serverappio_pb2 import ( # pylint: disable=E0611
|
|
|
69
68
|
GetNodesResponse,
|
|
70
69
|
)
|
|
71
70
|
from flwr.proto.serverappio_pb2_grpc import ServerAppIoStub # pylint: disable=E0611
|
|
71
|
+
from flwr.supercore.constant import SYSTEM_MESSAGE_TYPE
|
|
72
72
|
|
|
73
73
|
from .grid import Grid
|
|
74
74
|
|
|
@@ -127,7 +127,7 @@ class GrpcGrid(Grid):
|
|
|
127
127
|
self._grpc_stub: ServerAppIoStub | None = None
|
|
128
128
|
self._channel: grpc.Channel | None = None
|
|
129
129
|
self.node = Node(node_id=SUPERLINK_NODE_ID)
|
|
130
|
-
self._retry_invoker =
|
|
130
|
+
self._retry_invoker = make_simple_grpc_retry_invoker()
|
|
131
131
|
super().__init__()
|
|
132
132
|
|
|
133
133
|
@property
|
|
@@ -150,7 +150,7 @@ class GrpcGrid(Grid):
|
|
|
150
150
|
)
|
|
151
151
|
self._channel.subscribe(on_channel_state_change)
|
|
152
152
|
self._grpc_stub = ServerAppIoStub(self._channel)
|
|
153
|
-
|
|
153
|
+
wrap_stub(self._grpc_stub, self._retry_invoker)
|
|
154
154
|
log(DEBUG, "[flwr-serverapp] Connected to %s", self._addr)
|
|
155
155
|
|
|
156
156
|
def _disconnect(self) -> None:
|
|
@@ -341,7 +341,7 @@ class GrpcGrid(Grid):
|
|
|
341
341
|
message_id="",
|
|
342
342
|
src_node_id=self.node.node_id,
|
|
343
343
|
dst_node_id=self.node.node_id,
|
|
344
|
-
message_type=
|
|
344
|
+
message_type=SYSTEM_MESSAGE_TYPE,
|
|
345
345
|
group_id="",
|
|
346
346
|
ttl=0,
|
|
347
347
|
reply_to_message_id=msg_proto.metadata.reply_to_message_id,
|
flwr/server/serverapp/app.py
CHANGED
|
@@ -144,6 +144,10 @@ def run_serverapp( # pylint: disable=R0913, R0914, R0915, R0917, W0212
|
|
|
144
144
|
exit_code = ExitCode.SUCCESS
|
|
145
145
|
|
|
146
146
|
def on_exit() -> None:
|
|
147
|
+
# Set Grpc max retries to 1 to avoid blocking on exit
|
|
148
|
+
if grid:
|
|
149
|
+
grid._retry_invoker.max_tries = 1
|
|
150
|
+
|
|
147
151
|
# Stop heartbeat sender
|
|
148
152
|
if heartbeat_sender and heartbeat_sender.is_running:
|
|
149
153
|
heartbeat_sender.stop()
|
|
@@ -154,10 +158,13 @@ def run_serverapp( # pylint: disable=R0913, R0914, R0915, R0917, W0212
|
|
|
154
158
|
|
|
155
159
|
# Update run status
|
|
156
160
|
if run and run_status and grid:
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
+
try:
|
|
162
|
+
req = UpdateRunStatusRequest(
|
|
163
|
+
run_id=run.run_id, run_status=run_status_to_proto(run_status)
|
|
164
|
+
)
|
|
165
|
+
grid._stub.UpdateRunStatus(req)
|
|
166
|
+
except grpc.RpcError:
|
|
167
|
+
pass
|
|
161
168
|
|
|
162
169
|
# Close the Grpc connection
|
|
163
170
|
if grid:
|
|
@@ -30,7 +30,6 @@ from flwr.common.constant import (
|
|
|
30
30
|
GRPC_ADAPTER_METADATA_MESSAGE_QUALNAME_KEY,
|
|
31
31
|
)
|
|
32
32
|
from flwr.common.logger import log
|
|
33
|
-
from flwr.common.version import package_name, package_version
|
|
34
33
|
from flwr.proto import grpcadapter_pb2_grpc # pylint: disable=E0611
|
|
35
34
|
from flwr.proto.fab_pb2 import GetFabRequest # pylint: disable=E0611
|
|
36
35
|
from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611
|
|
@@ -49,6 +48,7 @@ from flwr.proto.message_pb2 import ( # pylint: disable=E0611
|
|
|
49
48
|
PushObjectRequest,
|
|
50
49
|
)
|
|
51
50
|
from flwr.proto.run_pb2 import GetRunRequest # pylint: disable=E0611
|
|
51
|
+
from flwr.supercore.version import package_name, package_version
|
|
52
52
|
|
|
53
53
|
from ..grpc_rere.fleet_servicer import FleetServicer
|
|
54
54
|
|
|
@@ -108,7 +108,7 @@ class NodeAuthServerInterceptor(grpc.ServerInterceptor): # type: ignore
|
|
|
108
108
|
def _wrap_method_handler(
|
|
109
109
|
self,
|
|
110
110
|
method_handler: grpc.RpcMethodHandler,
|
|
111
|
-
|
|
111
|
+
received_public_key: bytes,
|
|
112
112
|
) -> grpc.RpcMethodHandler:
|
|
113
113
|
def _generic_method_handler(
|
|
114
114
|
request: GrpcMessage,
|
|
@@ -117,21 +117,22 @@ class NodeAuthServerInterceptor(grpc.ServerInterceptor): # type: ignore
|
|
|
117
117
|
# Note: This function runs in a different thread
|
|
118
118
|
# than the `intercept_service` function.
|
|
119
119
|
|
|
120
|
-
#
|
|
121
|
-
if isinstance(request, (RegisterNodeFleetRequest
|
|
122
|
-
|
|
123
|
-
else:
|
|
120
|
+
# Skip registration and activation requests
|
|
121
|
+
if not isinstance(request, (RegisterNodeFleetRequest, ActivateNodeRequest)):
|
|
122
|
+
# Retrieve the node ID from the request
|
|
124
123
|
if hasattr(request, "node"):
|
|
125
|
-
|
|
124
|
+
received_node_id = request.node.node_id
|
|
126
125
|
else:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
received_node_id = request.node_id # type: ignore[attr-defined]
|
|
127
|
+
|
|
128
|
+
# Get the actual node ID based on the received public key
|
|
129
|
+
node_id = self.state_factory.state().get_node_id_by_public_key(
|
|
130
|
+
received_public_key
|
|
130
131
|
)
|
|
131
132
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
# Verify that the received node ID matches the actual node ID
|
|
134
|
+
if received_node_id != node_id:
|
|
135
|
+
context.abort(grpc.StatusCode.UNAUTHENTICATED, "Invalid node ID")
|
|
135
136
|
|
|
136
137
|
response: GrpcMessage = method_handler.unary_unary(request, context)
|
|
137
138
|
return response
|
|
@@ -166,13 +166,13 @@ def pull_messages( # pylint: disable=too-many-locals
|
|
|
166
166
|
response = PullMessagesResponse(messages_list=msg_proto, message_object_trees=trees)
|
|
167
167
|
|
|
168
168
|
# Record incoming traffic size
|
|
169
|
-
bytes_recv =
|
|
169
|
+
bytes_recv = request.ByteSize()
|
|
170
170
|
|
|
171
171
|
# Record traffic only if message was successfully processed
|
|
172
172
|
# All messages in this request are assumed to belong to the same run
|
|
173
173
|
if run_id_to_record is not None:
|
|
174
174
|
# Record outgoing traffic size
|
|
175
|
-
bytes_sent =
|
|
175
|
+
bytes_sent = response.ByteSize()
|
|
176
176
|
state.store_traffic(
|
|
177
177
|
run_id_to_record, bytes_sent=bytes_sent, bytes_recv=bytes_recv
|
|
178
178
|
)
|
|
@@ -191,7 +191,7 @@ def push_messages(
|
|
|
191
191
|
run_id = msg.metadata.run_id
|
|
192
192
|
|
|
193
193
|
# Record incoming traffic size
|
|
194
|
-
bytes_recv =
|
|
194
|
+
bytes_recv = request.ByteSize()
|
|
195
195
|
|
|
196
196
|
# Abort if the run is not running
|
|
197
197
|
abort_msg = check_abort(
|
|
@@ -218,7 +218,7 @@ def push_messages(
|
|
|
218
218
|
)
|
|
219
219
|
|
|
220
220
|
# Record outgoing traffic size
|
|
221
|
-
bytes_sent =
|
|
221
|
+
bytes_sent = response.ByteSize()
|
|
222
222
|
|
|
223
223
|
# Record traffic only if message was successfully processed
|
|
224
224
|
# Only one message is processed per request
|
|
@@ -321,7 +321,8 @@ def pull_object(
|
|
|
321
321
|
if content is not None:
|
|
322
322
|
object_available = content != b""
|
|
323
323
|
# Record bytes traffic pulled by SuperNode
|
|
324
|
-
|
|
324
|
+
if object_available:
|
|
325
|
+
state.store_traffic(request.run_id, bytes_sent=len(content), bytes_recv=0)
|
|
325
326
|
return PullObjectResponse(
|
|
326
327
|
object_found=True,
|
|
327
328
|
object_available=object_available,
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
from .in_memory_linkstate import InMemoryLinkState as InMemoryLinkState
|
|
19
19
|
from .linkstate import LinkState as LinkState
|
|
20
20
|
from .linkstate_factory import LinkStateFactory as LinkStateFactory
|
|
21
|
-
from .
|
|
21
|
+
from .sql_linkstate import SqlLinkState as SqlLinkState
|
|
22
22
|
|
|
23
23
|
__all__ = [
|
|
24
24
|
"InMemoryLinkState",
|
|
25
25
|
"LinkState",
|
|
26
26
|
"LinkStateFactory",
|
|
27
|
-
"
|
|
27
|
+
"SqlLinkState",
|
|
28
28
|
]
|
|
@@ -23,6 +23,7 @@ from dataclasses import dataclass, field
|
|
|
23
23
|
from datetime import datetime, timezone
|
|
24
24
|
from logging import ERROR, WARNING
|
|
25
25
|
|
|
26
|
+
from flwr.app.user_config import UserConfig
|
|
26
27
|
from flwr.common import Context, Message, log, now
|
|
27
28
|
from flwr.common.constant import (
|
|
28
29
|
HEARTBEAT_PATIENCE,
|
|
@@ -35,7 +36,7 @@ from flwr.common.constant import (
|
|
|
35
36
|
SubStatus,
|
|
36
37
|
)
|
|
37
38
|
from flwr.common.record import ConfigRecord
|
|
38
|
-
from flwr.common.typing import Run, RunStatus
|
|
39
|
+
from flwr.common.typing import Run, RunStatus
|
|
39
40
|
from flwr.proto.node_pb2 import NodeInfo # pylint: disable=E0611
|
|
40
41
|
from flwr.server.superlink.linkstate.linkstate import LinkState
|
|
41
42
|
from flwr.server.utils import validate_message
|
|
@@ -518,15 +519,6 @@ class InMemoryLinkState(LinkState, InMemoryCoreState): # pylint: disable=R0902,
|
|
|
518
519
|
node.online_until, tz=timezone.utc
|
|
519
520
|
).isoformat()
|
|
520
521
|
|
|
521
|
-
def get_node_public_key(self, node_id: int) -> bytes:
|
|
522
|
-
"""Get `public_key` for the specified `node_id`."""
|
|
523
|
-
with self.lock:
|
|
524
|
-
if (
|
|
525
|
-
node := self.nodes.get(node_id)
|
|
526
|
-
) is None or node.status == NodeStatus.UNREGISTERED:
|
|
527
|
-
raise ValueError(f"Node ID {node_id} not found")
|
|
528
|
-
return node.public_key
|
|
529
|
-
|
|
530
522
|
def get_node_id_by_public_key(self, public_key: bytes) -> int | None:
|
|
531
523
|
"""Get `node_id` for the specified `public_key` if it exists and is not
|
|
532
524
|
deleted."""
|
|
@@ -18,9 +18,10 @@
|
|
|
18
18
|
import abc
|
|
19
19
|
from collections.abc import Sequence
|
|
20
20
|
|
|
21
|
+
from flwr.app.user_config import UserConfig
|
|
21
22
|
from flwr.common import Context, Message
|
|
22
23
|
from flwr.common.record import ConfigRecord
|
|
23
|
-
from flwr.common.typing import Run, RunStatus
|
|
24
|
+
from flwr.common.typing import Run, RunStatus
|
|
24
25
|
from flwr.proto.node_pb2 import NodeInfo # pylint: disable=E0611
|
|
25
26
|
from flwr.supercore.corestate import CoreState
|
|
26
27
|
from flwr.superlink.federation import FederationManager
|
|
@@ -245,26 +246,6 @@ class LinkState(CoreState): # pylint: disable=R0904
|
|
|
245
246
|
the specified filters.
|
|
246
247
|
"""
|
|
247
248
|
|
|
248
|
-
@abc.abstractmethod
|
|
249
|
-
def get_node_public_key(self, node_id: int) -> bytes:
|
|
250
|
-
"""Get `public_key` for the specified `node_id`.
|
|
251
|
-
|
|
252
|
-
Parameters
|
|
253
|
-
----------
|
|
254
|
-
node_id : int
|
|
255
|
-
The identifier of the node whose public key is to be retrieved.
|
|
256
|
-
|
|
257
|
-
Returns
|
|
258
|
-
-------
|
|
259
|
-
bytes
|
|
260
|
-
The public key associated with the specified `node_id`.
|
|
261
|
-
|
|
262
|
-
Raises
|
|
263
|
-
------
|
|
264
|
-
ValueError
|
|
265
|
-
If the specified `node_id` does not exist in the link state.
|
|
266
|
-
"""
|
|
267
|
-
|
|
268
249
|
@abc.abstractmethod
|
|
269
250
|
def create_run( # pylint: disable=too-many-arguments,too-many-positional-arguments
|
|
270
251
|
self,
|
|
@@ -24,7 +24,7 @@ from flwr.superlink.federation import FederationManager
|
|
|
24
24
|
|
|
25
25
|
from .in_memory_linkstate import InMemoryLinkState
|
|
26
26
|
from .linkstate import LinkState
|
|
27
|
-
from .
|
|
27
|
+
from .sql_linkstate import SqlLinkState
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class LinkStateFactory:
|
|
@@ -56,20 +56,28 @@ class LinkStateFactory:
|
|
|
56
56
|
|
|
57
57
|
def state(self) -> LinkState:
|
|
58
58
|
"""Return a State instance and create it, if necessary."""
|
|
59
|
+
# Return cached state if it exists
|
|
60
|
+
if self.state_instance is not None:
|
|
61
|
+
if self.database == FLWR_IN_MEMORY_DB_NAME:
|
|
62
|
+
log(DEBUG, "Using InMemoryState")
|
|
63
|
+
else:
|
|
64
|
+
log(DEBUG, "Using SqlLinkState")
|
|
65
|
+
return self.state_instance
|
|
66
|
+
|
|
59
67
|
# Get the ObjectStore instance
|
|
60
68
|
object_store = self.objectstore_factory.store()
|
|
61
69
|
|
|
62
70
|
# InMemoryState
|
|
63
71
|
if self.database == FLWR_IN_MEMORY_DB_NAME:
|
|
64
|
-
|
|
65
|
-
self.
|
|
66
|
-
|
|
67
|
-
)
|
|
72
|
+
self.state_instance = InMemoryLinkState(
|
|
73
|
+
self.federation_manager, object_store
|
|
74
|
+
)
|
|
68
75
|
log(DEBUG, "Using InMemoryState")
|
|
69
76
|
return self.state_instance
|
|
70
77
|
|
|
71
|
-
#
|
|
72
|
-
state =
|
|
78
|
+
# SqlLinkState
|
|
79
|
+
state = SqlLinkState(self.database, self.federation_manager, object_store)
|
|
73
80
|
state.initialize()
|
|
74
|
-
|
|
81
|
+
self.state_instance = state
|
|
82
|
+
log(DEBUG, "Using SqlLinkState")
|
|
75
83
|
return state
|