Skip to content

Commit 6cb7ef1

Browse files
shegazyyclaude
andcommitted
Replace floating-point seconds with integer milliseconds in timing config
All 8 timing fields in `new_lm_flatcfg.fbs` are changed from `double` (seconds) to `uint32` (milliseconds), eliminating the need for the `secondsToMs()` conversion helper and removing the floating-point representation from the binary format entirely. Changes: - `new_lm_flatcfg.fbs`: 8 timing fields changed from `double` to `uint32` - `flatbuffer_config_loader.hpp`: `kExpectedSchemaVersion` bumped 1 → 2 - `flatbuffer_type_converters.hpp/.cpp`: removed `secondsToMs()` and `kSecondsToMilliseconds`; all 7 call sites simplified to direct assignment - `flatbuffer_type_converters_UT.cpp`: removed 5 `SecondsToMsTest` cases; updated all FlatBuffer builder calls to pass millisecond integers - `flatbuffer_config_loader_UT.cpp`: updated all builder calls likewise - `lifecycle_config.py` (`gen_config`): added `sec_to_ms()` conversion for all 8 timing fields so the generated JSON matches the new uint32 schema - `launch_manager.schema.json`: updated `schema_version` enum from `[1]` to `[2]` - All 20 JSON config files: `"schema_version": 1` → `"schema_version": 2` Closes #345 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 2b82ed2 commit 6cb7ef1

28 files changed

Lines changed: 411 additions & 391 deletions

File tree

