flwr-nightly 1.16.0.dev20250304__py3-none-any.whl → 1.16.0.dev20250305__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/server/compat/app.py +4 -1
- flwr/server/compat/app_utils.py +10 -2
- flwr/server/superlink/linkstate/in_memory_linkstate.py +236 -2
- flwr/server/superlink/linkstate/linkstate.py +101 -1
- flwr/server/superlink/linkstate/sqlite_linkstate.py +445 -2
- flwr/server/superlink/linkstate/utils.py +153 -4
- flwr/server/workflow/default_workflows.py +4 -1
- {flwr_nightly-1.16.0.dev20250304.dist-info → flwr_nightly-1.16.0.dev20250305.dist-info}/METADATA +1 -1
- {flwr_nightly-1.16.0.dev20250304.dist-info → flwr_nightly-1.16.0.dev20250305.dist-info}/RECORD +12 -12
- {flwr_nightly-1.16.0.dev20250304.dist-info → flwr_nightly-1.16.0.dev20250305.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.16.0.dev20250304.dist-info → flwr_nightly-1.16.0.dev20250305.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.16.0.dev20250304.dist-info → flwr_nightly-1.16.0.dev20250305.dist-info}/entry_points.txt +0 -0
@@ -20,12 +20,21 @@ from os import urandom
|
|
20
20
|
from typing import Optional, Union
|
21
21
|
from uuid import UUID, uuid4
|
22
22
|
|
23
|
-
from flwr.common import
|
23
|
+
from flwr.common import (
|
24
|
+
ConfigsRecord,
|
25
|
+
Context,
|
26
|
+
Error,
|
27
|
+
Message,
|
28
|
+
Metadata,
|
29
|
+
log,
|
30
|
+
now,
|
31
|
+
serde,
|
32
|
+
)
|
24
33
|
from flwr.common.constant import SUPERLINK_NODE_ID, ErrorCode, Status, SubStatus
|
25
34
|
from flwr.common.typing import RunStatus
|
26
35
|
|
27
36
|
# pylint: disable=E0611
|
28
|
-
from flwr.proto.error_pb2 import Error
|
37
|
+
from flwr.proto.error_pb2 import Error as ProtoError
|
29
38
|
from flwr.proto.message_pb2 import Context as ProtoContext
|
30
39
|
from flwr.proto.node_pb2 import Node
|
31
40
|
from flwr.proto.recordset_pb2 import ConfigsRecord as ProtoConfigsRecord
|
@@ -262,7 +271,7 @@ def create_taskres_for_unavailable_taskins(taskins_id: Union[str, UUID]) -> Task
|
|
262
271
|
ttl=0,
|
263
272
|
ancestry=[str(taskins_id)],
|
264
273
|
task_type="", # Unknown message type
|
265
|
-
error=
|
274
|
+
error=ProtoError(
|
266
275
|
code=ErrorCode.MESSAGE_UNAVAILABLE,
|
267
276
|
reason=MESSAGE_UNAVAILABLE_ERROR_REASON,
|
268
277
|
),
|
@@ -301,7 +310,7 @@ def create_taskres_for_unavailable_taskres(ref_taskins: TaskIns) -> TaskRes:
|
|
301
310
|
ttl=ttl,
|
302
311
|
ancestry=[ref_taskins.task_id],
|
303
312
|
task_type=ref_taskins.task.task_type,
|
304
|
-
error=
|
313
|
+
error=ProtoError(
|
305
314
|
code=ErrorCode.REPLY_MESSAGE_UNAVAILABLE,
|
306
315
|
reason=REPLY_MESSAGE_UNAVAILABLE_ERROR_REASON,
|
307
316
|
),
|
@@ -309,11 +318,64 @@ def create_taskres_for_unavailable_taskres(ref_taskins: TaskIns) -> TaskRes:
|
|
309
318
|
)
|
310
319
|
|
311
320
|
|
321
|
+
def create_message_error_unavailable_res_message(ins_metadata: Metadata) -> Message:
|
322
|
+
"""Generate an error Message that the SuperLink returns carrying the specified
|
323
|
+
error."""
|
324
|
+
current_time = now().timestamp()
|
325
|
+
ttl = max(ins_metadata.ttl - (current_time - ins_metadata.created_at), 0)
|
326
|
+
metadata = Metadata(
|
327
|
+
run_id=ins_metadata.run_id,
|
328
|
+
message_id=str(uuid4()),
|
329
|
+
src_node_id=SUPERLINK_NODE_ID,
|
330
|
+
dst_node_id=SUPERLINK_NODE_ID,
|
331
|
+
reply_to_message=ins_metadata.message_id,
|
332
|
+
group_id=ins_metadata.group_id,
|
333
|
+
message_type=ins_metadata.message_type,
|
334
|
+
ttl=ttl,
|
335
|
+
)
|
336
|
+
|
337
|
+
return Message(
|
338
|
+
metadata=metadata,
|
339
|
+
error=Error(
|
340
|
+
code=ErrorCode.REPLY_MESSAGE_UNAVAILABLE,
|
341
|
+
reason=REPLY_MESSAGE_UNAVAILABLE_ERROR_REASON,
|
342
|
+
),
|
343
|
+
)
|
344
|
+
|
345
|
+
|
346
|
+
def create_message_error_unavailable_ins_message(reply_to_message: UUID) -> Message:
|
347
|
+
"""Error to indicate that the enquired Message had expired before reply arrived or
|
348
|
+
that it isn't found."""
|
349
|
+
metadata = Metadata(
|
350
|
+
run_id=0, # Unknown
|
351
|
+
message_id=str(uuid4()),
|
352
|
+
src_node_id=SUPERLINK_NODE_ID,
|
353
|
+
dst_node_id=SUPERLINK_NODE_ID,
|
354
|
+
reply_to_message=str(reply_to_message),
|
355
|
+
group_id="", # Unknown
|
356
|
+
message_type="", # Unknown
|
357
|
+
ttl=0,
|
358
|
+
)
|
359
|
+
|
360
|
+
return Message(
|
361
|
+
metadata=metadata,
|
362
|
+
error=Error(
|
363
|
+
code=ErrorCode.MESSAGE_UNAVAILABLE,
|
364
|
+
reason=MESSAGE_UNAVAILABLE_ERROR_REASON,
|
365
|
+
),
|
366
|
+
)
|
367
|
+
|
368
|
+
|
312
369
|
def has_expired(task_ins_or_res: Union[TaskIns, TaskRes], current_time: float) -> bool:
|
313
370
|
"""Check if the TaskIns/TaskRes has expired."""
|
314
371
|
return task_ins_or_res.task.ttl + task_ins_or_res.task.created_at < current_time
|
315
372
|
|
316
373
|
|
374
|
+
def message_ttl_has_expired(message_metadata: Metadata, current_time: float) -> bool:
|
375
|
+
"""Check if the Message has expired."""
|
376
|
+
return message_metadata.ttl + message_metadata.created_at < current_time
|
377
|
+
|
378
|
+
|
317
379
|
def verify_taskins_ids(
|
318
380
|
inquired_taskins_ids: set[UUID],
|
319
381
|
found_taskins_dict: dict[UUID, TaskIns],
|
@@ -353,6 +415,48 @@ def verify_taskins_ids(
|
|
353
415
|
return ret_dict
|
354
416
|
|
355
417
|
|
418
|
+
def verify_message_ids(
|
419
|
+
inquired_message_ids: set[UUID],
|
420
|
+
found_message_ins_dict: dict[UUID, Message],
|
421
|
+
current_time: Optional[float] = None,
|
422
|
+
update_set: bool = True,
|
423
|
+
) -> dict[UUID, Message]:
|
424
|
+
"""Verify found Messages and generate error Messages for invalid ones.
|
425
|
+
|
426
|
+
Parameters
|
427
|
+
----------
|
428
|
+
inquired_message_ids : set[UUID]
|
429
|
+
Set of Message IDs for which to generate error Message if invalid.
|
430
|
+
found_message_ins_dict : dict[UUID, Message]
|
431
|
+
Dictionary containing all found Message indexed by their IDs.
|
432
|
+
current_time : Optional[float] (default: None)
|
433
|
+
The current time to check for expiration. If set to `None`, the current time
|
434
|
+
will automatically be set to the current timestamp using `now().timestamp()`.
|
435
|
+
update_set : bool (default: True)
|
436
|
+
If True, the `inquired_message_ids` will be updated to remove invalid ones,
|
437
|
+
by default True.
|
438
|
+
|
439
|
+
Returns
|
440
|
+
-------
|
441
|
+
dict[UUID, Message]
|
442
|
+
A dictionary of error Message indexed by the corresponding ID of the message
|
443
|
+
they are a reply of.
|
444
|
+
"""
|
445
|
+
ret_dict = {}
|
446
|
+
current = current_time if current_time else now().timestamp()
|
447
|
+
for message_id in list(inquired_message_ids):
|
448
|
+
# Generate error message if the inquired message doesn't exist or has expired
|
449
|
+
message_ins = found_message_ins_dict.get(message_id)
|
450
|
+
if message_ins is None or message_ttl_has_expired(
|
451
|
+
message_ins.metadata, current
|
452
|
+
):
|
453
|
+
if update_set:
|
454
|
+
inquired_message_ids.remove(message_id)
|
455
|
+
message_res = create_message_error_unavailable_ins_message(message_id)
|
456
|
+
ret_dict[message_id] = message_res
|
457
|
+
return ret_dict
|
458
|
+
|
459
|
+
|
356
460
|
def verify_found_taskres(
|
357
461
|
inquired_taskins_ids: set[UUID],
|
358
462
|
found_taskins_dict: dict[UUID, TaskIns],
|
@@ -397,3 +501,48 @@ def verify_found_taskres(
|
|
397
501
|
taskres.task.delivered_at = now().isoformat()
|
398
502
|
ret_dict[taskins_id] = taskres
|
399
503
|
return ret_dict
|
504
|
+
|
505
|
+
|
506
|
+
def verify_found_message_replies(
|
507
|
+
inquired_message_ids: set[UUID],
|
508
|
+
found_message_ins_dict: dict[UUID, Message],
|
509
|
+
found_message_res_list: list[Message],
|
510
|
+
current_time: Optional[float] = None,
|
511
|
+
update_set: bool = True,
|
512
|
+
) -> dict[UUID, Message]:
|
513
|
+
"""Verify found Message replies and generate error Message for invalid ones.
|
514
|
+
|
515
|
+
Parameters
|
516
|
+
----------
|
517
|
+
inquired_message_ids : set[UUID]
|
518
|
+
Set of Message IDs for which to generate error Message if invalid.
|
519
|
+
found_message_ins_dict : dict[UUID, Message]
|
520
|
+
Dictionary containing all found instruction Messages indexed by their IDs.
|
521
|
+
found_message_res_list : dict[Message, Message]
|
522
|
+
List of found Message to be verified.
|
523
|
+
current_time : Optional[float] (default: None)
|
524
|
+
The current time to check for expiration. If set to `None`, the current time
|
525
|
+
will automatically be set to the current timestamp using `now().timestamp()`.
|
526
|
+
update_set : bool (default: True)
|
527
|
+
If True, the `inquired_message_ids` will be updated to remove ones
|
528
|
+
that have a reply Message, by default True.
|
529
|
+
|
530
|
+
Returns
|
531
|
+
-------
|
532
|
+
dict[UUID, Message]
|
533
|
+
A dictionary of Message indexed by the corresponding Message ID.
|
534
|
+
"""
|
535
|
+
ret_dict: dict[UUID, Message] = {}
|
536
|
+
current = current_time if current_time else now().timestamp()
|
537
|
+
for message_res in found_message_res_list:
|
538
|
+
message_ins_id = UUID(message_res.metadata.reply_to_message)
|
539
|
+
if update_set:
|
540
|
+
inquired_message_ids.remove(message_ins_id)
|
541
|
+
# Check if the reply Message has expired
|
542
|
+
if message_ttl_has_expired(message_res.metadata, current):
|
543
|
+
# No need to insert the error Message
|
544
|
+
message_res = create_message_error_unavailable_res_message(
|
545
|
+
found_message_ins_dict[message_ins_id].metadata
|
546
|
+
)
|
547
|
+
ret_dict[message_ins_id] = message_res
|
548
|
+
return ret_dict
|
@@ -64,10 +64,13 @@ class DefaultWorkflow:
|
|
64
64
|
)
|
65
65
|
|
66
66
|
# Start the thread updating nodes
|
67
|
-
thread, f_stop = start_update_client_manager_thread(
|
67
|
+
thread, f_stop, c_done = start_update_client_manager_thread(
|
68
68
|
driver, context.client_manager
|
69
69
|
)
|
70
70
|
|
71
|
+
# Wait until the node registration done
|
72
|
+
c_done.wait()
|
73
|
+
|
71
74
|
# Initialize parameters
|
72
75
|
log(INFO, "[INIT]")
|
73
76
|
default_init_params_workflow(driver, context)
|
{flwr_nightly-1.16.0.dev20250304.dist-info → flwr_nightly-1.16.0.dev20250305.dist-info}/RECORD
RENAMED
@@ -223,8 +223,8 @@ flwr/server/app.py,sha256=a_3hM-RktaPp3QTKDlBuHATB9oS2deGShZGEtmhlnX0,31005
|
|
223
223
|
flwr/server/client_manager.py,sha256=7Ese0tgrH-i-ms363feYZJKwB8gWnXSmg_hYF2Bju4U,6227
|
224
224
|
flwr/server/client_proxy.py,sha256=4G-oTwhb45sfWLx2uZdcXD98IZwdTS6F88xe3akCdUg,2399
|
225
225
|
flwr/server/compat/__init__.py,sha256=VxnJtJyOjNFQXMNi9hIuzNlZM5n0Hj1p3aq_Pm2udw4,892
|
226
|
-
flwr/server/compat/app.py,sha256=
|
227
|
-
flwr/server/compat/app_utils.py,sha256=
|
226
|
+
flwr/server/compat/app.py,sha256=Y0xAqXLn20e6XKGb2nHdeUYdCj_Dux-SyFCc-5ivhqk,3369
|
227
|
+
flwr/server/compat/app_utils.py,sha256=568PfvPME8KHjX-L5GB2rYQa_Wy8iUBGs22KJqn8Xk0,3824
|
228
228
|
flwr/server/compat/driver_client_proxy.py,sha256=jMmrfqSm4-qW0jOCTpHhN9Kw0ohfMwsyKU9buBzrfG0,4958
|
229
229
|
flwr/server/compat/legacy_context.py,sha256=wBzBcfV6YO6IQGriM_FdJ5XZfiBBEEJdS_OdAiF47dY,1804
|
230
230
|
flwr/server/criterion.py,sha256=ypbAexbztzGUxNen9RCHF91QeqiEQix4t4Ih3E-42MM,1061
|
@@ -293,11 +293,11 @@ flwr/server/superlink/fleet/vce/backend/backend.py,sha256=LBAQxnbfPAphVOVIvYMj0Q
|
|
293
293
|
flwr/server/superlink/fleet/vce/backend/raybackend.py,sha256=jsUkFEVQTnrucK1jNQ_cUM8YwL7W4MQNA1GAf8ibRdg,7156
|
294
294
|
flwr/server/superlink/fleet/vce/vce_api.py,sha256=iXNSAJ7f8Sg1hOrVuRTGRkLdSWeFIpNWbusoOTc4I8I,12971
|
295
295
|
flwr/server/superlink/linkstate/__init__.py,sha256=v-2JyJlCB3qyhMNwMjmcNVOq4rkooqFU0LHH8Zo1jls,1064
|
296
|
-
flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=
|
297
|
-
flwr/server/superlink/linkstate/linkstate.py,sha256=
|
296
|
+
flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=tw98opVU78Q9jfIORLRhwSATiMTfDa5THlcegwXSzWM,29377
|
297
|
+
flwr/server/superlink/linkstate/linkstate.py,sha256=Yi76bAq-OJmDjl1HAQInrPIU0m9dKMiYugNJXKpKyuw,15843
|
298
298
|
flwr/server/superlink/linkstate/linkstate_factory.py,sha256=ISSMjDlwuN7swxjOeYlTNpI_kuZ8PGkMcJnf1dbhUSE,2069
|
299
|
-
flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=
|
300
|
-
flwr/server/superlink/linkstate/utils.py,sha256=
|
299
|
+
flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=c33n0iOZiQwNd07KfPkQbKZ7cSEX5LGg1crlUHd1ZD0,55309
|
300
|
+
flwr/server/superlink/linkstate/utils.py,sha256=vKJYvzP_MbYD2Qo8ly6Qibyb4SI92G_4sB60ubELj64,19048
|
301
301
|
flwr/server/superlink/simulation/__init__.py,sha256=mg-oapC9dkzEfjXPQFior5lpWj4g9kwbLovptyYM_g0,718
|
302
302
|
flwr/server/superlink/simulation/simulationio_grpc.py,sha256=8aUrZZLdvprKUfLLqFID4aItus9beU6m1qLQYIPB7k0,2224
|
303
303
|
flwr/server/superlink/simulation/simulationio_servicer.py,sha256=J_TmdqM-Bxgp-iPEI3tvCuBpykw1UX0FouMQalEYAF4,6907
|
@@ -308,7 +308,7 @@ flwr/server/utils/tensorboard.py,sha256=gEBD8w_5uaIfp5aw5RYH66lYZpd_SfkObHQ7eDd9
|
|
308
308
|
flwr/server/utils/validator.py,sha256=UzYFMIyXyORXYRYXbFhOk6q6GDpOE-eIqLhlNFnR__0,7256
|
309
309
|
flwr/server/workflow/__init__.py,sha256=SXY0XkwbkezFBxxrFB5hKUtmtAgnYISBkPouR1V71ss,902
|
310
310
|
flwr/server/workflow/constant.py,sha256=q4DLdR8Krlxuewq2AQjwTL75hphxE5ODNz4AhViHMXk,1082
|
311
|
-
flwr/server/workflow/default_workflows.py,sha256=
|
311
|
+
flwr/server/workflow/default_workflows.py,sha256=RwDX7hXOI1-q4FH9A0onHvadqa5yXTzslpmShPpXodk,14152
|
312
312
|
flwr/server/workflow/secure_aggregation/__init__.py,sha256=3XlgDOjD_hcukTGl6Bc1B-8M_dPlVSJuTbvXIbiO-Ic,880
|
313
313
|
flwr/server/workflow/secure_aggregation/secagg_workflow.py,sha256=l2IdMdJjs1bgHs5vQgLSOVzar7v2oxUn46oCrnVE1rM,5839
|
314
314
|
flwr/server/workflow/secure_aggregation/secaggplus_workflow.py,sha256=rfn2etO1nb7u-1oRl-H9q3enJZz3shMINZaBB7rPsC4,29671
|
@@ -329,8 +329,8 @@ flwr/superexec/exec_servicer.py,sha256=72AL60LBbWD-OTxTvtPBrnb_M5rccMtU_JAYcEVQV
|
|
329
329
|
flwr/superexec/exec_user_auth_interceptor.py,sha256=YtvcjrD2hMVmZ3y9wHuGI6FwmG_Y__q112t4fFnypy0,3793
|
330
330
|
flwr/superexec/executor.py,sha256=_B55WW2TD1fBINpabSSDRenVHXYmvlfhv-k8hJKU4lQ,3115
|
331
331
|
flwr/superexec/simulation.py,sha256=WQDon15oqpMopAZnwRZoTICYCfHqtkvFSqiTQ2hLD_g,4088
|
332
|
-
flwr_nightly-1.16.0.
|
333
|
-
flwr_nightly-1.16.0.
|
334
|
-
flwr_nightly-1.16.0.
|
335
|
-
flwr_nightly-1.16.0.
|
336
|
-
flwr_nightly-1.16.0.
|
332
|
+
flwr_nightly-1.16.0.dev20250305.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
333
|
+
flwr_nightly-1.16.0.dev20250305.dist-info/METADATA,sha256=X8lB9V-qGjFy1843wMvWpu-VV-sR-7xcfM-g9I2wh8A,15877
|
334
|
+
flwr_nightly-1.16.0.dev20250305.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
335
|
+
flwr_nightly-1.16.0.dev20250305.dist-info/entry_points.txt,sha256=JlNxX3qhaV18_2yj5a3kJW1ESxm31cal9iS_N_pf1Rk,538
|
336
|
+
flwr_nightly-1.16.0.dev20250305.dist-info/RECORD,,
|
{flwr_nightly-1.16.0.dev20250304.dist-info → flwr_nightly-1.16.0.dev20250305.dist-info}/LICENSE
RENAMED
File without changes
|
{flwr_nightly-1.16.0.dev20250304.dist-info → flwr_nightly-1.16.0.dev20250305.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|