flwr-nightly 1.20.0.dev20250728__py3-none-any.whl → 1.21.0.dev20250729__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/cli/new/templates/app/pyproject.baseline.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.jax.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +1 -1
- flwr/common/inflatable_utils.py +49 -6
- flwr/server/serverapp/app.py +6 -0
- flwr/simulation/app.py +8 -0
- {flwr_nightly-1.20.0.dev20250728.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/METADATA +1 -1
- {flwr_nightly-1.20.0.dev20250728.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/RECORD +16 -16
- {flwr_nightly-1.20.0.dev20250728.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.20.0.dev20250728.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/entry_points.txt +0 -0
flwr/common/inflatable_utils.py
CHANGED
@@ -34,6 +34,7 @@ from .constant import (
|
|
34
34
|
PULL_MAX_TIME,
|
35
35
|
PULL_MAX_TRIES_PER_OBJECT,
|
36
36
|
)
|
37
|
+
from .exit_handlers import add_exit_handler
|
37
38
|
from .inflatable import (
|
38
39
|
InflatableObject,
|
39
40
|
UnexpectedObjectContentError,
|
@@ -61,6 +62,34 @@ inflatable_class_registry: dict[str, type[InflatableObject]] = {
|
|
61
62
|
T = TypeVar("T", bound=InflatableObject)
|
62
63
|
|
63
64
|
|
65
|
+
# Allow thread pool executors to be shut down gracefully
|
66
|
+
_thread_pool_executors: set[concurrent.futures.ThreadPoolExecutor] = set()
|
67
|
+
_lock = threading.Lock()
|
68
|
+
|
69
|
+
|
70
|
+
def _shutdown_thread_pool_executors() -> None:
|
71
|
+
"""Shutdown all thread pool executors gracefully."""
|
72
|
+
with _lock:
|
73
|
+
for executor in _thread_pool_executors:
|
74
|
+
executor.shutdown(wait=False, cancel_futures=True)
|
75
|
+
_thread_pool_executors.clear()
|
76
|
+
|
77
|
+
|
78
|
+
def _track_executor(executor: concurrent.futures.ThreadPoolExecutor) -> None:
|
79
|
+
"""Track a thread pool executor for graceful shutdown."""
|
80
|
+
with _lock:
|
81
|
+
_thread_pool_executors.add(executor)
|
82
|
+
|
83
|
+
|
84
|
+
def _untrack_executor(executor: concurrent.futures.ThreadPoolExecutor) -> None:
|
85
|
+
"""Untrack a thread pool executor."""
|
86
|
+
with _lock:
|
87
|
+
_thread_pool_executors.discard(executor)
|
88
|
+
|
89
|
+
|
90
|
+
add_exit_handler(_shutdown_thread_pool_executors)
|
91
|
+
|
92
|
+
|
64
93
|
class ObjectUnavailableError(Exception):
|
65
94
|
"""Exception raised when an object has been pre-registered but is not yet
|
66
95
|
available."""
|
@@ -165,7 +194,16 @@ def push_object_contents_from_iterable(
|
|
165
194
|
# Push all object contents concurrently
|
166
195
|
num_workers = get_num_workers(max_concurrent_pushes)
|
167
196
|
with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor:
|
168
|
-
|
197
|
+
# Ensure that the thread pool executors are tracked for graceful shutdown
|
198
|
+
_track_executor(executor)
|
199
|
+
|
200
|
+
# Submit push tasks for each object content
|
201
|
+
executor.map(push, object_contents) # Non-blocking map
|
202
|
+
|
203
|
+
# The context manager will block until all submitted tasks have completed
|
204
|
+
|
205
|
+
# Remove the executor from the list of tracked executors
|
206
|
+
_untrack_executor(executor)
|
169
207
|
|
170
208
|
|
171
209
|
def pull_objects( # pylint: disable=too-many-arguments,too-many-locals
|
@@ -262,13 +300,18 @@ def pull_objects( # pylint: disable=too-many-arguments,too-many-locals
|
|
262
300
|
# Submit all pull tasks concurrently
|
263
301
|
num_workers = get_num_workers(max_concurrent_pulls)
|
264
302
|
with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor:
|
265
|
-
|
266
|
-
|
267
|
-
|
303
|
+
# Ensure that the thread pool executors are tracked for graceful shutdown
|
304
|
+
_track_executor(executor)
|
305
|
+
|
306
|
+
# Submit pull tasks for each object ID
|
307
|
+
executor.map(pull_with_retries, object_ids) # Non-blocking map
|
308
|
+
|
309
|
+
# The context manager will block until all submitted tasks have completed
|
268
310
|
|
269
|
-
|
270
|
-
|
311
|
+
# Remove the executor from the list of tracked executors
|
312
|
+
_untrack_executor(executor)
|
271
313
|
|
314
|
+
# If an error occurred during pulling, raise it
|
272
315
|
if err_to_raise is not None:
|
273
316
|
raise err_to_raise
|
274
317
|
|
flwr/server/serverapp/app.py
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
import argparse
|
19
|
+
import gc
|
19
20
|
from logging import DEBUG, ERROR, INFO
|
20
21
|
from pathlib import Path
|
21
22
|
from queue import Queue
|
@@ -115,6 +116,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
|
|
115
116
|
run_status = None
|
116
117
|
heartbeat_sender = None
|
117
118
|
grid = None
|
119
|
+
context = None
|
118
120
|
while True:
|
119
121
|
|
120
122
|
try:
|
@@ -248,6 +250,10 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915
|
|
248
250
|
if grid:
|
249
251
|
grid.close()
|
250
252
|
|
253
|
+
# Clean up the Context
|
254
|
+
context = None
|
255
|
+
gc.collect()
|
256
|
+
|
251
257
|
event(
|
252
258
|
EventType.FLWR_SERVERAPP_RUN_LEAVE,
|
253
259
|
event_details={"run-id-hash": hash_run_id, "success": success},
|
flwr/simulation/app.py
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
import argparse
|
19
|
+
import gc
|
19
20
|
from logging import DEBUG, ERROR, INFO
|
20
21
|
from queue import Queue
|
21
22
|
from time import sleep
|
@@ -271,6 +272,13 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09
|
|
271
272
|
)
|
272
273
|
)
|
273
274
|
|
275
|
+
# Clean up the Context if it exists
|
276
|
+
try:
|
277
|
+
del updated_context
|
278
|
+
except NameError:
|
279
|
+
pass
|
280
|
+
gc.collect()
|
281
|
+
|
274
282
|
# Stop the loop if `flwr-simulation` is expected to process a single run
|
275
283
|
if run_once:
|
276
284
|
break
|
{flwr_nightly-1.20.0.dev20250728.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: flwr-nightly
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.21.0.dev20250729
|
4
4
|
Summary: Flower: A Friendly Federated AI Framework
|
5
5
|
License: Apache-2.0
|
6
6
|
Keywords: Artificial Intelligence,Federated AI,Federated Analytics,Federated Evaluation,Federated Learning,Flower,Machine Learning
|
{flwr_nightly-1.20.0.dev20250728.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/RECORD
RENAMED
@@ -61,15 +61,15 @@ flwr/cli/new/templates/app/code/task.pytorch.py.tpl,sha256=XlJqA4Ix_PloO_zJLhjiN
|
|
61
61
|
flwr/cli/new/templates/app/code/task.sklearn.py.tpl,sha256=vHdhtMp0FHxbYafXyhDT9aKmmmA0Jvpx5Oum1Yu9lWY,1850
|
62
62
|
flwr/cli/new/templates/app/code/task.tensorflow.py.tpl,sha256=SKXAZdgBnPpbAbJ90Rb7oQ5ilnopBx_j_JNFoUDeEAI,1732
|
63
63
|
flwr/cli/new/templates/app/code/utils.baseline.py.tpl,sha256=YkHAgppUeD2BnBoGfVB6dEvBfjuIPGsU1gw4CiUi3qA,40
|
64
|
-
flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=
|
65
|
-
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=
|
66
|
-
flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256
|
67
|
-
flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=
|
68
|
-
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=
|
69
|
-
flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=
|
70
|
-
flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=
|
71
|
-
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=
|
72
|
-
flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=
|
64
|
+
flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=o7WJPF7lH_azNTiUrvTtLfXKyAY3_xTzwvUpkp3suUI,3180
|
65
|
+
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=zDNuDkvgVI7SNK7RLSlaFs2LhSW1-THDKNBJVw1_y78,2497
|
66
|
+
flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=dsjlA0aS-U7xzB7YCYMOGVb7a0XJTB5bsemFzwUPkPg,2019
|
67
|
+
flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=BHGb2N57Xm2scO1mqDSNgK_aiI68mRh6u4Y9TLL5bZE,1471
|
68
|
+
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=O6eN6Zqx2ieh-WbaiMYmxfhCrLKJjwymn_nhUDEOldM,1542
|
69
|
+
flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=oMTI8qXSgQsGlZextUpkWFvNOMlnWbzn2EocPSwDrtw,1409
|
70
|
+
flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=bu65oSrM85fP_H0-RlMS2i8XgL_8O5TfSHLW87lb30s,1508
|
71
|
+
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=mAEPeBfGyrINgRuP6-nX_KJNTQjC4E5N1Nrcddxiffs,1484
|
72
|
+
flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=mK8wOWqoQOVxZG6-OVwA2ChmKxexC7TfQV0ztPE4BWY,1508
|
73
73
|
flwr/cli/run/__init__.py,sha256=RPyB7KbYTFl6YRiilCch6oezxrLQrl1kijV7BMGkLbA,790
|
74
74
|
flwr/cli/run/run.py,sha256=psmr215gkV0e0QtX9NFp7KUwKSA_ZwekdJmoL1zFyfw,8478
|
75
75
|
flwr/cli/stop.py,sha256=l8DcRkA---CESVJgc7iTHLWIBAPGxWIfoem8qSU3lZQ,4972
|
@@ -124,7 +124,7 @@ flwr/common/grpc.py,sha256=y70hUFvXkIf3l03xOhlb7qhS6W1UJZRSZqCdB0ir0v8,10381
|
|
124
124
|
flwr/common/heartbeat.py,sha256=SyEpNDnmJ0lni0cWO67rcoJVKasCLmkNHm3dKLeNrLU,5749
|
125
125
|
flwr/common/inflatable.py,sha256=GDL9oBKs16_yyVdlH6kBf493O5xll_h9V7XB5Mpx1Hc,9524
|
126
126
|
flwr/common/inflatable_protobuf_utils.py,sha256=JtRqp-fV47goDM2y8JRQ7AmwwjeGaWexwoMWLcxX5gE,5056
|
127
|
-
flwr/common/inflatable_utils.py,sha256=
|
127
|
+
flwr/common/inflatable_utils.py,sha256=OcNW8_CfHNuJhHekwRtnrDJZ4vbhujw2w7SG7Y0TuSI,18955
|
128
128
|
flwr/common/logger.py,sha256=JbRf6E2vQxXzpDBq1T8IDUJo_usu3gjWEBPQ6uKcmdg,13049
|
129
129
|
flwr/common/message.py,sha256=xAL7iZN5-n-xPQpgoSFvxNrzs8fmiiPfoU0DjNQEhRw,19953
|
130
130
|
flwr/common/object_ref.py,sha256=p3SfTeqo3Aj16SkB-vsnNn01zswOPdGNBitcbRnqmUk,9134
|
@@ -250,7 +250,7 @@ flwr/server/server.py,sha256=39m4FSN2T-uVA-no9nstN0eWW0co-IUUAIMmpd3V7Jc,17893
|
|
250
250
|
flwr/server/server_app.py,sha256=8uagoZX-3CY3tazPqkIV9jY-cN0YrRRrDmVe23o0AV0,9515
|
251
251
|
flwr/server/server_config.py,sha256=e_6ddh0riwOJsdNn2BFev344uMWfDk9n7dyjNpPgm1w,1349
|
252
252
|
flwr/server/serverapp/__init__.py,sha256=xcC0T_MQSMS9cicUzUUpMNCOsF2d8Oh_8jvnoBLuZvo,800
|
253
|
-
flwr/server/serverapp/app.py,sha256=
|
253
|
+
flwr/server/serverapp/app.py,sha256=k0wAdZiMAEz7WsUigxv038I5Eel3vXwuSqGGj2HtX3c,9524
|
254
254
|
flwr/server/serverapp_components.py,sha256=dfSqmrsVy3arKXpl3ZIBQWdV8rehfIms8aJooyzdmEM,2118
|
255
255
|
flwr/server/strategy/__init__.py,sha256=HhsSWMWaC7oCb2g7Kqn1MBKdrfvgi8VxACy9ZL706Q0,2836
|
256
256
|
flwr/server/strategy/aggregate.py,sha256=smlKKy-uFUuuFR12vlclucnwSQWRz78R79-Km4RWqbw,13978
|
@@ -322,7 +322,7 @@ flwr/server/workflow/secure_aggregation/secagg_workflow.py,sha256=b_pKk7gmbahwyj
|
|
322
322
|
flwr/server/workflow/secure_aggregation/secaggplus_workflow.py,sha256=DkayCsnlAya6Y2PZsueLgoUCMRtV-GbnW08RfWx_SXM,29460
|
323
323
|
flwr/serverapp/__init__.py,sha256=HPvC_ZvMS7GCM7ALVrG_Wwm4bSDr4DZETeC561v3T9w,719
|
324
324
|
flwr/simulation/__init__.py,sha256=Gg6OsP1Z-ixc3-xxzvl7j7rz2Fijy9rzyEPpxgAQCeM,1556
|
325
|
-
flwr/simulation/app.py,sha256=
|
325
|
+
flwr/simulation/app.py,sha256=hP7vP29qZOA_3dipzUdmkRXP25eS8RlF1MT-S09t3oc,10625
|
326
326
|
flwr/simulation/legacy_app.py,sha256=nMISQqW0otJL1-2Kfd94O6BLlGS2IEmEPKTM2WGKrIs,15861
|
327
327
|
flwr/simulation/ray_transport/__init__.py,sha256=ogd-0AMv2U-wBZ1r3sHWaDIOIrVqr88Xi6C8o4Dviy0,734
|
328
328
|
flwr/simulation/ray_transport/ray_actor.py,sha256=JN3xTqFIr5Z750k92CcA_uavzOHhSWDwE2WCaecvpks,19147
|
@@ -374,7 +374,7 @@ flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca
|
|
374
374
|
flwr/supernode/servicer/clientappio/__init__.py,sha256=7Oy62Y_oijqF7Dxi6tpcUQyOpLc_QpIRZ83NvwmB0Yg,813
|
375
375
|
flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=ClPoKco7Tjj_cxRPhZlQSrOvcGa8sJwGs26LUNZnI3Y,10608
|
376
376
|
flwr/supernode/start_client_internal.py,sha256=VC7rV4QaX5Vk4Lw0DDodhwsKvGiHbr0mqrV0H77h1UI,21999
|
377
|
-
flwr_nightly-1.
|
378
|
-
flwr_nightly-1.
|
379
|
-
flwr_nightly-1.
|
380
|
-
flwr_nightly-1.
|
377
|
+
flwr_nightly-1.21.0.dev20250729.dist-info/METADATA,sha256=GHFlQXdDz-wfpA4HvkHCNFyBN-mRXY1F85QgYuKUE_c,15966
|
378
|
+
flwr_nightly-1.21.0.dev20250729.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
379
|
+
flwr_nightly-1.21.0.dev20250729.dist-info/entry_points.txt,sha256=jNpDXGBGgs21RqUxelF_jwGaxtqFwm-MQyfz-ZqSjrA,367
|
380
|
+
flwr_nightly-1.21.0.dev20250729.dist-info/RECORD,,
|
{flwr_nightly-1.20.0.dev20250728.dist-info → flwr_nightly-1.21.0.dev20250729.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|