Skip to content

Commit f040ca3

Browse files
committed
feat(tools-api): add lightweight package mode support
- Introduced support for lightweight package mode in the Tools API. - The API now respects the `DDS_LIGHTWEIGHT_PACKAGE` environment variable, allowing for smaller worker packages (~50KB) without binaries. - Updated `CSession` and `SSubmitRequestData` to automatically enable lightweight mode based on the environment variable. - Fixed logic in `DDSWorker.sh` to handle both full and lightweight package deployments correctly. - Added tests to verify the behavior of the lightweight mode. Refs: https://its.cern.ch/jira/browse/EPN-566
1 parent f261faa commit f040ca3

8 files changed

Lines changed: 279 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
10+
### Added
11+
12+
- **dds-tools-lib**: Tools API now respects `DDS_LIGHTWEIGHT_PACKAGE` environment variable. When set, both `CSession::create()` and `SSubmitRequestData` constructor automatically enable lightweight mode.
13+
14+
### Fixed
15+
16+
- **DDSWorker.sh**: Fixed inverted logic bug that caused worker package deployment to fail when pre-compiled binaries were present. The script now correctly handles both full packages (with binaries) and lightweight packages (without binaries).
17+
818
## [3.15.0] - 2025-10-08
919

1020
### Added

ReleaseNotes.md

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,65 @@
11
# Release Notes
22

3+
## [Unreleased]
4+
5+
### 🎉 New Features
6+
7+
#### Tools API Environment Variable Support
8+
9+
- **Automatic Lightweight Mode**: Tools API now automatically detects and respects the `DDS_LIGHTWEIGHT_PACKAGE` environment variable
10+
- **No More `make wn_bin`**: When using lightweight mode, you no longer need to build the worker binary package with `make wn_bin` - a huge time saver!
11+
- **Simplified API Usage**: Users no longer need to manually set the `enable_lightweight` flag when the environment variable is set
12+
- **Consistent Behavior**: Tools API now behaves consistently with command-line tools (`dds-session` and `dds-submit`)
13+
- **Smaller Packages**: Worker packages reduced from ~15MB to ~50KB in lightweight mode
14+
15+
### 🐛 Bug Fixes
16+
17+
#### Critical Worker Package Deployment Fix
18+
19+
- **DDSWorker.sh Logic Error**: Fixed inverted logic bug that caused worker package deployment to fail when pre-compiled binaries were present
20+
- **Impact**: This bug prevented users from deploying full worker packages (with binaries) even though the binaries were correctly packaged
21+
- **Resolution**: The script now correctly:
22+
- Extracts and uses binaries when they exist (full package mode)
23+
- Validates lightweight mode requirements when binaries are absent (lightweight package mode)
24+
25+
### 🚀 For Users
26+
27+
#### If You Use Tools API
28+
29+
Before this fix, you had to explicitly set the lightweight flag:
30+
31+
```cpp
32+
submitInfo.setFlag(SSubmitRequestData::ESubmitRequestFlags::enable_lightweight, true);
33+
```
34+
35+
Now, simply set the environment variable before running your application:
36+
37+
```bash
38+
export DDS_LIGHTWEIGHT_PACKAGE=1
39+
./my_dds_app
40+
```
41+
42+
The Tools API will automatically:
43+
44+
- Start sessions with `--lightweight` flag
45+
- Configure submit requests for lightweight mode
46+
47+
#### If You Experienced Worker Package Failures
48+
49+
If you previously encountered errors like:
50+
51+
```text
52+
Error: Can't find WN pre-compiled bin.: /path/to/dds-wrk-bin-3.14-Linux-x86_64.tar.gz
53+
```
54+
55+
This was caused by the DDSWorker.sh bug and is now fixed. Your worker packages will deploy correctly regardless of whether they contain pre-compiled binaries or are in lightweight mode.
56+
57+
### 📝 Complete Changelog
58+
59+
For a complete list of all changes, see [CHANGELOG.md](CHANGELOG.md).
60+
61+
---
62+
363
## [3.15.0] - 2025-10-08
464

565
### 🎉 New Features
@@ -79,4 +139,4 @@ For a complete list of all changes, see [CHANGELOG.md](CHANGELOG.md).
79139

80140
### 📋 Known Issues
81141