‎examples/demo_verification/lifecycle_demo_test.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"schema_version": 1,
2+
"schema_version": 2,
33
"defaults": {
44
"deployment_config": {
55
"bin_dir": "/tmp/tests/examples",

‎score/launch_manager/src/daemon/src/configuration/config_schema/examples/example_conf.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"schema_version": 1,
2+
"schema_version": 2,
33
"defaults": {
44
"deployment_config": {
55
"ready_timeout": 0.5,

‎score/launch_manager/src/daemon/src/configuration/config_schema/launch_manager.schema.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@
373373
"type": "integer",
374374
"description": "Specifies the schema version number that the Launch Manager uses to determine how to parse and validate this configuration file.",
375375
"enum": [
376-
1
376+
2
377377
]
378378
},
379379
"defaults": {

‎score/launch_manager/src/daemon/src/configuration/details/flatbuffer_config_loader_UT.cpp‎

Lines changed: 109 additions & 73 deletions
Large diffs are not rendered by default.

‎score/launch_manager/src/daemon/src/configuration/details/flatbuffer_type_converters.cpp‎

Lines changed: 11 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include <score/assert.hpp>
2222
#include <sys/types.h>
2323
#include <cstdint>
24-
#include <limits>
2524
#include <string>
2625
#include <vector>
2726

@@ -34,8 +33,9 @@ namespace
3433
{
3534

3635
template <typename T>
37-
score::cpp::expected<T, IConfigLoader::Error> requireScalarValue(const ::flatbuffers::Optional<T>& field,
38-
const std::string_view field_name)
36+
score::cpp::expected<T, IConfigLoader::Error> requireScalarValue(
37+
const ::flatbuffers::Optional<T>& field,
38+
const std::string_view field_name)
3939
{
4040
if (!field.has_value())
4141
{
@@ -56,29 +56,6 @@ std::optional<T> optionalScalarValue(const ::flatbuffers::Optional<T>& field)
5656
namespace details
5757
{
5858

59-
constexpr double kSecondsToMilliseconds = 1000.0;
60-
61-
score::cpp::expected<uint32_t, IConfigLoader::Error> secondsToMs(double seconds)
62-
{
63-
if (seconds < 0.0)
64-
{
65-
LM_LOG_ERROR() << "Negative time value " << seconds << " seconds is not supported";
66-
return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat);
67-
}
68-
if (seconds * kSecondsToMilliseconds > static_cast<double>(std::numeric_limits<uint32_t>::max()))
69-
{
70-
LM_LOG_ERROR() << "Time value " << seconds << " seconds exceeds maximum representable milliseconds";
71-
return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat);
72-
}
73-
const auto result = static_cast<uint32_t>(seconds * kSecondsToMilliseconds);
74-
if (seconds > 0.0 && result == 0U)
75-
{
76-
LM_LOG_ERROR() << "Sub-millisecond time value " << seconds << " seconds rounds to 0ms";
77-
return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat);
78-
}
79-
return result;
80-
}
81-
8259
ApplicationType convertApplicationType(fb::ApplicationType fb_type)
8360
{
8461
switch (fb_type)
@@ -202,13 +179,7 @@ score::cpp::expected<std::optional<RestartAction>, IConfigLoader::Error> convert
202179
{
203180
return score::cpp::make_unexpected(delay_before_restart.error());
204181
}
205-
auto delay_ms = secondsToMs(*delay_before_restart);
206-
if (!delay_ms.has_value())
207-
{
208-
LM_LOG_ERROR() << "Invalid value for RestartAction::delay_before_restart";
209-
return score::cpp::make_unexpected(delay_ms.error());
210-
}
211-
return std::optional<RestartAction>{RestartAction{*number_of_attempts, *delay_ms}};
182+
return std::optional<RestartAction>{RestartAction{*number_of_attempts, *delay_before_restart}};
212183
}
213184

214185
std::optional<SwitchRunTargetAction> convertSwitchRunTargetAction(const fb::SwitchRunTargetAction* sa)
@@ -247,13 +218,7 @@ score::cpp::expected<ComponentAliveSupervision, IConfigLoader::Error> convertCom
247218
{
248219
return score::cpp::make_unexpected(failed_cycles_tolerance.error());
249220
}
250-
auto reporting_cycle_ms = secondsToMs(*reporting_cycle);
251-
if (!reporting_cycle_ms.has_value())
252-
{
253-
LM_LOG_ERROR() << "Invalid value for ComponentAliveSupervision::reporting_cycle";
254-
return score::cpp::make_unexpected(reporting_cycle_ms.error());
255-
}
256-
result.reporting_cycle_ms = *reporting_cycle_ms;
221+
result.reporting_cycle_ms = *reporting_cycle;
257222
result.failed_cycles_tolerance = *failed_cycles_tolerance;
258223
result.min_indications = optionalScalarValue(fb_cas->min_indications());
259224
result.max_indications = optionalScalarValue(fb_cas->max_indications());
@@ -428,20 +393,8 @@ score::cpp::expected<DeploymentConfig, IConfigLoader::Error> convertDeploymentCo
428393
{
429394
return score::cpp::make_unexpected(shutdown_timeout.error());
430395
}
431-
auto ready_timeout_ms = secondsToMs(*ready_timeout);
432-
if (!ready_timeout_ms.has_value())
433-
{
434-
LM_LOG_ERROR() << "Invalid value for DeploymentConfig::ready_timeout";
435-
return score::cpp::make_unexpected(ready_timeout_ms.error());
436-
}
437-
auto shutdown_timeout_ms = secondsToMs(*shutdown_timeout);
438-
if (!shutdown_timeout_ms.has_value())
439-
{
440-
LM_LOG_ERROR() << "Invalid value for DeploymentConfig::shutdown_timeout";
441-
return score::cpp::make_unexpected(shutdown_timeout_ms.error());
442-
}
443-
result.ready_timeout_ms = *ready_timeout_ms;
444-
result.shutdown_timeout_ms = *shutdown_timeout_ms;
396+
result.ready_timeout_ms = *ready_timeout;
397+
result.shutdown_timeout_ms = *shutdown_timeout;
445398
result.environmental_variables = convertEnvironmentalVariables(fb_dc->environmental_variables());
446399
result.bin_dir = fb_dc->bin_dir()->str();
447400
result.working_dir = fb_dc->working_dir()->str();
@@ -513,13 +466,7 @@ score::cpp::expected<RunTargetConfig, IConfigLoader::Error> convertRunTarget(con
513466
result.name = fb_rt->name()->str();
514467
result.description = safeString(fb_rt->description());
515468
result.depends_on = convertStringVector(fb_rt->depends_on());
516-
auto transition_timeout_ms = secondsToMs(*transition_timeout);
517-
if (!transition_timeout_ms.has_value())
518-
{
519-
LM_LOG_ERROR() << "Invalid value for RunTarget::transition_timeout";
520-
return score::cpp::make_unexpected(transition_timeout_ms.error());
521-
}
522-
result.transition_timeout_ms = *transition_timeout_ms;
469+
result.transition_timeout_ms = *transition_timeout;
523470
result.recovery_action = convertRequiredSwitchRunTargetAction(fb_rt->recovery_action());
524471
}
525472
return result;
@@ -539,13 +486,7 @@ score::cpp::expected<FallbackRunTargetConfig, IConfigLoader::Error> convertFallb
539486
}
540487
result.description = safeString(fb_frt->description());
541488
result.depends_on = convertStringVector(fb_frt->depends_on());
542-
auto transition_timeout_ms = secondsToMs(*transition_timeout);
543-
if (!transition_timeout_ms.has_value())
544-
{
545-
LM_LOG_ERROR() << "Invalid value for FallbackRunTarget::transition_timeout";
546-
return score::cpp::make_unexpected(transition_timeout_ms.error());
547-
}
548-
result.transition_timeout_ms = *transition_timeout_ms;
489+
result.transition_timeout_ms = *transition_timeout;
549490
}
550491
return result;
551492
}
@@ -562,13 +503,7 @@ score::cpp::expected<AliveSupervisionConfig, IConfigLoader::Error> convertAliveS
562503
{
563504
return score::cpp::make_unexpected(evaluation_cycle.error());
564505
}
565-
auto evaluation_cycle_ms = secondsToMs(*evaluation_cycle);
566-
if (!evaluation_cycle_ms.has_value())
567-
{
568-
LM_LOG_ERROR() << "Invalid value for AliveSupervision::evaluation_cycle";
569-
return score::cpp::make_unexpected(evaluation_cycle_ms.error());
570-
}
571-
return AliveSupervisionConfig{*evaluation_cycle_ms};
506+
return AliveSupervisionConfig{*evaluation_cycle};
572507
}
573508

574509
score::cpp::expected<std::optional<WatchdogConfig>, IConfigLoader::Error> convertWatchdog(const fb::Watchdog* fb_wd)
@@ -597,13 +532,7 @@ score::cpp::expected<std::optional<WatchdogConfig>, IConfigLoader::Error> conver
597532
}
598533
WatchdogConfig result{};
599534
result.device_file_path = fb_wd->device_file_path()->str();
600-
auto max_timeout_ms = secondsToMs(*max_timeout);
601-
if (!max_timeout_ms.has_value())
602-
{
603-
LM_LOG_ERROR() << "Invalid value for Watchdog::max_timeout";
604-
return score::cpp::make_unexpected(max_timeout_ms.error());
605-
}
606-
result.max_timeout_ms = *max_timeout_ms;
535+
result.max_timeout_ms = *max_timeout;
607536
result.deactivate_on_shutdown = *deactivate_on_shutdown;
608537
result.require_magic_close = *require_magic_close;
609538
return std::optional<WatchdogConfig>{std::move(result)};

