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 SIGTERM signal.

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;
}