flwr-nightly 1.13.0.dev20241019__py3-none-any.whl → 1.13.0.dev20241022__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/client/app.py +11 -11
- flwr/client/node_state_tests.py +7 -8
- flwr/client/{node_state.py → run_info_store.py} +3 -3
- flwr/common/constant.py +2 -3
- flwr/server/app.py +51 -9
- flwr/server/driver/inmemory_driver.py +2 -2
- flwr/server/{superlink/state → serverapp}/__init__.py +3 -9
- flwr/server/serverapp/app.py +20 -0
- flwr/server/superlink/driver/driver_grpc.py +2 -2
- flwr/server/superlink/driver/driver_servicer.py +9 -7
- flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +4 -2
- flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +4 -2
- flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +2 -2
- flwr/server/superlink/fleet/message_handler/message_handler.py +7 -7
- flwr/server/superlink/fleet/rest_rere/rest_api.py +7 -7
- flwr/server/superlink/fleet/vce/vce_api.py +23 -23
- flwr/server/superlink/linkstate/__init__.py +28 -0
- flwr/server/superlink/{state/in_memory_state.py → linkstate/in_memory_linkstate.py} +8 -8
- flwr/server/superlink/{state/state.py → linkstate/linkstate.py} +10 -10
- flwr/server/superlink/{state/state_factory.py → linkstate/linkstate_factory.py} +9 -9
- flwr/server/superlink/{state/sqlite_state.py → linkstate/sqlite_linkstate.py} +14 -14
- flwr/simulation/app.py +1 -1
- flwr/simulation/ray_transport/ray_client_proxy.py +2 -2
- flwr/simulation/run_simulation.py +3 -3
- flwr/superexec/app.py +9 -2
- flwr/superexec/simulation.py +1 -1
- {flwr_nightly-1.13.0.dev20241019.dist-info → flwr_nightly-1.13.0.dev20241022.dist-info}/METADATA +1 -1
- {flwr_nightly-1.13.0.dev20241019.dist-info → flwr_nightly-1.13.0.dev20241022.dist-info}/RECORD +32 -30
- {flwr_nightly-1.13.0.dev20241019.dist-info → flwr_nightly-1.13.0.dev20241022.dist-info}/entry_points.txt +1 -0
- /flwr/server/superlink/{state → linkstate}/utils.py +0 -0
- {flwr_nightly-1.13.0.dev20241019.dist-info → flwr_nightly-1.13.0.dev20241022.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.13.0.dev20241019.dist-info → flwr_nightly-1.13.0.dev20241022.dist-info}/WHEEL +0 -0
|
@@ -28,7 +28,7 @@ from typing import Callable, Optional
|
|
|
28
28
|
|
|
29
29
|
from flwr.client.client_app import ClientApp, ClientAppException, LoadClientAppError
|
|
30
30
|
from flwr.client.clientapp.utils import get_load_client_app_fn
|
|
31
|
-
from flwr.client.
|
|
31
|
+
from flwr.client.run_info_store import DeprecatedRunInfoStore
|
|
32
32
|
from flwr.common.constant import (
|
|
33
33
|
NUM_PARTITIONS_KEY,
|
|
34
34
|
PARTITION_ID_KEY,
|
|
@@ -40,7 +40,7 @@ from flwr.common.message import Error
|
|
|
40
40
|
from flwr.common.serde import message_from_taskins, message_to_taskres
|
|
41
41
|
from flwr.common.typing import Run
|
|
42
42
|
from flwr.proto.task_pb2 import TaskIns, TaskRes # pylint: disable=E0611
|
|
43
|
-
from flwr.server.superlink.
|
|
43
|
+
from flwr.server.superlink.linkstate import LinkState, LinkStateFactory
|
|
44
44
|
|
|
45
45
|
from .backend import Backend, error_messages_backends, supported_backends
|
|
46
46
|
|
|
@@ -48,7 +48,7 @@ NodeToPartitionMapping = dict[int, int]
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
def _register_nodes(
|
|
51
|
-
num_nodes: int, state_factory:
|
|
51
|
+
num_nodes: int, state_factory: LinkStateFactory
|
|
52
52
|
) -> NodeToPartitionMapping:
|
|
53
53
|
"""Register nodes with the StateFactory and create node-id:partition-id mapping."""
|
|
54
54
|
nodes_mapping: NodeToPartitionMapping = {}
|
|
@@ -60,16 +60,16 @@ def _register_nodes(
|
|
|
60
60
|
return nodes_mapping
|
|
61
61
|
|
|
62
62
|
|
|
63
|
-
def
|
|
63
|
+
def _register_node_info_stores(
|
|
64
64
|
nodes_mapping: NodeToPartitionMapping,
|
|
65
65
|
run: Run,
|
|
66
66
|
app_dir: Optional[str] = None,
|
|
67
|
-
) -> dict[int,
|
|
68
|
-
"""Create
|
|
69
|
-
|
|
67
|
+
) -> dict[int, DeprecatedRunInfoStore]:
|
|
68
|
+
"""Create DeprecatedRunInfoStore objects and register the context for the run."""
|
|
69
|
+
node_info_store: dict[int, DeprecatedRunInfoStore] = {}
|
|
70
70
|
num_partitions = len(set(nodes_mapping.values()))
|
|
71
71
|
for node_id, partition_id in nodes_mapping.items():
|
|
72
|
-
|
|
72
|
+
node_info_store[node_id] = DeprecatedRunInfoStore(
|
|
73
73
|
node_id=node_id,
|
|
74
74
|
node_config={
|
|
75
75
|
PARTITION_ID_KEY: partition_id,
|
|
@@ -78,18 +78,18 @@ def _register_node_states(
|
|
|
78
78
|
)
|
|
79
79
|
|
|
80
80
|
# Pre-register Context objects
|
|
81
|
-
|
|
81
|
+
node_info_store[node_id].register_context(
|
|
82
82
|
run_id=run.run_id, run=run, app_dir=app_dir
|
|
83
83
|
)
|
|
84
84
|
|
|
85
|
-
return
|
|
85
|
+
return node_info_store
|
|
86
86
|
|
|
87
87
|
|
|
88
88
|
# pylint: disable=too-many-arguments,too-many-locals
|
|
89
89
|
def worker(
|
|
90
90
|
taskins_queue: "Queue[TaskIns]",
|
|
91
91
|
taskres_queue: "Queue[TaskRes]",
|
|
92
|
-
|
|
92
|
+
node_info_store: dict[int, DeprecatedRunInfoStore],
|
|
93
93
|
backend: Backend,
|
|
94
94
|
f_stop: threading.Event,
|
|
95
95
|
) -> None:
|
|
@@ -103,7 +103,7 @@ def worker(
|
|
|
103
103
|
node_id = task_ins.task.consumer.node_id
|
|
104
104
|
|
|
105
105
|
# Retrieve context
|
|
106
|
-
context =
|
|
106
|
+
context = node_info_store[node_id].retrieve_context(run_id=task_ins.run_id)
|
|
107
107
|
|
|
108
108
|
# Convert TaskIns to Message
|
|
109
109
|
message = message_from_taskins(task_ins)
|
|
@@ -112,7 +112,7 @@ def worker(
|
|
|
112
112
|
out_mssg, updated_context = backend.process_message(message, context)
|
|
113
113
|
|
|
114
114
|
# Update Context
|
|
115
|
-
|
|
115
|
+
node_info_store[node_id].update_context(
|
|
116
116
|
task_ins.run_id, context=updated_context
|
|
117
117
|
)
|
|
118
118
|
except Empty:
|
|
@@ -145,7 +145,7 @@ def worker(
|
|
|
145
145
|
|
|
146
146
|
|
|
147
147
|
def add_taskins_to_queue(
|
|
148
|
-
state:
|
|
148
|
+
state: LinkState,
|
|
149
149
|
queue: "Queue[TaskIns]",
|
|
150
150
|
nodes_mapping: NodeToPartitionMapping,
|
|
151
151
|
f_stop: threading.Event,
|
|
@@ -160,7 +160,7 @@ def add_taskins_to_queue(
|
|
|
160
160
|
|
|
161
161
|
|
|
162
162
|
def put_taskres_into_state(
|
|
163
|
-
state:
|
|
163
|
+
state: LinkState, queue: "Queue[TaskRes]", f_stop: threading.Event
|
|
164
164
|
) -> None:
|
|
165
165
|
"""Put TaskRes into State from a queue."""
|
|
166
166
|
while not f_stop.is_set():
|
|
@@ -177,8 +177,8 @@ def run_api(
|
|
|
177
177
|
app_fn: Callable[[], ClientApp],
|
|
178
178
|
backend_fn: Callable[[], Backend],
|
|
179
179
|
nodes_mapping: NodeToPartitionMapping,
|
|
180
|
-
state_factory:
|
|
181
|
-
|
|
180
|
+
state_factory: LinkStateFactory,
|
|
181
|
+
node_info_stores: dict[int, DeprecatedRunInfoStore],
|
|
182
182
|
f_stop: threading.Event,
|
|
183
183
|
) -> None:
|
|
184
184
|
"""Run the VCE."""
|
|
@@ -223,7 +223,7 @@ def run_api(
|
|
|
223
223
|
worker,
|
|
224
224
|
taskins_queue,
|
|
225
225
|
taskres_queue,
|
|
226
|
-
|
|
226
|
+
node_info_stores,
|
|
227
227
|
backend,
|
|
228
228
|
f_stop,
|
|
229
229
|
)
|
|
@@ -264,7 +264,7 @@ def start_vce(
|
|
|
264
264
|
client_app: Optional[ClientApp] = None,
|
|
265
265
|
client_app_attr: Optional[str] = None,
|
|
266
266
|
num_supernodes: Optional[int] = None,
|
|
267
|
-
state_factory: Optional[
|
|
267
|
+
state_factory: Optional[LinkStateFactory] = None,
|
|
268
268
|
existing_nodes_mapping: Optional[NodeToPartitionMapping] = None,
|
|
269
269
|
) -> None:
|
|
270
270
|
"""Start Fleet API with the Simulation Engine."""
|
|
@@ -303,7 +303,7 @@ def start_vce(
|
|
|
303
303
|
if not state_factory:
|
|
304
304
|
log(INFO, "A StateFactory was not supplied to the SimulationEngine.")
|
|
305
305
|
# Create an empty in-memory state factory
|
|
306
|
-
state_factory =
|
|
306
|
+
state_factory = LinkStateFactory(":flwr-in-memory-state:")
|
|
307
307
|
log(INFO, "Created new %s.", state_factory.__class__.__name__)
|
|
308
308
|
|
|
309
309
|
if num_supernodes:
|
|
@@ -312,8 +312,8 @@ def start_vce(
|
|
|
312
312
|
num_nodes=num_supernodes, state_factory=state_factory
|
|
313
313
|
)
|
|
314
314
|
|
|
315
|
-
# Construct mapping of
|
|
316
|
-
|
|
315
|
+
# Construct mapping of DeprecatedRunInfoStore
|
|
316
|
+
node_info_stores = _register_node_info_stores(
|
|
317
317
|
nodes_mapping=nodes_mapping, run=run, app_dir=app_dir if is_app else None
|
|
318
318
|
)
|
|
319
319
|
|
|
@@ -376,7 +376,7 @@ def start_vce(
|
|
|
376
376
|
backend_fn,
|
|
377
377
|
nodes_mapping,
|
|
378
378
|
state_factory,
|
|
379
|
-
|
|
379
|
+
node_info_stores,
|
|
380
380
|
f_stop,
|
|
381
381
|
)
|
|
382
382
|
except LoadClientAppError as loadapp_ex:
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Copyright 2024 Flower Labs GmbH. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
"""Flower LinkState."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
from .in_memory_linkstate import InMemoryLinkState as InMemoryLinkState
|
|
19
|
+
from .linkstate import LinkState as LinkState
|
|
20
|
+
from .linkstate_factory import LinkStateFactory as LinkStateFactory
|
|
21
|
+
from .sqlite_linkstate import SqliteLinkState as SqliteLinkState
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"InMemoryLinkState",
|
|
25
|
+
"LinkState",
|
|
26
|
+
"LinkStateFactory",
|
|
27
|
+
"SqliteLinkState",
|
|
28
|
+
]
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
# ==============================================================================
|
|
15
|
-
"""In-memory
|
|
15
|
+
"""In-memory LinkState implementation."""
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
import threading
|
|
@@ -29,14 +29,14 @@ from flwr.common.constant import (
|
|
|
29
29
|
)
|
|
30
30
|
from flwr.common.typing import Run, UserConfig
|
|
31
31
|
from flwr.proto.task_pb2 import TaskIns, TaskRes # pylint: disable=E0611
|
|
32
|
-
from flwr.server.superlink.
|
|
32
|
+
from flwr.server.superlink.linkstate.linkstate import LinkState
|
|
33
33
|
from flwr.server.utils import validate_task_ins_or_res
|
|
34
34
|
|
|
35
35
|
from .utils import generate_rand_int_from_bytes, make_node_unavailable_taskres
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
class
|
|
39
|
-
"""In-memory
|
|
38
|
+
class InMemoryLinkState(LinkState): # pylint: disable=R0902,R0904
|
|
39
|
+
"""In-memory LinkState implementation."""
|
|
40
40
|
|
|
41
41
|
def __init__(self) -> None:
|
|
42
42
|
|
|
@@ -277,7 +277,7 @@ class InMemoryState(State): # pylint: disable=R0902,R0904
|
|
|
277
277
|
def create_node(
|
|
278
278
|
self, ping_interval: float, public_key: Optional[bytes] = None
|
|
279
279
|
) -> int:
|
|
280
|
-
"""Create, store in state, and return `node_id`."""
|
|
280
|
+
"""Create, store in the link state, and return `node_id`."""
|
|
281
281
|
# Sample a random int64 as node_id
|
|
282
282
|
node_id = generate_rand_int_from_bytes(NODE_ID_NUM_BYTES)
|
|
283
283
|
|
|
@@ -365,7 +365,7 @@ class InMemoryState(State): # pylint: disable=R0902,R0904
|
|
|
365
365
|
def store_server_private_public_key(
|
|
366
366
|
self, private_key: bytes, public_key: bytes
|
|
367
367
|
) -> None:
|
|
368
|
-
"""Store `server_private_key` and `server_public_key` in state."""
|
|
368
|
+
"""Store `server_private_key` and `server_public_key` in the link state."""
|
|
369
369
|
with self.lock:
|
|
370
370
|
if self.server_private_key is None and self.server_public_key is None:
|
|
371
371
|
self.server_private_key = private_key
|
|
@@ -382,12 +382,12 @@ class InMemoryState(State): # pylint: disable=R0902,R0904
|
|
|
382
382
|
return self.server_public_key
|
|
383
383
|
|
|
384
384
|
def store_node_public_keys(self, public_keys: set[bytes]) -> None:
|
|
385
|
-
"""Store a set of `node_public_keys` in state."""
|
|
385
|
+
"""Store a set of `node_public_keys` in the link state."""
|
|
386
386
|
with self.lock:
|
|
387
387
|
self.node_public_keys = public_keys
|
|
388
388
|
|
|
389
389
|
def store_node_public_key(self, public_key: bytes) -> None:
|
|
390
|
-
"""Store a `node_public_key` in state."""
|
|
390
|
+
"""Store a `node_public_key` in the link state."""
|
|
391
391
|
with self.lock:
|
|
392
392
|
self.node_public_keys.add(public_key)
|
|
393
393
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
# ==============================================================================
|
|
15
|
-
"""Abstract base class
|
|
15
|
+
"""Abstract base class LinkState."""
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
import abc
|
|
@@ -23,8 +23,8 @@ from flwr.common.typing import Run, UserConfig
|
|
|
23
23
|
from flwr.proto.task_pb2 import TaskIns, TaskRes # pylint: disable=E0611
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
class
|
|
27
|
-
"""Abstract
|
|
26
|
+
class LinkState(abc.ABC): # pylint: disable=R0904
|
|
27
|
+
"""Abstract LinkState."""
|
|
28
28
|
|
|
29
29
|
@abc.abstractmethod
|
|
30
30
|
def store_task_ins(self, task_ins: TaskIns) -> Optional[UUID]:
|
|
@@ -32,8 +32,8 @@ class State(abc.ABC): # pylint: disable=R0904
|
|
|
32
32
|
|
|
33
33
|
Usually, the Driver API calls this to schedule instructions.
|
|
34
34
|
|
|
35
|
-
Stores the value of the `task_ins` in the state and, if successful,
|
|
36
|
-
`task_id` (UUID) of the `task_ins`. If, for any reason,
|
|
35
|
+
Stores the value of the `task_ins` in the link state and, if successful,
|
|
36
|
+
returns the `task_id` (UUID) of the `task_ins`. If, for any reason,
|
|
37
37
|
storing the `task_ins` fails, `None` is returned.
|
|
38
38
|
|
|
39
39
|
Constraints
|
|
@@ -130,11 +130,11 @@ class State(abc.ABC): # pylint: disable=R0904
|
|
|
130
130
|
def create_node(
|
|
131
131
|
self, ping_interval: float, public_key: Optional[bytes] = None
|
|
132
132
|
) -> int:
|
|
133
|
-
"""Create, store in state, and return `node_id`."""
|
|
133
|
+
"""Create, store in the link state, and return `node_id`."""
|
|
134
134
|
|
|
135
135
|
@abc.abstractmethod
|
|
136
136
|
def delete_node(self, node_id: int, public_key: Optional[bytes] = None) -> None:
|
|
137
|
-
"""Remove `node_id` from state."""
|
|
137
|
+
"""Remove `node_id` from the link state."""
|
|
138
138
|
|
|
139
139
|
@abc.abstractmethod
|
|
140
140
|
def get_nodes(self, run_id: int) -> set[int]:
|
|
@@ -182,7 +182,7 @@ class State(abc.ABC): # pylint: disable=R0904
|
|
|
182
182
|
def store_server_private_public_key(
|
|
183
183
|
self, private_key: bytes, public_key: bytes
|
|
184
184
|
) -> None:
|
|
185
|
-
"""Store `server_private_key` and `server_public_key` in state."""
|
|
185
|
+
"""Store `server_private_key` and `server_public_key` in the link state."""
|
|
186
186
|
|
|
187
187
|
@abc.abstractmethod
|
|
188
188
|
def get_server_private_key(self) -> Optional[bytes]:
|
|
@@ -194,11 +194,11 @@ class State(abc.ABC): # pylint: disable=R0904
|
|
|
194
194
|
|
|
195
195
|
@abc.abstractmethod
|
|
196
196
|
def store_node_public_keys(self, public_keys: set[bytes]) -> None:
|
|
197
|
-
"""Store a set of `node_public_keys` in state."""
|
|
197
|
+
"""Store a set of `node_public_keys` in the link state."""
|
|
198
198
|
|
|
199
199
|
@abc.abstractmethod
|
|
200
200
|
def store_node_public_key(self, public_key: bytes) -> None:
|
|
201
|
-
"""Store a `node_public_key` in state."""
|
|
201
|
+
"""Store a `node_public_key` in the link state."""
|
|
202
202
|
|
|
203
203
|
@abc.abstractmethod
|
|
204
204
|
def get_node_public_keys(self) -> set[bytes]:
|
|
@@ -20,13 +20,13 @@ from typing import Optional
|
|
|
20
20
|
|
|
21
21
|
from flwr.common.logger import log
|
|
22
22
|
|
|
23
|
-
from .
|
|
24
|
-
from .
|
|
25
|
-
from .
|
|
23
|
+
from .in_memory_linkstate import InMemoryLinkState
|
|
24
|
+
from .linkstate import LinkState
|
|
25
|
+
from .sqlite_linkstate import SqliteLinkState
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
class
|
|
29
|
-
"""Factory class that creates
|
|
28
|
+
class LinkStateFactory:
|
|
29
|
+
"""Factory class that creates LinkState instances.
|
|
30
30
|
|
|
31
31
|
Parameters
|
|
32
32
|
----------
|
|
@@ -39,19 +39,19 @@ class StateFactory:
|
|
|
39
39
|
|
|
40
40
|
def __init__(self, database: str) -> None:
|
|
41
41
|
self.database = database
|
|
42
|
-
self.state_instance: Optional[
|
|
42
|
+
self.state_instance: Optional[LinkState] = None
|
|
43
43
|
|
|
44
|
-
def state(self) ->
|
|
44
|
+
def state(self) -> LinkState:
|
|
45
45
|
"""Return a State instance and create it, if necessary."""
|
|
46
46
|
# InMemoryState
|
|
47
47
|
if self.database == ":flwr-in-memory-state:":
|
|
48
48
|
if self.state_instance is None:
|
|
49
|
-
self.state_instance =
|
|
49
|
+
self.state_instance = InMemoryLinkState()
|
|
50
50
|
log(DEBUG, "Using InMemoryState")
|
|
51
51
|
return self.state_instance
|
|
52
52
|
|
|
53
53
|
# SqliteState
|
|
54
|
-
state =
|
|
54
|
+
state = SqliteLinkState(self.database)
|
|
55
55
|
state.initialize()
|
|
56
56
|
log(DEBUG, "Using SqliteState")
|
|
57
57
|
return state
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
# ==============================================================================
|
|
15
|
-
"""SQLite based implemenation of
|
|
15
|
+
"""SQLite based implemenation of the link state."""
|
|
16
16
|
|
|
17
17
|
# pylint: disable=too-many-lines
|
|
18
18
|
|
|
@@ -37,7 +37,7 @@ from flwr.proto.recordset_pb2 import RecordSet # pylint: disable=E0611
|
|
|
37
37
|
from flwr.proto.task_pb2 import Task, TaskIns, TaskRes # pylint: disable=E0611
|
|
38
38
|
from flwr.server.utils.validator import validate_task_ins_or_res
|
|
39
39
|
|
|
40
|
-
from .
|
|
40
|
+
from .linkstate import LinkState
|
|
41
41
|
from .utils import (
|
|
42
42
|
convert_sint64_to_uint64,
|
|
43
43
|
convert_sint64_values_in_dict_to_uint64,
|
|
@@ -126,8 +126,8 @@ CREATE TABLE IF NOT EXISTS task_res(
|
|
|
126
126
|
DictOrTuple = Union[tuple[Any, ...], dict[str, Any]]
|
|
127
127
|
|
|
128
128
|
|
|
129
|
-
class
|
|
130
|
-
"""SQLite-based
|
|
129
|
+
class SqliteLinkState(LinkState): # pylint: disable=R0904
|
|
130
|
+
"""SQLite-based LinkState implementation."""
|
|
131
131
|
|
|
132
132
|
def __init__(
|
|
133
133
|
self,
|
|
@@ -183,7 +183,7 @@ class SqliteState(State): # pylint: disable=R0904
|
|
|
183
183
|
) -> list[dict[str, Any]]:
|
|
184
184
|
"""Execute a SQL query."""
|
|
185
185
|
if self.conn is None:
|
|
186
|
-
raise AttributeError("
|
|
186
|
+
raise AttributeError("LinkState is not initialized.")
|
|
187
187
|
|
|
188
188
|
if data is None:
|
|
189
189
|
data = []
|
|
@@ -216,9 +216,9 @@ class SqliteState(State): # pylint: disable=R0904
|
|
|
216
216
|
|
|
217
217
|
Usually, the Driver API calls this to schedule instructions.
|
|
218
218
|
|
|
219
|
-
Stores the value of the task_ins in the state and, if successful,
|
|
220
|
-
task_id (UUID) of the task_ins. If, for any reason, storing
|
|
221
|
-
`None` is returned.
|
|
219
|
+
Stores the value of the task_ins in the link state and, if successful,
|
|
220
|
+
returns the task_id (UUID) of the task_ins. If, for any reason, storing
|
|
221
|
+
the task_ins fails, `None` is returned.
|
|
222
222
|
|
|
223
223
|
Constraints
|
|
224
224
|
-----------
|
|
@@ -645,7 +645,7 @@ class SqliteState(State): # pylint: disable=R0904
|
|
|
645
645
|
"""
|
|
646
646
|
|
|
647
647
|
if self.conn is None:
|
|
648
|
-
raise AttributeError("
|
|
648
|
+
raise AttributeError("LinkState not intitialized")
|
|
649
649
|
|
|
650
650
|
with self.conn:
|
|
651
651
|
self.conn.execute(query_1, data)
|
|
@@ -656,7 +656,7 @@ class SqliteState(State): # pylint: disable=R0904
|
|
|
656
656
|
def create_node(
|
|
657
657
|
self, ping_interval: float, public_key: Optional[bytes] = None
|
|
658
658
|
) -> int:
|
|
659
|
-
"""Create, store in state, and return `node_id`."""
|
|
659
|
+
"""Create, store in the link state, and return `node_id`."""
|
|
660
660
|
# Sample a random uint64 as node_id
|
|
661
661
|
uint64_node_id = generate_rand_int_from_bytes(NODE_ID_NUM_BYTES)
|
|
662
662
|
|
|
@@ -706,7 +706,7 @@ class SqliteState(State): # pylint: disable=R0904
|
|
|
706
706
|
params += (public_key,) # type: ignore
|
|
707
707
|
|
|
708
708
|
if self.conn is None:
|
|
709
|
-
raise AttributeError("
|
|
709
|
+
raise AttributeError("LinkState is not initialized.")
|
|
710
710
|
|
|
711
711
|
try:
|
|
712
712
|
with self.conn:
|
|
@@ -800,7 +800,7 @@ class SqliteState(State): # pylint: disable=R0904
|
|
|
800
800
|
def store_server_private_public_key(
|
|
801
801
|
self, private_key: bytes, public_key: bytes
|
|
802
802
|
) -> None:
|
|
803
|
-
"""Store `server_private_key` and `server_public_key` in state."""
|
|
803
|
+
"""Store `server_private_key` and `server_public_key` in the link state."""
|
|
804
804
|
query = "SELECT COUNT(*) FROM credential"
|
|
805
805
|
count = self.query(query)[0]["COUNT(*)"]
|
|
806
806
|
if count < 1:
|
|
@@ -833,13 +833,13 @@ class SqliteState(State): # pylint: disable=R0904
|
|
|
833
833
|
return public_key
|
|
834
834
|
|
|
835
835
|
def store_node_public_keys(self, public_keys: set[bytes]) -> None:
|
|
836
|
-
"""Store a set of `node_public_keys` in state."""
|
|
836
|
+
"""Store a set of `node_public_keys` in the link state."""
|
|
837
837
|
query = "INSERT INTO public_key (public_key) VALUES (?)"
|
|
838
838
|
data = [(key,) for key in public_keys]
|
|
839
839
|
self.query(query, data)
|
|
840
840
|
|
|
841
841
|
def store_node_public_key(self, public_key: bytes) -> None:
|
|
842
|
-
"""Store a `node_public_key` in state."""
|
|
842
|
+
"""Store a `node_public_key` in the link state."""
|
|
843
843
|
query = "INSERT INTO public_key (public_key) VALUES (:public_key)"
|
|
844
844
|
self.query(query, {"public_key": public_key})
|
|
845
845
|
|
flwr/simulation/app.py
CHANGED
|
@@ -36,7 +36,7 @@ from flwr.server.history import History
|
|
|
36
36
|
from flwr.server.server import Server, init_defaults, run_fl
|
|
37
37
|
from flwr.server.server_config import ServerConfig
|
|
38
38
|
from flwr.server.strategy import Strategy
|
|
39
|
-
from flwr.server.superlink.
|
|
39
|
+
from flwr.server.superlink.linkstate.utils import generate_rand_int_from_bytes
|
|
40
40
|
from flwr.simulation.ray_transport.ray_actor import (
|
|
41
41
|
ClientAppActor,
|
|
42
42
|
VirtualClientEngineActor,
|
|
@@ -22,7 +22,7 @@ from typing import Optional
|
|
|
22
22
|
from flwr import common
|
|
23
23
|
from flwr.client import ClientFnExt
|
|
24
24
|
from flwr.client.client_app import ClientApp
|
|
25
|
-
from flwr.client.
|
|
25
|
+
from flwr.client.run_info_store import DeprecatedRunInfoStore
|
|
26
26
|
from flwr.common import DEFAULT_TTL, Message, Metadata, RecordSet
|
|
27
27
|
from flwr.common.constant import (
|
|
28
28
|
NUM_PARTITIONS_KEY,
|
|
@@ -65,7 +65,7 @@ class RayActorClientProxy(ClientProxy):
|
|
|
65
65
|
|
|
66
66
|
self.app_fn = _load_app
|
|
67
67
|
self.actor_pool = actor_pool
|
|
68
|
-
self.proxy_state =
|
|
68
|
+
self.proxy_state = DeprecatedRunInfoStore(
|
|
69
69
|
node_id=node_id,
|
|
70
70
|
node_config={
|
|
71
71
|
PARTITION_ID_KEY: str(partition_id),
|
|
@@ -44,8 +44,8 @@ from flwr.server.run_serverapp import run as run_server_app
|
|
|
44
44
|
from flwr.server.server_app import ServerApp
|
|
45
45
|
from flwr.server.superlink.fleet import vce
|
|
46
46
|
from flwr.server.superlink.fleet.vce.backend.backend import BackendConfig
|
|
47
|
-
from flwr.server.superlink.
|
|
48
|
-
from flwr.server.superlink.
|
|
47
|
+
from flwr.server.superlink.linkstate import LinkStateFactory
|
|
48
|
+
from flwr.server.superlink.linkstate.utils import generate_rand_int_from_bytes
|
|
49
49
|
from flwr.simulation.ray_transport.utils import (
|
|
50
50
|
enable_tf_gpu_growth as enable_gpu_growth,
|
|
51
51
|
)
|
|
@@ -389,7 +389,7 @@ def _main_loop(
|
|
|
389
389
|
) -> None:
|
|
390
390
|
"""Start ServerApp on a separate thread, then launch Simulation Engine."""
|
|
391
391
|
# Initialize StateFactory
|
|
392
|
-
state_factory =
|
|
392
|
+
state_factory = LinkStateFactory(":flwr-in-memory-state:")
|
|
393
393
|
|
|
394
394
|
f_stop = threading.Event()
|
|
395
395
|
# A Threading event to indicate if an exception was raised in the ServerApp thread
|
flwr/superexec/app.py
CHANGED
|
@@ -27,6 +27,7 @@ from flwr.common.address import parse_address
|
|
|
27
27
|
from flwr.common.config import parse_config_args
|
|
28
28
|
from flwr.common.constant import EXEC_API_DEFAULT_ADDRESS
|
|
29
29
|
from flwr.common.exit_handlers import register_exit_handlers
|
|
30
|
+
from flwr.common.logger import warn_deprecated_feature
|
|
30
31
|
from flwr.common.object_ref import load_app, validate
|
|
31
32
|
|
|
32
33
|
from .exec_grpc import run_superexec_api_grpc
|
|
@@ -37,6 +38,12 @@ def run_superexec() -> None:
|
|
|
37
38
|
"""Run Flower SuperExec."""
|
|
38
39
|
log(INFO, "Starting Flower SuperExec")
|
|
39
40
|
|
|
41
|
+
warn_deprecated_feature(
|
|
42
|
+
"Manually launching the SuperExec is deprecated. Since `flwr 1.13.0` "
|
|
43
|
+
"the executor service runs in the SuperLink. Launching it manually is not "
|
|
44
|
+
"recommended."
|
|
45
|
+
)
|
|
46
|
+
|
|
40
47
|
event(EventType.RUN_SUPEREXEC_ENTER)
|
|
41
48
|
|
|
42
49
|
args = _parse_args_run_superexec().parse_args()
|
|
@@ -54,7 +61,7 @@ def run_superexec() -> None:
|
|
|
54
61
|
# Start SuperExec API
|
|
55
62
|
superexec_server: grpc.Server = run_superexec_api_grpc(
|
|
56
63
|
address=address,
|
|
57
|
-
executor=
|
|
64
|
+
executor=load_executor(args),
|
|
58
65
|
certificates=certificates,
|
|
59
66
|
config=parse_config_args(
|
|
60
67
|
[args.executor_config] if args.executor_config else args.executor_config
|
|
@@ -163,7 +170,7 @@ def _try_obtain_certificates(
|
|
|
163
170
|
)
|
|
164
171
|
|
|
165
172
|
|
|
166
|
-
def
|
|
173
|
+
def load_executor(
|
|
167
174
|
args: argparse.Namespace,
|
|
168
175
|
) -> Executor:
|
|
169
176
|
"""Get the executor plugin."""
|
flwr/superexec/simulation.py
CHANGED
|
@@ -29,7 +29,7 @@ from flwr.common.config import unflatten_dict
|
|
|
29
29
|
from flwr.common.constant import RUN_ID_NUM_BYTES
|
|
30
30
|
from flwr.common.logger import log
|
|
31
31
|
from flwr.common.typing import UserConfig
|
|
32
|
-
from flwr.server.superlink.
|
|
32
|
+
from flwr.server.superlink.linkstate.utils import generate_rand_int_from_bytes
|
|
33
33
|
|
|
34
34
|
from .executor import Executor, RunTracker
|
|
35
35
|
|