82-
See [GitHub Issues](https://github.com/FairRootGroup/DDS/issues) for current known issues.
142+
See [GitHub Issues](https://github.com/FairRootGroup/DDS/issues) for current known issues.

dds-tools-lib/README.md

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,41 @@ int main()
332332
}
333333
```
334334

335+
## Lightweight Package Mode
336+
337+
The Tools API respects the `DDS_LIGHTWEIGHT_PACKAGE` environment variable. When set to `1`, `true`, `yes`, or `on` (case-insensitive), DDS creates minimal worker packages (~50KB) without binaries.
338+
339+
**Benefits:**
340+
- **No need to build `make wn_bin` target** - Eliminates the worker binary compilation step
341+
- Significantly smaller worker packages (~50KB vs ~15MB)
342+
- Faster deployment to worker nodes
343+
344+
**Using environment variable:**
345+
```cpp
346+
// Set environment variable before creating session
347+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "1", 1);
348+
349+
dds::tools_api::CSession session;
350+
session.create(); // Automatically uses lightweight mode
351+
```
352+
353+
**Using explicit flag:**
354+
```cpp
355+
dds::tools_api::CSession session;
356+
357+
dds::tools_api::SSubmitRequestData submitInfo;
358+
submitInfo.m_rms = "localhost";
359+
submitInfo.m_config = "dds-submit.cfg";
360+
submitInfo.m_enable_lightweight = true; // Explicitly enable lightweight mode
361+
362+
session.syncSendRequest<dds::tools_api::SSubmitRequest>(submitInfo, ...);
363+
```
364+
365+
**Prerequisites for lightweight mode:**
366+
- DDS must be pre-installed on worker nodes
367+
- `DDS_COMMANDER_BIN_LOCATION` environment variable must point to DDS binaries directory (e.g., `/opt/dds/bin`)
368+
- `DDS_COMMANDER_LIBS_LOCATION` environment variable must point to DDS libraries directory (e.g., `/opt/dds/lib`)
369+
335370
## Example: Subscribing to Task Done Events
336371

337372
```cpp
@@ -500,4 +535,4 @@ catch (const std::exception& e)
500535
2. Use synchronous requests for simple, one-off operations
501536
3. Use asynchronous requests with callbacks for more complex scenarios or when receiving multiple responses
502537
4. Handle exceptions properly to avoid program crashes
503-
5. Subscribe to message callbacks to receive important notifications from the server
538+
5. Subscribe to message callbacks to receive important notifications from the server

dds-tools-lib/src/Tools.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <chrono>
99
#include <sstream>
1010
// BOOST
11+
#include <boost/algorithm/string.hpp>
1112
#include <boost/any.hpp>
1213
#include <boost/filesystem.hpp>
1314
#if __has_include(<boost/process/v1.hpp>)
@@ -102,6 +103,13 @@ boost::uuids::uuid CSession::create()
102103

103104
stringstream ssCmd;
104105
ssCmd << bp::search_path("dds-session").string() << " start";
106+
107+
// Check environment variable for lightweight mode
108+
if (isLightweightModeEnabledByEnv())
109+
{
110+
ssCmd << " --lightweight";
111+
}
112+
105113
execute(ssCmd.str(), chrono::seconds(g_WAIT_PROCESS_SEC), &sOut, &sErr, &nExitCode);
106114

107115
if (nExitCode != 0 || !sErr.empty())

dds-tools-lib/src/ToolsProtocol.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ constexpr const char* SSubmitRequestData::_protocolTag;
166166

167167
SSubmitRequestData::SSubmitRequestData()
168168
{
169+
// Check environment variable for lightweight mode and set flag automatically
170+
if (isLightweightModeEnabledByEnv())
171+
{
172+
setFlag(ESubmitRequestFlags::enable_lightweight, true);
173+
}
169174
}
170175

171176
SSubmitRequestData::SSubmitRequestData(const boost::property_tree::ptree& _pt)

