From 6587a339855681827238f7aa3302d43782fe1fc3 Mon Sep 17 00:00:00 2001 From: Piotr Korkus Date: Wed, 18 Mar 2026 14:05:12 +0100 Subject: [PATCH] docs: update to supported formats - move md to rst - regenerate diagrams in plantuml --- docs/index.rst | 2 + docs/module/lifecycle_client_lib/lifecycle.md | 132 ----------- .../module/lifecycle_client_lib/lifecycle.rst | 220 ++++++++++++++++++ .../lifecycle_client_lib/lifecyclemanager.md | 19 -- .../lifecycle_client_lib/lifecyclemanager.rst | 52 +++++ .../model/app_lifecycle.puml | 25 ++ .../model/app_lifecycle.uxf | 4 - .../model/lifecycle_system_view.puml | 36 +++ .../model/lifecycle_system_view.uxf | 40 ---- .../model/sequence_application_container.puml | 51 ++++ .../model/sequence_application_container.uxf | 75 ------ .../model/sequence_view.puml | 44 ++++ .../model/sequence_view.uxf | 37 --- .../model/structural_view.puml | 79 +++++++ .../model/structural_view.uxf | 70 ------ 15 files changed, 509 insertions(+), 377 deletions(-) delete mode 100644 docs/module/lifecycle_client_lib/lifecycle.md create mode 100644 docs/module/lifecycle_client_lib/lifecycle.rst delete mode 100644 docs/module/lifecycle_client_lib/lifecyclemanager.md create mode 100644 docs/module/lifecycle_client_lib/lifecyclemanager.rst create mode 100644 docs/module/lifecycle_client_lib/model/app_lifecycle.puml delete mode 100644 docs/module/lifecycle_client_lib/model/app_lifecycle.uxf create mode 100644 docs/module/lifecycle_client_lib/model/lifecycle_system_view.puml delete mode 100644 docs/module/lifecycle_client_lib/model/lifecycle_system_view.uxf create mode 100644 docs/module/lifecycle_client_lib/model/sequence_application_container.puml delete mode 100644 docs/module/lifecycle_client_lib/model/sequence_application_container.uxf create mode 100644 docs/module/lifecycle_client_lib/model/sequence_view.puml delete mode 100644 docs/module/lifecycle_client_lib/model/sequence_view.uxf create mode 100644 docs/module/lifecycle_client_lib/model/structural_view.puml delete mode 100644 docs/module/lifecycle_client_lib/model/structural_view.uxf diff --git a/docs/index.rst b/docs/index.rst index 3dfd4d99..ee80d617 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -21,6 +21,8 @@ Lifecycle :titlesonly: module/*/index + module/lifecycle_client_lib/lifecycle + module/lifecycle_client_lib/lifecyclemanager statistics.rst Overview diff --git a/docs/module/lifecycle_client_lib/lifecycle.md b/docs/module/lifecycle_client_lib/lifecycle.md deleted file mode 100644 index 803a2930..00000000 --- a/docs/module/lifecycle_client_lib/lifecycle.md +++ /dev/null @@ -1,132 +0,0 @@ -# Application Lifecycle - -## Introduction -Purpose of this component is to have a layer of abstraction, that unifies API, for execution managers and applications so in case of replacing lifecycle manager there will be no need to change applications. - -> This component has `ASIL-B` safety level. - -## External interfaces - -Component consists of three main parts: -* Application Base class `score::mw::lifecycle::Application` from which application developers shall subclass their own application. -* Lifecycle manager class `score::mw::lifecycle::LifecycleManager` see [lifecyclemanager.md](lifecyclemanager.md) file. -* Runner class `score::mw::lifecycle::Run` which instantiates the user provided application and decides which LifeCycleManager to use. - -Overview on how lifecycle application is related to execution manager. -![Lifecycle Manager Application Overview](model/lifecycle_system_view.uxf) - -### AAS Interfaces -N/A - -### External C++ interfaces -`score:mw::Application` methods which have to be implemented by the application: -#### Initialize -This method shall do basic initialization of application (what was not done in application [State `Initializing`](#state-initializing)). -Method returns a `Result`, which either contains `void` on success or an error. In case of an error lifecycle manager will join all running threads and will return with non zero value. -Input parameter to this method is an instance of `ApplicationContext`, which is a wrapper around the arguments, which have been given to `main`. - -#### Run -This method implements the `Run` state of the app (see [State `Run`](#state-run)). This could be a long running -functionality. In case `Run()` returns, this implicitly means, that the app has ended. If -app implementations do spawn some worker threads in the context of `Run()`, those threads -are joined again before` Run()` returns. -To be able to terminate an application `Run()` method from outside asynchronously in a cooperative manner, the `Run()` method -gets a `stop_token`, where it shall synchronize/listen on (see concepts in https://en.cppreference.com/w/cpp/thread/stop_token) -This `stop_token` is controlled by an external `stop_source` owned by the `LifecycleManager`. - -ApplicationContext class represents cmd line arguments of an Application that are passed during `Initialize` function call. -#### get_argument -Function gets a argument name as a string and returns it's value if it exists, otherwise empty string is returned. -#### get_arguments -Returns list of cmd line arguments represented as a vector. -Example code: - - std::array in_args{}; - if (context.get_arguments().empty()) - { - score::mw::log::LogError() << "Incorrect arguments given\n"; - } else - { - context.get_argument("-i", in_args[0]); - if (in_args[0].empty()) - { - score::mw::log::LogError() << "Tsync Incorrect arguments given\n"; - } else - { - // argument is in in_args[0] to be used by application - } - } - -#### run_application template function -`run_application` function abstracts initialization and running of an application with LifeCycleManager. This function should be used to start application, it take command line arguments as input parameters - -### Hardware interfaces -N/A -### Interrupts -N/A -### File system -N/A -### POSIX signals -SIGTERM see [lifecyclemanager.md](lifecyclemanager.md) - -## Static architecture -![Structural View](model/structural_view.uxf) - -## Dynamic architecture - -### Activity sequencing -The following sequence diagram shows the interaction between OS and instances of `Application` class, which were -decorated with a `LifecycleManager`: - -![Sequence View](model/sequence_view.uxf) - -### Stateful behavior - -The following state machine depicts the states/transitions of an application: - -![Application Lifecycle](model/app_lifecycle.uxf) - -#### State `Terminated` respectively `Not Started` - -This is the initial respectively final state of an application, before its executable has been started (forked, executed) and after it -has terminated. - -#### State `Initializing` - -This state is automatically entered upon start of the executable (fork + exec). It is left towards state `Run` -if the application decides to do so via an active/explicit reporting to the platform, that it has entered `Run`. - -##### What shall/can be done in this state -* Initialize internal variables/memory -* Access persistent storage to read/lookup configuration -* Search for/start searching for other service instances to be used to provide application services - * Note: These operations must not be performed in a blocking manner! Otherwise the predefined maximum amount of time to be spent in machine state `Initializing` might be exceeded and the ECU will restart immediately once that becomes the case. -* access remote service instances if available - * Also here, keep in mind the note from above! -* access to low-level platform services, which are expected to be available, when an application starts. -* call to exit. F.i. if initialization can't conclude. - -##### What must not be done in this state -* Offer any service instance. Reason: If it would offer a service instance, an instant service call to this instance - could happen and would then be served during state `Initializing`, which isn't acceptable. -* Generally: Providing/Executing main application logic, which is assigned to `Run` state. - -#### State `Run` - -As mentioned above: This state is entered, when the application reports `Run` state to the platform. -An application should only enter this state, if it is able to provide its core/base functionality. If it isn't able to -do so, it shall not report `Run` at all. - -##### Example of what could be done in this state -* Assign invalid/dummy values as defaults to the fields/events of service(s) to be offered -* Offer service(s) -* Prepare DTCs -* Wait for dependent services to become available via their generated proxy classes -* connect to/lookup other required resources -* run core logic - -## Variability -* N/A - -### Deployment -* There is example app available that can help with deploying this library see [example application](test/example/README.md) subdirectory diff --git a/docs/module/lifecycle_client_lib/lifecycle.rst b/docs/module/lifecycle_client_lib/lifecycle.rst new file mode 100644 index 00000000..e7454c22 --- /dev/null +++ b/docs/module/lifecycle_client_lib/lifecycle.rst @@ -0,0 +1,220 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _application_lifecycle: + +Application Lifecycle +===================== + +Introduction +------------ + +Purpose of this component is to have a layer of abstraction, that unifies API, for execution managers and applications so in case of replacing lifecycle manager there will be no need to change applications. + +.. note:: + + This component has ``ASIL-B`` safety level. + +External interfaces +------------------- + +Component consists of three main parts: + +* Application Base class ``score::mw::lifecycle::Application`` from which application developers shall subclass their own application. +* Lifecycle manager class ``score::mw::lifecycle::LifecycleManager`` see :ref:`lifecyclemanager_class`. +* Runner class ``score::mw::lifecycle::Run`` which instantiates the user provided application and decides which LifeCycleManager to use. + +Overview on how lifecycle application is related to execution manager. + +.. uml:: model/lifecycle_system_view.puml + :caption: Lifecycle Manager Application Overview + +AAS Interfaces +~~~~~~~~~~~~~~ + +N/A + +External C++ interfaces +~~~~~~~~~~~~~~~~~~~~~~~ + +``score:mw::Application`` methods which have to be implemented by the application: + +Initialize +^^^^^^^^^^ + +This method shall do basic initialization of application (what was not done in application :ref:`State Initializing `). +Method returns a ``Result``, which either contains ``void`` on success or an error. In case of an error lifecycle manager will join all running threads and will return with non zero value. +Input parameter to this method is an instance of ``ApplicationContext``, which is a wrapper around the arguments, which have been given to ``main``. + +Run +^^^ + +This method implements the ``Run`` state of the app (see :ref:`State Run `). This could be a long running +functionality. In case ``Run()`` returns, this implicitly means, that the app has ended. If +app implementations do spawn some worker threads in the context of ``Run()``, those threads +are joined again before ``Run()`` returns. +To be able to terminate an application ``Run()`` method from outside asynchronously in a cooperative manner, the ``Run()`` method +gets a ``stop_token``, where it shall synchronize/listen on (see concepts in https://en.cppreference.com/w/cpp/thread/stop_token) +This ``stop_token`` is controlled by an external ``stop_source`` owned by the ``LifecycleManager``. + +ApplicationContext class represents cmd line arguments of an Application that are passed during ``Initialize`` function call. + +get_argument +^^^^^^^^^^^^ + +Function gets a argument name as a string and returns it's value if it exists, otherwise empty string is returned. + +get_arguments +^^^^^^^^^^^^^ + +Returns list of cmd line arguments represented as a vector. + +Example code: + +.. code-block:: cpp + + std::array in_args{}; + if (context.get_arguments().empty()) + { + score::mw::log::LogError() << "Incorrect arguments given\n"; + } else + { + context.get_argument("-i", in_args[0]); + if (in_args[0].empty()) + { + score::mw::log::LogError() << "Tsync Incorrect arguments given\n"; + } else + { + // argument is in in_args[0] to be used by application + } + } + +run_application template function +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``run_application`` function abstracts initialization and running of an application with LifeCycleManager. This function should be used to start application, it take command line arguments as input parameters + +Hardware interfaces +~~~~~~~~~~~~~~~~~~~ + +N/A + +Interrupts +~~~~~~~~~~ + +N/A + +File system +~~~~~~~~~~~ + +N/A + +POSIX signals +~~~~~~~~~~~~~ + +SIGTERM see `lifecyclemanager.rst `_ + +Static architecture +------------------- + +.. uml:: model/structural_view.puml + :caption: Structural View + +Dynamic architecture +-------------------- + +Activity sequencing +~~~~~~~~~~~~~~~~~~~ + +The following sequence diagram shows the interaction between OS and instances of ``Application`` class, which were +decorated with a ``LifecycleManager``: + +.. uml:: model/sequence_view.puml + :caption: Sequence View + +Stateful behavior +~~~~~~~~~~~~~~~~~ + +The following state machine depicts the states/transitions of an application: + +.. uml:: model/app_lifecycle.puml + :caption: Application Lifecycle + +.. _state-terminated: + +State ``Terminated`` respectively ``Not Started`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This is the initial respectively final state of an application, before its executable has been started (forked, executed) and after it +has terminated. + +.. _state-initializing: + +State ``Initializing`` +^^^^^^^^^^^^^^^^^^^^^^ + +This state is automatically entered upon start of the executable (fork + exec). It is left towards state ``Run`` +if the application decides to do so via an active/explicit reporting to the platform, that it has entered ``Run``. + +What shall/can be done in this state ++++++++++++++++++++++++++++++++++++++ + +* Initialize internal variables/memory +* Access persistent storage to read/lookup configuration +* Search for/start searching for other service instances to be used to provide application services + + * Note: These operations must not be performed in a blocking manner! Otherwise the predefined maximum amount of time to be spent in machine state ``Initializing`` might be exceeded and the ECU will restart immediately once that becomes the case. + +* access remote service instances if available + + * Also here, keep in mind the note from above! + +* access to low-level platform services, which are expected to be available, when an application starts. +* call to exit. F.i. if initialization can't conclude. + +What must not be done in this state +++++++++++++++++++++++++++++++++++++ + +* Offer any service instance. Reason: If it would offer a service instance, an instant service call to this instance + could happen and would then be served during state ``Initializing``, which isn't acceptable. +* Generally: Providing/Executing main application logic, which is assigned to ``Run`` state. + +.. _state-run: + +State ``Run`` +^^^^^^^^^^^^^ + +As mentioned above: This state is entered, when the application reports ``Run`` state to the platform. +An application should only enter this state, if it is able to provide its core/base functionality. If it isn't able to +do so, it shall not report ``Run`` at all. + +Example of what could be done in this state +++++++++++++++++++++++++++++++++++++++++++++ + +* Assign invalid/dummy values as defaults to the fields/events of service(s) to be offered +* Offer service(s) +* Prepare DTCs +* Wait for dependent services to become available via their generated proxy classes +* connect to/lookup other required resources +* run core logic + +Variability +----------- + +* N/A + +Deployment +---------- + +* There is example app available that can help with deploying this library see `example application `_ subdirectory diff --git a/docs/module/lifecycle_client_lib/lifecyclemanager.md b/docs/module/lifecycle_client_lib/lifecyclemanager.md deleted file mode 100644 index 097016bd..00000000 --- a/docs/module/lifecycle_client_lib/lifecyclemanager.md +++ /dev/null @@ -1,19 +0,0 @@ -# Lifecyclemanager class - -## Introduction -Purpose of `score::mw::lifecycle::LifecycleManager` component is to have a layer of abstraction, that unifies API, for execution managers. - -> This component has `ASIL-B` safety level. - -## External C++ interfaces -`LifecycleManager` class is a decoration of [score::mw::lifecycle::Application](lifecycle.md) class. It adds POSIX signal handling for SIGTERM signal, for decorated `Application`. - -Methods which have to be implemented in case of adding new lifecycle manager: -### report_running -Hook function for reporting running state in lifecycle manager -### report_shutdown -Hook function for reporting shutdown state in lifecycle manager - -### POSIX signals -#### SIGTERM -Lifecycle manager `handle_signal` function waits for SIGTERM signal, if signal is received it's shuts down application, reports shutdown to execution manager and exits itself. diff --git a/docs/module/lifecycle_client_lib/lifecyclemanager.rst b/docs/module/lifecycle_client_lib/lifecyclemanager.rst new file mode 100644 index 00000000..36a98045 --- /dev/null +++ b/docs/module/lifecycle_client_lib/lifecyclemanager.rst @@ -0,0 +1,52 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _lifecyclemanager_class: + +Lifecyclemanager class +====================== + +Introduction +------------ + +Purpose of ``score::mw::lifecycle::LifecycleManager`` component is to have a layer of abstraction, that unifies API, for execution managers. + +.. note:: + + This component has ``ASIL-B`` safety level. + +External C++ interfaces +----------------------- + +``LifecycleManager`` class is a decoration of :ref:`score::mw::lifecycle::Application ` class. It adds POSIX signal handling for SIGTERM signal, for decorated ``Application``. + +Methods which have to be implemented in case of adding new lifecycle manager: + +report_running +~~~~~~~~~~~~~~ + +Hook function for reporting running state in lifecycle manager + +report_shutdown +~~~~~~~~~~~~~~~ + +Hook function for reporting shutdown state in lifecycle manager + +POSIX signals +~~~~~~~~~~~~~ + +SIGTERM +^^^^^^^ + +Lifecycle manager ``handle_signal`` function waits for SIGTERM signal, if signal is received it's shuts down application, reports shutdown to execution manager and exits itself. diff --git a/docs/module/lifecycle_client_lib/model/app_lifecycle.puml b/docs/module/lifecycle_client_lib/model/app_lifecycle.puml new file mode 100644 index 00000000..476cbdc1 --- /dev/null +++ b/docs/module/lifecycle_client_lib/model/app_lifecycle.puml @@ -0,0 +1,25 @@ +@startuml app_lifecycle +!define DIRECTION top to bottom direction + +title Application Lifecycle State Machine + +state Terminated { +} + +state Initializing { +} + +state Run { +} + +[*] --> Terminated + +Terminated --> Initializing: fork/exec + +Initializing --> Run: Report Run + +Run --> Terminated: exit/Sig Term/Sig Kill + +Terminated --> [*] + +@enduml diff --git a/docs/module/lifecycle_client_lib/model/app_lifecycle.uxf b/docs/module/lifecycle_client_lib/model/app_lifecycle.uxf deleted file mode 100644 index ea91b987..00000000 --- a/docs/module/lifecycle_client_lib/model/app_lifecycle.uxf +++ /dev/null @@ -1,4 +0,0 @@ -10UMLState10110820090Terminated/Not StartedUMLSpecialState1782020type=initialRelation117811090lt=->10;10;90;70UMLSpecialState12382020type=finalRelation11168110100lt=->90;10;10;80UMLState50110821090InitializingUMLState301378190100RunRelation391188210210lt=-> -Report Run190;10;10;190Relation29113823040lt=-> -fork/exec10;20;210;20Relation181188220210lt=-> -exit/Sig Term/Sig Kill180;190;10;10 \ No newline at end of file diff --git a/docs/module/lifecycle_client_lib/model/lifecycle_system_view.puml b/docs/module/lifecycle_client_lib/model/lifecycle_system_view.puml new file mode 100644 index 00000000..5a403543 --- /dev/null +++ b/docs/module/lifecycle_client_lib/model/lifecycle_system_view.puml @@ -0,0 +1,36 @@ +@startuml lifecycle_system_view +title Lifecycle System View + +class "mw:Application" as mwApp #FFFF00 + +class "Application" as App #0000FF { +} + +class "mw:LifecycleManager" as LifecycleManager #FFFF00 + +class "Execution Manager" as ExecMgr + +class "OS" as OS + +class "Application Context" as AppCtx #0000FF { +} + +App --|> mwApp : <> +App --> LifecycleManager : manages (run, terminate) + +LifecycleManager --> ExecMgr : reports state (run, terminate) +LifecycleManager --> OS : handles application SIGTERM + +AppCtx --> ExecMgr : starts + +AppCtx --> LifecycleManager : starts + +note left of App + Application +end note + +note right of LifecycleManager + mw::lifecycle +end note + +@enduml diff --git a/docs/module/lifecycle_client_lib/model/lifecycle_system_view.uxf b/docs/module/lifecycle_client_lib/model/lifecycle_system_view.uxf deleted file mode 100644 index 4c5f872e..00000000 --- a/docs/module/lifecycle_client_lib/model/lifecycle_system_view.uxf +++ /dev/null @@ -1,40 +0,0 @@ -10Lifecycle applicationUMLClass40412616030/mw:application/ -bg=yellow -Relation28411614050lt=<<. -implements -m1=1 -m2=1120;20;10;20UMLClass11012618030Application -bg=blueUMLClass18024644030mw:LifecycleManager -bg=yellowRelation450146160120lt=<. -manages (run, terminate) -m1=1 -m2=110;10;10;100UMLClass12050642030Execution Manager -Relation280266110260lt=<- -reports state -(run, terminate) -m1=1 -m2=n10;240;10;10UMLClass12054654030OSRelation580266140300lt=<- -handles -application SIGTERM -m1=n -m2=1 -10;10;10;280UMLClass6036621030Application context (main) -bg=blueRelation15038660140lt=<- -starts -m1=n -m2=1 -10;10;10;120Relation19026660120lt=<- -starts -m1=1 -m2=110;10;10;100UMLNote66278180130Scope of.. -bg=white -UMLClass67210815030Application -bg=Blue -UMLClass67214815030mw:lifecycle -bg=yellow -Relation440266140260lt=<- -handles -application SIGTERM -m1=n -m2=1 -10;10;10;240 diff --git a/docs/module/lifecycle_client_lib/model/sequence_application_container.puml b/docs/module/lifecycle_client_lib/model/sequence_application_container.puml new file mode 100644 index 00000000..20120f5a --- /dev/null +++ b/docs/module/lifecycle_client_lib/model/sequence_application_container.puml @@ -0,0 +1,51 @@ +@startuml sequence_application_container +title AasApplicationContainer Sequence Diagram + +participant "main" as Main +participant "Container" as Container +participant "LifecycleManager" as LM +participant "Application" as App + +== Container Setup == +Main ->> Container: new AasApplicationContainer() +Main ->> Container: With(args) +Main ->> Container: With(args) + +== Launch == +Main ->> Container: Launch() +activate Container + +Container ->> LM: new LifecycleManager() +Container ->> LM: run(*this, context_) +activate LM + +LM ->> Container: Initialize(context) + +== Initialize Applications == +loop for each application + LM ->> App: Initialize(context) + App -->> LM: result +end + +alt initialization failed + LM -->> Container: error + Container -->> Main: error +else initialization success + + == Run Applications == + loop for each application (except last) + LM ->> App: run(stop_token) [threaded] + end + + LM ->> App: run(stop_token) [last app, main thread] + App -->> LM: result + + LM -->> Container: result +end + +deactivate LM +deactivate Container + +Container -->> Main: exit code + +@enduml diff --git a/docs/module/lifecycle_client_lib/model/sequence_application_container.uxf b/docs/module/lifecycle_client_lib/model/sequence_application_container.uxf deleted file mode 100644 index 7da1868c..00000000 --- a/docs/module/lifecycle_client_lib/model/sequence_application_container.uxf +++ /dev/null @@ -1,75 +0,0 @@ -8UMLGeneric20008024_:main_Relation232162456lt=.10;10;10;50UMLGeneric23256161672UMLGeneric720016024_:AasApplicationContainer_Relation784162456lt=.10;10;10;50UMLGeneric784561640UMLGeneric1720408024_:Application_Relation1752562488lt=.10;10;10;90UMLGeneric17521281632Relation2404856032lt=<. -<<create>>680;20;10;20Relation784882456lt=.10;10;10;50UMLGeneric7841281688Relation24012056032lt=<<<- -With<App1>(Args&&...)680;20;10;20Relation79212097632lt=<. -<<create>>1200;20;10;20Relation79214415256lt=<<<- -add Application10;50;80;50;80;10;10;10Relation24018456032lt=<.. -10;20;680;20Relation79226415256lt=<<<- -add Application10;50;80;50;80;10;10;10Relation79224097632lt=<. -<<create>>1200;20;10;20UMLGeneric7842481688Relation7842082456lt=.10;10;10;50UMLGeneric17522481632Relation175215224112lt=.10;10;10;120Relation24024056032lt=<<<- -With<App2>(Args&&...)680;20;10;20Relation7843282456lt=.10;10;10;50UMLGeneric43240016024_:LifeCycleManager_UMLGeneric496496161232Relation24030456032lt=<.. -10;20;680;20UMLGeneric784368161360Relation24036056032lt=<<<- -Launch()680;20;10;20Relation50444829632lt=<. -<<create>>10;20;350;20Relation50449629632lt=<<<- -run(*this, context_)10;20;350;20Relation50452829632lt=<<<- -Initialize(context)350;20;10;20UMLGeneric4964401632Relation4964642448lt=.10;10;10;40UMLFrame1847441664160loop --- -[for each thread] -bg=CYANRelation175227224352lt=.10;10;10;420Relation79284860832lt=<.. -result10;20;740;20Relation50484829632lt=<.. -result10;20;350;20UMLFrame192816159272opt --- - -bg=GREENUMLNote082411256Rest of sequence -is cancelled in -error case -bg=REDRelation24084827232lt=<.. -result10;20;320;20Relation1048489624lt=.100;10;10;10Relation175286424216lt=.10;10;10;250Relation504100029632lt=<<<- -Run(stop_token)350;20;10;20UMLFrame16013521056200loop --- - -bg=REDUMLGeneric175210641656Relation792107260840lt=<<<- -<<create thread calling Run() -of application>>740;20;10;20UMLGeneric138410641656UMLGeneric13443929624_:amp::jthread_Relation138467224128lt=.10;10;10;140Relation1392108837632lt=<<<- -Run(stop_token)450;20;10;20Relation1752111224112lt=.10;10;10;120Relation792120097632lt=<<<- -call Run() for the last application1200;20;10;20UMLGeneric175212081696Relation792128097632lt=<.. -return result10;20;1200;20Relation1752129624448lt=.10;10;10;540Relation504128029632lt=<.. -return result10;20;350;20Relation240128027232lt=<.. -return result10;20;320;20UMLFrame12812321152368alt --- - - - - - - --- - -bg=GREENText256124810424[result != 0] - -style=wordwrapUMLFrame73610321112104loop --- -[for each application except -the last one] -bg=CYANRelation1384111224312lt=.10;10;10;370UMLGeneric138414081696Relation792140060832lt=<<<- -join()740;20;10;20Relation792147260832lt=<.. -return result10;20;740;20Text536136013624[for each thread] - -style=wordwrapRelation504147229632lt=<.. -return result10;20;350;20Relation240147227232lt=<.. -return result10;20;320;20UMLFrame184143286496opt --- - -bg=BLUEText264155210424[result != 0] - -style=wordwrapRelation504164029632lt=<.. -return 010;20;350;20Relation240164827232lt=<.. -return 010;20;320;20Relation1384149624248lt=.10;10;10;290Relation4964162440lt=.10;10;10;30UMLGeneric13846001680Relation138440824208lt=.10;10;10;240Relation79259260832lt=<<<- -<<create thread calling Initialize() of application740;20;10;20UMLFrame7365601112128loop --- -[for each application] -bg=CYANUMLGeneric175260816264Relation139260037632lt=<<<- -Initialize(context)450;20;10;20Relation139284837632lt=<.. -result10;20;450;20UMLGeneric13847841688Relation138486424216lt=.10;10;10;250Relation79277660832lt=<<<- -join()740;20;10;20Text28082410424[result != 0] -Relation50492029632lt=<.. -return 010;20;350;20 \ No newline at end of file diff --git a/docs/module/lifecycle_client_lib/model/sequence_view.puml b/docs/module/lifecycle_client_lib/model/sequence_view.puml new file mode 100644 index 00000000..160ab5aa --- /dev/null +++ b/docs/module/lifecycle_client_lib/model/sequence_view.puml @@ -0,0 +1,44 @@ +@startuml sequence_view +title Application Lifecycle Sequence Diagram + +participant "OS_ExecMgmt" as OS +participant "Process" as Process +participant "AppContext" as AppCtx +participant "Application" as App +participant "LifecycleManager" as LM +participant "StopSource" as StopSrc +participant "StopToken" as StopTok + +== Initialization == +OS ->> Process: create +Process ->> Process: main(argc, argv) +Process ->> AppCtx: ctor(argc, argv) +Process ->> App: ctor() +Process ->> StopSrc: ctor() +Process ->> LM: ctor(Application&, AppContext&) +OS ->> LM: registerSignalHandler() + +== Execution == +Process ->> LM: run() +LM ->> App: Initialize(AppContext&) +App -->> LM: return +LM ->> StopTok: create +LM ->> App: run(StopToken) + +== Signal Handling == +OS ->> LM: Signal(SigTerm) +LM ->> StopSrc: request_stop() +StopSrc ->> StopTok: notify() + +== Polling == +note over App: Check stop_requested() + +App ->> StopTok: stop_requested() +StopTok -->> App: TRUE/FALSE + +== Shutdown == +App -->> LM: return exitCode +LM ->> Process: return exitCode +Process ->> OS: return exitCode + +@enduml diff --git a/docs/module/lifecycle_client_lib/model/sequence_view.uxf b/docs/module/lifecycle_client_lib/model/sequence_view.uxf deleted file mode 100644 index f52b7903..00000000 --- a/docs/module/lifecycle_client_lib/model/sequence_view.uxf +++ /dev/null @@ -1,37 +0,0 @@ -9UMLGeneric0011736_:OS_ExecMgmt_UMLGeneric261819027_:Process_Relation3627271116lt=.10;10;10;1220Relation457223436lt=<<<- -create240;20;10;20Relation28899271008lt=.10;10;10;1100Relation4510826136lt=<<<- -main(int argc, const char* argv[])270;20;10;20UMLGeneric28812618936UMLGeneric6571989027_:Application_Relation69321627900lt=.10;10;10;980Relation29718937836lt=<<<- -ctor400;20;10;20UMLGeneric88223412627_:LifecycleManager_Relation92725227873lt=.10;10;10;950Relation29723460336lt=<<<- -ctor(Application&, ApplicationContext&)650;20;10;20UMLGeneric44112615327_:ApplicationContext_Relation29712616236lt=<<<- -ctor(argc, argv)160;20;10;20Relation29730664836lt=<<<- -run700;20;10;20UMLGeneric92732418585Relation70236924336lt=<<<- -Initialize(ApplicationContext&)10;20;250;20UMLGeneric6933871845Relation70240524336lt=<.. -return250;20;10;20Relation70251324336lt=<<<- -run(StopToken)10;20;250;20UMLGeneric69353118360UMLGeneric11974149027_:StopSource_Relation93641427936lt=<<<- -ctor290;20;10;20Relation4534290036lt=<<<- -registerSignalHandler()10;20;980;20Relation45657107136lt=<<<- -Signal(SigTerm)1170;20;10;20UMLGeneric13954599027_:StopToken_Relation93644131536lt=<<<- -get_token()330;20;10;20Relation123343227675lt=.10;10;10;730UMLGeneric12334501836Relation124245017136lt=<<<- -ctor170;20;10;20Relation93646831536lt=<.. -return StopToken10;20;330;20UMLGeneric10986661854Relation110767514436lt=<<<- -request_stop140;20;10;20UMLGeneric12336841854Relation142247727621lt=.10;10;10;670UMLGeneric14227111854Relation124269319836lt=<<<- -notify200;20;10;20UMLFrame97831458234Alternative --- -cyclically StopToken Polling - - - - - - - --- -usage of stop_callbackRelation70282873836lt=<<<- -stop_requested()800;20;10;20UMLGeneric14228371836Relation70284673836lt=<.. -Return TRUE10;20;800;20UMLGeneric14229451827UMLGeneric101723420727_:LifeCycleManagerSigHandler_Relation109825227864lt=.10;10;10;940Relation70287324336lt=<.. -return exitCode250;20;10;20Relation297102664836lt=<.. -return exitCode10;20;700;20Relation45104426136lt=<.. -return exitCode10;20;270;20UMLGeneric6939541827Relation70293673836lt=<<<- -stop_callback()10;20;800;20UMLGeneric9279811827Relation70296324336lt=<.. -return exitCode250;20;10;20UMLGeneric92710261818UMLSpecialState28810891818type=terminationUMLSpecialState69310891818type=terminationUMLSpecialState92710891818type=terminationUMLSpecialState123310801818type=terminationUMLSpecialState142210801818type=terminationUMLSpecialState109810801818type=terminationRelation4548690036lt=<- -report_run_hook()10;20;980;20UMLGeneric3645181071 \ No newline at end of file diff --git a/docs/module/lifecycle_client_lib/model/structural_view.puml b/docs/module/lifecycle_client_lib/model/structural_view.puml new file mode 100644 index 00000000..e5c16e82 --- /dev/null +++ b/docs/module/lifecycle_client_lib/model/structural_view.puml @@ -0,0 +1,79 @@ +@startuml structural_view +title Structural View + +' Interfaces and Classes +interface "<>\nscore::mw::lifecycle::Application" as IApplication { + + initialize(const ApplicationContext&): int32_t {abstract} + + run(amp::stop_token stop_token): int32_t {abstract} +} + +class "score::mw::lifecycle::ApplicationContext" as ApplicationContext { + + ApplicationContext(const int32_t argc, const score::StringLiteral argv[]) + + get_arguments(): const std::vector& const noexcept + + get_argument(const amp::string_view flag): std::string const noexcept + -- + - m_args: std::vector + - m_app_path: std::string +} + +class "score::mw::lifecycle::LifecycleManager" as LifecycleManager { + + LifecycleManager(std::unique_ptr signal_interface) + + LifecycleManager(LifecycleManager&& other) = delete + + LifecycleManager(const LifecycleManager& other) = delete + + LifecycleManager& operator=(LifecycleManager&& other) = delete + + LifecycleManager& operator=(const LifecycleManager& other) = delete + + run(Application& app, const ApplicationContext&): int32_t + -- + - m_stop_source: amp::stop_source + - m_app: Application* + - m_signal_set: sigset_t + - m_signal_handler_thread: std::thread + - signal_: std::unique_ptr +} + +class "score::mw::lifecycle::AasApplicationContainer" as AasApplicationContainer { + + initialize(const ApplicationContext&): int32_t override + + run(amp::stop_token stop_token): int32_t override + + AasApplicationContainer(const int32_t argc, const score::StringLiteral* argv, const std::size_t count_expected_applications): noexcept + + With(Args&&.. args): AasApplicationContainer& + + Launch(): int32_t + -- + - context_: score::mw::lifecycle::ApplicationContext + - applications_: std::vector> + - count_expected_applications_: std::size_t +} + +class "Run" as RunTemplate { + + Run(const int32_t argc, const score::StringLiteral* argv) + + AsPosixProcess(Args&&... args): int32_t const + -- + - context_: ApplicationContext +} + +' Relationships +AasApplicationContainer --|> IApplication : implements +LifecycleManager --> IApplication : manages +LifecycleManager --> ApplicationContext : uses +AasApplicationContainer --> ApplicationContext : uses +RunTemplate --> LifecycleManager : creates & runs +RunTemplate --> IApplication : creates & runs +RunTemplate --> ApplicationContext : uses + +note right of LifecycleManager + Note + -- + Implementation is platform specific. + It typically implements + a (POSIX) signal handling as we expect, + that termination of apps is + done via signaling in all environments. +end note + +note right of RunTemplate + Note + -- + Enable the easy usage of our + application in different environments +end note + +@enduml diff --git a/docs/module/lifecycle_client_lib/model/structural_view.uxf b/docs/module/lifecycle_client_lib/model/structural_view.uxf deleted file mode 100644 index 3237b39b..00000000 --- a/docs/module/lifecycle_client_lib/model/structural_view.uxf +++ /dev/null @@ -1,70 +0,0 @@ -9Space for diagram notesUMLClass882549486144<<interface>> -score::mw::lifecycle::Application --- -Operation -+ initialize(const ApplicationContext&): std::int32_t virtual = 0 -+ run(amp::stop_token stop_token): std::int32_t virtual = 0UMLClass171855486135score::mw::lifecycle::ApplicationContext --- -Operations -+ ApplicationContext(const int32_t argc, const score::StringLiteral argv[]) -+ get_arguments(): const std::vector<std::string>& const noexcept -+ get_argument(const amp::string_view flag): std::string const noexcept --- -Atrribuite -+ m_args: std::vector<std::string> -+ m_app_path: std::string -UMLClass873189495252score::mw::lifecycle::LifecycleManager --- -operations -+ LifecycleManager(std::unique_ptr<score::os::Signal> signal_interface) - -+ LifeCycleManager(LifeCycleManager&& other) = delete; -+ LifeCycleManager(const LifeCycleManager& other) = delete; -+ LifeCycleManager& operator=(LifeCycleManager&& other) = delete; -+ LifeCycleManager& operator=(const LifeCycleManager& other) = delete; - -+ run(Application& app, const ApplicationContext&): int32_t --- -Attribute -+ m_stop_source: amp::stop_source -+ m_app: Application* -+ m_signal_set: sigset_t -+ m_signal_handler_thread: std::thread -+ signal_: std::unique_ptr<score::os::Signal> UMLNote7290441126Note --- -Implementation is platform specific. It typically implements -a (POSIX) signal handling as we expect, that termination of apps is -done via signaling in all environments.Relation9541175490lt=<-40;80;10;10Relation108043272135lt=<- -manages10;130;10;10UMLClass1539396441180template=ApplicationType -Run --- -Operation -+ Run(const int32_t argc, const score::StringLiteral* argv) -+ AsPosixProcess(Args&&... args): std::int32_t const - --- -Attribute -+ context_: ApplicationContextRelation135940519845lt=<- -Create & -Run10;20;200;20Relation135954019836lt=<- -Create10;20;200;20UMLNote165662132463Note --- -Enable the easy usage of our application in different -environmentsRelation17555672772lt=<-10;10;10;60UMLClass0549783198score::mw::lifecycle::AasApplicationContainer --- -operation -+ initialize(const ApplicationContext&): std::int32_t override -+ run(amp::stop_token stop_token): std::int32_t override -+ AasApplicationContainer(cosnt std::int32_t argc, const score::StringLiteral* argv, const std::size_t count_expected_applications): noexcept -+ With<App,...Args>(Args&&.. args) : AasApplicationContainer& -+ Launch() : std::int32_t --- -Atrribuite -+ context_: score::mw::lifecycle::ApplicationContext -+ applications_: std::vector<std::unique_ptr<Application>> -+ count_expected_applications_: std::size_tRelation77457612636lt=<<- -Implements120;20;10;20Relation576369315198lt=<- -Create & -Run -330;20;10;20;10;200Relation39673827135lt=<<<<- -10;10;10;130