Skip to content

Commit

Permalink
feat(framework) Introduce flwr_exit function (#4801)
Browse files Browse the repository at this point in the history
Co-authored-by: Javier <[email protected]>
Co-authored-by: Daniel J. Beutel <[email protected]>
  • Loading branch information
3 people authored Jan 19, 2025
1 parent 17ef284 commit aa4442f
Show file tree
Hide file tree
Showing 28 changed files with 548 additions and 65 deletions.
2 changes: 1 addition & 1 deletion framework/docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def find_test_modules(package_path):
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "ref-exit-codes/_template.rst"]

# Sphinx redirects, implemented after the doc filename changes.
# To prevent 404 errors and redirect to the new pages.
Expand Down
1 change: 1 addition & 0 deletions framework/docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ Information-oriented API reference and other reference material.
ref-telemetry
ref-changelog
ref-flower-network-communication
ref-exit-codes-dir
ref-faq

Contributor docs
Expand Down
27 changes: 27 additions & 0 deletions framework/docs/source/ref-exit-codes-dir.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Exit Codes
==========

This reference provides an index of all exit codes and recommended resolutions.

Categories
----------

- **Success exit codes (0-99)**: Indicate successful completion of processes.
- **SuperLink-specific exit codes (100-199)**: Specific to ``flower-superlink``
(SuperLink) errors.
- **ServerApp-specific exit codes (200-299)**: Specific to ``flwr-serverapp``
(ServerApp) errors.
- **SuperNode-specific exit codes (300-399)**: Specific to ``flower-supernode``
(SuperNode) errors.
- **ClientApp-specific exit codes (400-499)**: Specific to ``flwr-clientapp``
(ClientApp) errors.
- **Common exit codes (500-)**: Shared across multiple components.

Indices
-------

.. toctree::
:maxdepth: 1
:glob:

ref-exit-codes/*
7 changes: 7 additions & 0 deletions framework/docs/source/ref-exit-codes/000.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[0] SUCCESS
===========

Description
-----------

The process completed successfully.
7 changes: 7 additions & 0 deletions framework/docs/source/ref-exit-codes/001.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[1] GRACEFUL_EXIT_SIGINT
========================

Description
-----------

The process exited gracefully, triggered by ``SIGINT``.
7 changes: 7 additions & 0 deletions framework/docs/source/ref-exit-codes/002.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[2] GRACEFUL_EXIT_SIGQUIT
=========================

Description
-----------

The process exited gracefully, triggered by ``SIGQUIT``.
7 changes: 7 additions & 0 deletions framework/docs/source/ref-exit-codes/003.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[3] GRACEFUL_EXIT_SIGTERM
=========================

Description
-----------

The process exited gracefully, triggered by ``SIGTERM``.
23 changes: 23 additions & 0 deletions framework/docs/source/ref-exit-codes/100.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[100] SUPERLINK_THREAD_CRASH
============================

Description
-----------

A critical background thread has crashed in the SuperLink, causing it to exit
prematurely. This indicates a serious issue with the SuperLink that requires immediate
investigation.

Critical background threads include:

1. **Scheduler**: Schedules the execution of runs. This thread exists only when the
isolation mode is set to ``subprocess`` (default).
2. **REST API server**: Manages the REST API server. This thread exists only when the
Fleet API type is set to ``rest``.

How to Resolve
--------------

1. Check the logs for any errors that may have caused the thread to crash.
2. Ensure the SuperLink's configuration is correct.
3. If the issue persists, please contact support for further assistance.
20 changes: 20 additions & 0 deletions framework/docs/source/ref-exit-codes/300.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[300] SUPERNODE_REST_ADDRESS_INVALID
====================================

Description
-----------

The provided SuperLink address for the REST API is invalid. The address must start with
``http://`` or ``https://`` to be recognized correctly.

How to Resolve
--------------

When using the REST API, ensure that the server address starts with either ``https://``
or ``http://``. For example:

- ``http://127.0.0.1:8080``
- ``https://example.com:8080``

Verify the address in your configuration or command-line arguments and correct it as
needed.
26 changes: 26 additions & 0 deletions framework/docs/source/ref-exit-codes/301.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[301] SUPERNODE_NODE_AUTH_KEYS_REQUIRED
=======================================

Description
-----------

To run the SuperNode with authentication, file paths for both the private and public
keys must be provided. Specifically, the following options must be specified:

- ``--auth-supernode-private-key``
- ``--auth-supernode-public-key``

Providing only one of these options is insufficient for authentication.

How to Resolve
--------------

1. Ensure that the paths to both the private key and public key files are specified in
command-line arguments. For example:

.. code-block:: bash
--auth-supernode-private-key /path/to/private_key.pem
--auth-supernode-public-key /path/to/public_key.pem
2. Verify that the specified file paths are correct and that the files exist.
32 changes: 32 additions & 0 deletions framework/docs/source/ref-exit-codes/302.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[302] SUPERNODE_NODE_AUTH_KEYS_INVALID
======================================

Description
-----------

The provided key files are invalid. Authentication requires a valid elliptic curve
private and public key pair. This error occurs when either:

- The **private key** file specified in ``--auth-supernode-private-key`` is invalid or
unreadable.
- The **public key** file specified in ``--auth-supernode-public-key`` is invalid or
unreadable.

How to Resolve
--------------

1. Ensure that the file paths provided for the private and public key options are
correct.

2. Verify that both files exist and contain valid elliptic curve keys. - The private key
file should be in a format compatible with elliptic curve cryptography. - The public key
file should match the private key.

3. If the files are corrupted or not in the correct format, regenerate the elliptic
curve key pair and update the file paths accordingly. For example, in Linux/MacOS, **for
rapid prototyping only** (not production; follow company procedures for key management):

.. code-block:: bash
openssl ecparam-genkey -name secp384r1 -out private_key.pem
openssl ec -in private_key.pem -pubout -out public_key.pem
16 changes: 16 additions & 0 deletions framework/docs/source/ref-exit-codes/500.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[500] COMMON_ADDRESS_INVALID
============================

Description
-----------

The provided address is invalid and cannot be parsed. It must be a valid URL, IPv4, or
IPv6 address.

How to Resolve
--------------

Verify that the address is correctly formatted as one of the following:
- URL (e.g., ``https://127.0.0.1:8080`` or ``https://example.com:8080``)
- IPv4 (e.g., ``192.168.1.1:9091``)
- IPv6 (e.g., ``[2001:0db8::1]:9092``)
18 changes: 18 additions & 0 deletions framework/docs/source/ref-exit-codes/501.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[501] COMMON_MISSING_EXTRA_REST
===============================

Description
-----------

Extra dependencies required for using the REST-based Fleet API are missing.

How to Resolve
--------------

To enable the REST-based Fleet API, install ``flwr`` with the ``rest`` extra:

.. code-block:: bash
pip install "flwr[rest]"
Ensure that the installation completes successfully, and then retry.
16 changes: 16 additions & 0 deletions framework/docs/source/ref-exit-codes/502.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[502] COMMON_TLS_NOT_SUPPORTED
==============================

Description
-----------

The ``flwr-serverapp`` and ``flwr-clientapp`` do not currently support TLS, as they are
assumed to be executed within the same network as their respective long-running
processes: ``flower-superlink`` and ``flower-supernode``. Please refer to the `Flower
Network Communication <../ref-flower-network-communication.html>`_ guide for further
details.

How to Resolve
--------------

Use the ``--insecure`` flag to proceed without TLS.
12 changes: 12 additions & 0 deletions framework/docs/source/ref-exit-codes/_template.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[<CODE>] <NAME>
===============

Description
-----------

<DESCRIPTION>

How to Resolve
--------------

<RESOLUTION_STEPS>
14 changes: 7 additions & 7 deletions src/py/flwr/client/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
ISOLATION_MODE_PROCESS,
ISOLATION_MODE_SUBPROCESS,
MAX_RETRY_DELAY,
MISSING_EXTRA_REST,
RUN_ID_NUM_BYTES,
SERVER_OCTET,
TRANSPORT_TYPE_GRPC_ADAPTER,
Expand All @@ -55,6 +54,7 @@
TRANSPORT_TYPES,
ErrorCode,
)
from flwr.common.exit import ExitCode, flwr_exit
from flwr.common.grpc import generic_create_grpc_server
from flwr.common.logger import log, warn_deprecated_feature
from flwr.common.message import Error
Expand Down Expand Up @@ -763,7 +763,10 @@ def _init_connection(transport: Optional[str], server_address: str) -> tuple[
# Parse IP address
parsed_address = parse_address(server_address)
if not parsed_address:
sys.exit(f"Server address ({server_address}) cannot be parsed.")
flwr_exit(
ExitCode.COMMON_ADDRESS_INVALID,
f"SuperLink address ({server_address}) cannot be parsed.",
)
host, port, is_v6 = parsed_address
address = f"[{host}]:{port}" if is_v6 else f"{host}:{port}"

Expand All @@ -778,12 +781,9 @@ def _init_connection(transport: Optional[str], server_address: str) -> tuple[

from .rest_client.connection import http_request_response
except ModuleNotFoundError:
sys.exit(MISSING_EXTRA_REST)
flwr_exit(ExitCode.COMMON_MISSING_EXTRA_REST)
if server_address[:4] != "http":
sys.exit(
"When using the REST API, please provide `https://` or "
"`http://` before the server address (e.g. `http://127.0.0.1:8080`)"
)
flwr_exit(ExitCode.SUPERNODE_REST_ADDRESS_INVALID)
connection, error_type = http_request_response, RequestsConnectionError
elif transport == TRANSPORT_TYPE_GRPC_RERE:
connection, error_type = grpc_request_response, RpcError
Expand Down
10 changes: 4 additions & 6 deletions src/py/flwr/client/clientapp/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@


import argparse
import sys
import time
from logging import DEBUG, ERROR, INFO
from typing import Optional
Expand All @@ -29,6 +28,7 @@
from flwr.common.args import add_args_flwr_app_common
from flwr.common.config import get_flwr_dir
from flwr.common.constant import CLIENTAPPIO_API_DEFAULT_CLIENT_ADDRESS, ErrorCode
from flwr.common.exit import ExitCode, flwr_exit
from flwr.common.grpc import create_channel
from flwr.common.logger import log
from flwr.common.message import Error
Expand Down Expand Up @@ -61,12 +61,10 @@ def flwr_clientapp() -> None:
"""Run process-isolated Flower ClientApp."""
args = _parse_args_run_flwr_clientapp().parse_args()
if not args.insecure:
log(
ERROR,
"flwr-clientapp does not support TLS yet. "
"Please use the '--insecure' flag.",
flwr_exit(
ExitCode.COMMON_TLS_NOT_SUPPORTED,
"flwr-clientapp does not support TLS yet.",
)
sys.exit(1)

log(INFO, "Starting Flower ClientApp")
log(
Expand Down
5 changes: 2 additions & 3 deletions src/py/flwr/client/rest_client/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@


import random
import sys
import threading
from collections.abc import Iterator
from contextlib import contextmanager
Expand All @@ -32,12 +31,12 @@
from flwr.client.message_handler.message_handler import validate_out_message
from flwr.common import GRPC_MAX_MESSAGE_LENGTH
from flwr.common.constant import (
MISSING_EXTRA_REST,
PING_BASE_MULTIPLIER,
PING_CALL_TIMEOUT,
PING_DEFAULT_INTERVAL,
PING_RANDOM_RANGE,
)
from flwr.common.exit import ExitCode, flwr_exit
from flwr.common.logger import log
from flwr.common.message import Message, Metadata
from flwr.common.retry_invoker import RetryInvoker
Expand All @@ -62,7 +61,7 @@
try:
import requests
except ModuleNotFoundError:
sys.exit(MISSING_EXTRA_REST)
flwr_exit(ExitCode.COMMON_MISSING_EXTRA_REST)


PATH_CREATE_NODE: str = "api/v0/fleet/create-node"
Expand Down
Loading

0 comments on commit aa4442f

Please sign in to comment.