‎score/launch_manager/src/daemon/src/configuration/details/flatbuffer_type_converters.hpp‎

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,16 @@ namespace details
4040
template <typename TargetT>
4141
score::cpp::expected<TargetT, IConfigLoader::Error> validateRange(int64_t value, const std::string_view field_name)
4242
{
43-
// Asserts ensure that std::numeric_limits<TargetT>::min() and std::numeric_limits<TargetT>::max() can be
43+
// Asserts ensure that std::numeric_limits<TargetT>::min() and std::numeric_limits<TargetT>::max() can be
4444
// safely cast to int64_t for the range check:
4545
// Case 1: TargetT is unsigned and smaller than int64_t, so max fits in int64_t and min is 0
4646
// Case 2: TargetT is signed and smaller than int64_t, so both min and max fit in int64_t
4747
// Case 3: TargetT is signed and exactly int64_t, so min and max are the full int64_t range
4848

4949
static_assert(std::numeric_limits<TargetT>::is_integer, "TargetT must be an integer type");
50-
static_assert(sizeof(TargetT) < sizeof(int64_t) ||
51-
(sizeof(TargetT) == sizeof(int64_t) && std::is_signed_v<TargetT>),
52-
"TargetT max must be representable as int64_t");
50+
static_assert(
51+
sizeof(TargetT) < sizeof(int64_t) || (sizeof(TargetT) == sizeof(int64_t) && std::is_signed_v<TargetT>),
52+
"TargetT max must be representable as int64_t");
5353

5454
if (value < static_cast<int64_t>(std::numeric_limits<TargetT>::min()) ||
5555
value > static_cast<int64_t>(std::numeric_limits<TargetT>::max()))
@@ -63,15 +63,12 @@ score::cpp::expected<TargetT, IConfigLoader::Error> validateRange(int64_t value,
6363

6464
// --- Scalar and enum helpers ---
6565

66-
/// @brief Converts a time value from seconds to milliseconds.
67-
[[nodiscard]] score::cpp::expected<uint32_t, IConfigLoader::Error> secondsToMs(double seconds);
6866
/// @brief Converts a FlatBuffer ApplicationType enum to the config ApplicationType.
6967
[[nodiscard]] ApplicationType convertApplicationType(fb::ApplicationType fb_type);
7068
/// @brief Converts a FlatBuffer ProcessState enum to the config ProcessState.
7169
[[nodiscard]] ProcessState convertProcessState(fb::ProcessState fb_state);
7270
/// @brief Converts a FlatBuffer SchedulingPolicy enum to a POSIX scheduling policy constant.
73-
[[nodiscard]] score::cpp::expected<int32_t, IConfigLoader::Error> convertSchedulingPolicy(
74-
fb::SchedulingPolicy policy);
71+
[[nodiscard]] score::cpp::expected<int32_t, IConfigLoader::Error> convertSchedulingPolicy(fb::SchedulingPolicy policy);
7572

7673
// --- String and vector helpers ---
7774

@@ -93,16 +90,15 @@ score::cpp::expected<TargetT, IConfigLoader::Error> validateRange(int64_t value,
9390
[[nodiscard]] score::cpp::expected<std::optional<RestartAction>, IConfigLoader::Error> convertRestartAction(
9491
const fb::RestartAction* ra);
9592
/// @brief Converts a FlatBuffer SwitchRunTargetAction to a config SwitchRunTargetAction, or nullopt if absent.
96-
[[nodiscard]] std::optional<SwitchRunTargetAction> convertSwitchRunTargetAction(
97-
const fb::SwitchRunTargetAction* sa);
93+
[[nodiscard]] std::optional<SwitchRunTargetAction> convertSwitchRunTargetAction(const fb::SwitchRunTargetAction* sa);
9894
/// @brief Converts a required FlatBuffer SwitchRunTargetAction; asserts if null.
9995
[[nodiscard]] SwitchRunTargetAction convertRequiredSwitchRunTargetAction(const fb::SwitchRunTargetAction* sa);
10096

10197
// --- Component converters ---
10298

10399
/// @brief Converts a FlatBuffer ComponentAliveSupervision to the config equivalent.
104-
[[nodiscard]] score::cpp::expected<ComponentAliveSupervision, IConfigLoader::Error>
105-
convertComponentAliveSupervision(const fb::ComponentAliveSupervision* fb_cas);
100+
[[nodiscard]] score::cpp::expected<ComponentAliveSupervision, IConfigLoader::Error> convertComponentAliveSupervision(
101+
const fb::ComponentAliveSupervision* fb_cas);
106102
/// @brief Converts a FlatBuffer ApplicationProfile to the config equivalent.
107103
[[nodiscard]] score::cpp::expected<ApplicationProfile, IConfigLoader::Error> convertApplicationProfile(
108104
const fb::ApplicationProfile* fb_ap);
@@ -127,8 +123,7 @@ convertComponentAliveSupervision(const fb::ComponentAliveSupervision* fb_cas);
127123
// --- Run target converters ---
128124

129125
/// @brief Converts a single FlatBuffer RunTarget to a RunTargetConfig.
130-
[[nodiscard]] score::cpp::expected<RunTargetConfig, IConfigLoader::Error> convertRunTarget(
131-
const fb::RunTarget* fb_rt);
126+
[[nodiscard]] score::cpp::expected<RunTargetConfig, IConfigLoader::Error> convertRunTarget(const fb::RunTarget* fb_rt);
132127
/// @brief Converts a FlatBuffer FallbackRunTarget to a FallbackRunTargetConfig.
133128
[[nodiscard]] score::cpp::expected<FallbackRunTargetConfig, IConfigLoader::Error> convertFallbackRunTarget(
134129
const fb::FallbackRunTarget* fb_frt);

0 commit comments

Comments
 (0)