dds-tools-lib/src/ToolsProtocol.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
// STD
1010
#include <bitset>
1111
#include <chrono>
12+
#include <cstdlib>
1213
#include <ostream>
1314
#include <string>
1415
#include <vector>
1516
// BOOST
17+
#include <boost/algorithm/string.hpp>
1618
#include <boost/property_tree/ptree.hpp>
1719
// DDS
1820
#include "Intercom.h"
@@ -22,6 +24,19 @@ namespace dds
2224
{
2325
namespace tools_api
2426
{
27+
/// \brief Helper function to check DDS_LIGHTWEIGHT_PACKAGE environment variable
28+
inline bool isLightweightModeEnabledByEnv()
29+
{
30+
const char* envLightweight = std::getenv("DDS_LIGHTWEIGHT_PACKAGE");
31+
if (envLightweight != nullptr)
32+
{
33+
std::string envValue(envLightweight);
34+
boost::algorithm::to_lower(envValue);
35+
return (envValue == "1" || envValue == "true" || envValue == "yes" || envValue == "on");
36+
}
37+
return false;
38+
}
39+
2540
/// \brief Structure holds information of a done response.
2641
DDS_TOOLS_DECLARE_DATA_CLASS(SBaseResponseData, SDoneResponseData, "done")
2742

dds-tools-lib/tests/TestProtocol.cpp

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,4 +290,140 @@ BOOST_AUTO_TEST_CASE(test_dds_tools_protocol_submit_response)
290290
BOOST_CHECK_EQUAL(data.m_jobIDs[2], "125.job");
291291
}
292292

293+
BOOST_AUTO_TEST_CASE(test_dds_tools_protocol_lightweight_env_helper)
294+
{
295+
// Test helper function with different environment variable values
296+
297+
// Test with value "1"
298+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "1", 1);
299+
BOOST_CHECK(isLightweightModeEnabledByEnv() == true);
300+
301+
// Test with value "true"
302+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "true", 1);
303+
BOOST_CHECK(isLightweightModeEnabledByEnv() == true);
304+
305+
// Test with value "TRUE" (case insensitive)
306+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "TRUE", 1);
307+
BOOST_CHECK(isLightweightModeEnabledByEnv() == true);
308+
309+
// Test with value "yes"
310+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "yes", 1);
311+
BOOST_CHECK(isLightweightModeEnabledByEnv() == true);
312+
313+
// Test with value "YES" (case insensitive)
314+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "YES", 1);
315+
BOOST_CHECK(isLightweightModeEnabledByEnv() == true);
316+
317+
// Test with value "on"
318+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "on", 1);
319+
BOOST_CHECK(isLightweightModeEnabledByEnv() == true);
320+
321+
// Test with value "ON" (case insensitive)
322+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "ON", 1);
323+
BOOST_CHECK(isLightweightModeEnabledByEnv() == true);
324+
325+
// Test with value "0" (should be false)
326+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "0", 1);
327+
BOOST_CHECK(isLightweightModeEnabledByEnv() == false);
328+
329+
// Test with value "false"
330+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "false", 1);
331+
BOOST_CHECK(isLightweightModeEnabledByEnv() == false);
332+
333+
// Test with value "no"
334+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "no", 1);
335+
BOOST_CHECK(isLightweightModeEnabledByEnv() == false);
336+
337+
// Test with invalid value
338+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "invalid", 1);
339+
BOOST_CHECK(isLightweightModeEnabledByEnv() == false);
340+
341+
// Test with empty value
342+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "", 1);
343+
BOOST_CHECK(isLightweightModeEnabledByEnv() == false);
344+
345+
// Test with unset variable
346+
unsetenv("DDS_LIGHTWEIGHT_PACKAGE");
347+
BOOST_CHECK(isLightweightModeEnabledByEnv() == false);
348+
}
349+
350+
BOOST_AUTO_TEST_CASE(test_dds_tools_protocol_submit_request_env_lightweight)
351+
{
352+
// Test that SSubmitRequestData constructor respects DDS_LIGHTWEIGHT_PACKAGE
353+
354+
// Test with environment variable set to "1"
355+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "1", 1);
356+
{
357+
SSubmitRequestData data;
358+
BOOST_CHECK(data.isFlagEnabled(SSubmitRequestData::ESubmitRequestFlags::enable_lightweight) == true);
359+
}
360+
361+
// Test with environment variable set to "true"
362+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "true", 1);
363+
{
364+
SSubmitRequestData data;
365+
BOOST_CHECK(data.isFlagEnabled(SSubmitRequestData::ESubmitRequestFlags::enable_lightweight) == true);
366+
}
367+
368+
// Test with environment variable unset
369+
unsetenv("DDS_LIGHTWEIGHT_PACKAGE");
370+
{
371+
SSubmitRequestData data;
372+
BOOST_CHECK(data.isFlagEnabled(SSubmitRequestData::ESubmitRequestFlags::enable_lightweight) == false);
373+
}
374+
375+
// Test that explicit flag setting overrides environment variable
376+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "1", 1);
377+
{
378+
SSubmitRequestData data;
379+
// First check it's enabled by env
380+
BOOST_CHECK(data.isFlagEnabled(SSubmitRequestData::ESubmitRequestFlags::enable_lightweight) == true);
381+
382+
// Now explicitly disable it
383+
data.setFlag(SSubmitRequestData::ESubmitRequestFlags::enable_lightweight, false);
384+
BOOST_CHECK(data.isFlagEnabled(SSubmitRequestData::ESubmitRequestFlags::enable_lightweight) == false);
385+
386+
// And enable it again
387+
data.setFlag(SSubmitRequestData::ESubmitRequestFlags::enable_lightweight, true);
388+
BOOST_CHECK(data.isFlagEnabled(SSubmitRequestData::ESubmitRequestFlags::enable_lightweight) == true);
389+
}
390+
391+
// Clean up
392+
unsetenv("DDS_LIGHTWEIGHT_PACKAGE");
393+
}
394+
395+
BOOST_AUTO_TEST_CASE(test_dds_tools_protocol_submit_request_serialization_with_lightweight)
396+
{
397+
// Test that lightweight flag is properly serialized/deserialized
398+
399+
setenv("DDS_LIGHTWEIGHT_PACKAGE", "1", 1);
400+
{
401+
SSubmitRequestData dataTest;
402+
dataTest.m_rms = "slurm";
403+
dataTest.m_instances = 10;
404+
dataTest.m_slots = 32;
405+
dataTest.m_config = "/path/to/config";
406+
dataTest.m_pluginPath = "/path/to/plugin";
407+
dataTest.m_requestID = 456;
408+
// Flag should already be set by constructor due to environment variable
409+
410+
BOOST_CHECK(dataTest.isFlagEnabled(SSubmitRequestData::ESubmitRequestFlags::enable_lightweight) == true);
411+
412+
// Serialize to JSON and back
413+
stringstream strBuf(dataTest.toJSON());
414+
415+
ptree pt;
416+
read_json(strBuf, pt);
417+
const ptree& childPT = pt.get_child("dds.tools-api.submit");
418+
419+
SSubmitRequestData data(childPT);
420+
421+
BOOST_CHECK(data == dataTest);
422+
BOOST_CHECK(data.isFlagEnabled(SSubmitRequestData::ESubmitRequestFlags::enable_lightweight) == true);
423+
}
424+
425+
// Clean up
426+
unsetenv("DDS_LIGHTWEIGHT_PACKAGE");
427+
}
428+
293429
BOOST_AUTO_TEST_SUITE_END()

