Integration#
Configuration#
The Launch Manager is currently configured with a single json file. See Configuration and Configuration examples for details about the Launch Manager configuration format.
Generating flatbuffer file#
The json configuration has to be converted to a flatbuffer file before it can be used by the Launch Manager.
The provided bazel function launch_manager_config handles the compilation
of the json configuration to flatbuffer files.
load("@score_lifecycle//:defs.bzl", "launch_manager_config")
# This is your launch manager json configuration
exports_files(["lm_config.json"])
# Afterwards, you can refer to the generated flatbuffer files with :example_config_gen
# The generated flatbuffer file has identical as the json configuration file, but with ".bin" file ending (example: "lm_config.bin")
launch_manager_config(
name ="example_config_gen",
config="//scripts/config_mapping:lm_config.json"
)
Location of the configuration file#
The Launch Manager can be started with a CLI flag defining the absolute or relative path to the configuration file:
launch_manager -c <config path>
Example: launch_manager -c /opt/launch_manager/etc/lm_config.bin
If -c is not specified, the Launch Manager will attempt to load the
configuration from the default path etc/launch_manager_config.bin.
State manager mw::com config#
An example mw::com config is provided with the following target
//score/launch_manager:example_com_config.
This is a single config that includes both Launch Manager and the
State Manager instance definition so they can be used by both.
For more information about the mw::com configuraiton please refer
to their documentation and tutorial at documentaiton
https://eclipse-score.github.io/communication/v0.5.0/score/mw/com/doc/tutorial/chapter_2/README.html#separate-configuration-files-for-provider-and-consumer
LmControlService service type#
LmControlService service type
"serviceTypes": [
{
"serviceTypeName": "/score/mw/lifecycle/LmControlService",
"version": {
"major": 1,
"minor": 0
},
"bindings": [
{
"binding": "SHM",
"serviceId": 1,
"events": [
{
"eventName": "ActivationResult",
"eventId": 1
}
],
"methods": [
{
"methodName": "ActivateRunTarget",
"methodId": 2
},
{
"methodName": "GetActiveRunTarget",
"methodId": 3
}
]
}
]
}
]
Implementation#
Starting a process#
A reporting process must signal to the Launch Manager that it has started successfully by calling the lifecycle API for the language it is implemented in.
A ready_timeout_ms can be configured for each component.
If the process does not report Running within that timeout, the Launch
Manager terminates the process and registers an error.
Stopping a process#
A process can be configured to terminate in 2 ways:
Self-terminating - The process terminates whenever it wants.
Non-self-terminating - The process remains alive until LCM requests the process to end using a
SIGTERMsignal.
For a process to support being terminated by LCM, it needs to respond to
a SIGTERM signal by ending ongoing tasks, freeing resources and
exiting.
If a process does not terminate after receiving a SIGTERM, and a
shutdown_timeout_ms is configured, then after the timeout is fired a
SIGKILL is sent and the process is forcefully terminated.
Examples#
C Reporting Process
/********************************************************************************
* 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
********************************************************************************/
#include "score/mw/lifecycle/report_running.h"
#include <unistd.h>
#include <stdio.h>
int main(int argc, char* argv[]){
// report running
int8_t result = score_mw_lifecycle_report_running();
// check report was successful
if(result != 0){
printf("Failed to report kRunning to LCM! Terminating");
return 1;
}
return 0;
}
C++ Reporting Process
/********************************************************************************
* 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
********************************************************************************/
#include <unistd.h>
#include <atomic>
#include <csignal>
#include <cstdlib>
#include <iostream>
#include <score/mw/lifecycle/report_running.h>
volatile std::sig_atomic_t exitRequested{0};
void sigTermHandler(int)
{
exitRequested = 1;
}
int main(int argc, char* argv[])
{
// register signal handler so that lcm can request a termination
signal(SIGTERM, sigTermHandler);
// report running state
score::mw::lifecycle::report_running();
// do some work
// wait until lm wants to terminate
while (exitRequested == 0)
{
pause();
}
return EXIT_SUCCESS;
}
Rust Reporting Process
// *******************************************************************************
// 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
// *******************************************************************************
fn main() -> Result<(), &'static str> {
// report running and check result
if !lifecycle_client_rs::report_running() {
return Err("Failed to report execution state");
}
// do work
Ok(())
}
C++ also contains an alternative Lifecycle API that allows the user to create have a layer of abstraction, so in case of replacing lifecycle manager there will be no need to change applications.
C++ Lifecycle Application
/********************************************************************************
* 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
********************************************************************************/
#include <cstdlib>
#include <score/mw/lifecycle/application.h>
#include <score/mw/lifecycle/runapplication.h>
class LifecycleApp final : public score::mw::lifecycle::Application
{
public:
// called before the process reports Running to the Launch Manager
std::int32_t Initialize(const score::mw::lifecycle::ApplicationContext& appCtx) override
{
// read arguments and set up resources here
return EXIT_SUCCESS;
}
// called once initialization succeeded, returns when termination is requested
std::int32_t Run(const score::cpp::stop_token& stopToken) override
{
while (!stopToken.stop_requested())
{
// do some work
}
return EXIT_SUCCESS;
}
};
int main(int argc, char** argv)
{
return score::mw::lifecycle::run_application<LifecycleApp>(argc, argv);
}
State management#
A State Manager is an application that dictates which run-targets shall be
active by communicating with the Launch Manager using the ILmControl
interface.
The State Manager is itself a managed component and must report
Running to the Launch Manager using the lifecycle API before calling
activate_run_target, otherwise Launch Manager does not consider the State
Manager ready and will cause errors.
The configuration also requires that the component that is the State Manager has
to have the field application_profile.application_type set to
State_Manager.
Example#
State Manager example
/********************************************************************************
* 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
********************************************************************************/
#include <score/mw/lifecycle/ilm_control.hpp>
#include <score/mw/lifecycle/report_running.h>
#include <unistd.h>
#include <atomic>
#include <cassert>
#include <csignal>
#include <iostream>
std::atomic<bool> exitRequested{false};
void signalHandler(int signal)
{
exitRequested = true;
}
int main()
{
// register signal handler and assert success
assert(signal(SIGINT, signalHandler));
assert(signal(SIGTERM, signalHandler));
// report running to LM
score::mw::lifecycle::report_running();
// create a client
auto client_result = score::mw::lifecycle::ILmControl::Create("StateManager/LaunchManager/Instance");
if (!client_result.has_value())
{
std::cerr << "Failed to create client " << client_result.error() << std::endl;
return EXIT_FAILURE;
}
// get the client from the result
std::unique_ptr<score::mw::lifecycle::ILmControl> client = std::move(client_result).value();
// register a method that gets called when a run target is switched
const auto register_result = client->register_run_target_activation_callback(
[]([[maybe_unused]] score::mw::lifecycle::RunTargetActivationSource source,
score::mw::lifecycle::RunTargetName target) {
std::cout << "Successfully activated Run Target " << target << std::endl;
});
if (!register_result.has_value())
{
std::cerr << "Failed to register activation callback " << register_result.error() << std::endl;
return EXIT_FAILURE;
}
// activate a different run target
const auto result = client->activate_run_target(score::mw::lifecycle::RunTargetName{"Running"}, true);
if (result.has_value())
{
std::cerr << "Successfully requested Run Target " << std::endl;
}
else
{
std::cerr << "Requesting Run Target "
<< " failed with error: " << result.error().Message() << std::endl;
}
// pause until LM tells us to terminate
::pause();
return EXIT_SUCCESS;
}