etc/DDSWorker.sh.in

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,14 @@ LIGHTWEIGHT_PKG=""
253253
# use pre-compiled binaries from the worker package
254254
# ***** prepare pre-compiled wn binaries *****
255255
WN_BIN_ARC="$WD/$BASE_NAME-$PKG_VERSION-$OS-$host_arch.tar.gz"
256-
if [ ! -f "$WN_BIN_ARC" ]; then
257-
# Checking for a lightweight package
256+
if [ -f "$WN_BIN_ARC" ]; then
257+
# Binary archive exists - use full package mode
258+
logMsg "Found pre-compiled binary archive: $WN_BIN_ARC"
259+
logMsg "Extracting binaries..."
260+
# un-tar without creating a sub-directory
261+
tar --strip-components=1 -xzf $WN_BIN_ARC || clean_up 1
262+
else
263+
# Binary archive doesn't exist - check for lightweight package mode
258264
logMsg "Worker package is in lightweight mode. Validating environment..."
259265

260266
# Validate DDS_COMMANDER_BIN_LOCATION
@@ -294,14 +300,6 @@ if [ ! -f "$WN_BIN_ARC" ]; then
294300
DDS_BINARIES_LOCATION=$DDS_COMMANDER_BIN_LOCATION
295301
DDS_LIBS_LOCATION=$DDS_COMMANDER_LIBS_LOCATION
296302
LIGHTWEIGHT_PKG="YES"
297-
else
298-
logMsg "Error: Can't find WN pre-compiled bin.: $WN_BIN_ARC"
299-
clean_up 1
300-
fi
301-
302-
# un-tar without creating a sub-directory
303-
if [ -z "$LIGHTWEIGHT_PKG" ]; then
304-
tar --strip-components=1 -xzf $WN_BIN_ARC || clean_up 1
305303
fi
306304

307305
export PATH=$DDS_BINARIES_LOCATION:$PATH

0 commit comments

Comments
 (0)