feat(plugin_loader): Phase 134 P0 - Best-effort plugin loading (continue on failures)
This commit is contained in:
@ -11,12 +11,50 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
pub(super) fn load_all_plugins(loader: &PluginLoaderV2) -> BidResult<()> {
|
pub(super) fn load_all_plugins(loader: &PluginLoaderV2) -> BidResult<()> {
|
||||||
let config = loader.config.as_ref().ok_or(BidError::PluginError)?;
|
let config = loader.config.as_ref().ok_or(BidError::PluginError)?;
|
||||||
for (lib_name, lib_def) in &config.libraries {
|
|
||||||
load_plugin(loader, lib_name, lib_def)?;
|
// Phase 134 P0: Best-effort loading
|
||||||
|
// Failures don't stop the entire load process
|
||||||
|
let mut loaded_count = 0;
|
||||||
|
let mut failed_count = 0;
|
||||||
|
|
||||||
|
// Load libraries in deterministic order (sorted by name)
|
||||||
|
let mut lib_items: Vec<_> = config.libraries.iter().collect();
|
||||||
|
lib_items.sort_by_key(|(name, _)| *name);
|
||||||
|
|
||||||
|
for (lib_name, lib_def) in lib_items {
|
||||||
|
match load_plugin(loader, lib_name, lib_def) {
|
||||||
|
Ok(()) => loaded_count += 1,
|
||||||
|
Err(_) => {
|
||||||
|
failed_count += 1;
|
||||||
|
// Log already printed by load_plugin, continue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (plugin_name, root) in &config.plugins {
|
|
||||||
load_plugin_from_root(loader, plugin_name, root)?;
|
// Load plugins in deterministic order (sorted by name)
|
||||||
|
let mut plugin_items: Vec<_> = config.plugins.iter().collect();
|
||||||
|
plugin_items.sort_by_key(|(name, _)| *name);
|
||||||
|
|
||||||
|
for (plugin_name, root) in plugin_items {
|
||||||
|
match load_plugin_from_root(loader, plugin_name, root) {
|
||||||
|
Ok(()) => loaded_count += 1,
|
||||||
|
Err(_) => {
|
||||||
|
failed_count += 1;
|
||||||
|
// Log already printed by load_plugin_from_root, continue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Phase 134 P0: Log summary
|
||||||
|
if failed_count > 0 {
|
||||||
|
get_global_ring0().log.warn(&format!(
|
||||||
|
"[plugin/init] loaded {} plugins, {} failed",
|
||||||
|
loaded_count, failed_count
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continue with singleton prebirth even if some plugins failed
|
||||||
|
// This follows "fail gracefully" principle: partially working state is better than complete failure
|
||||||
super::singletons::prebirth_singletons(loader)?;
|
super::singletons::prebirth_singletons(loader)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,55 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Phase 134 P0: Plugin best-effort loading smoke test
|
||||||
|
# Tests: Even with plugin failures, plugins are not disabled entirely
|
||||||
|
# Acceptance: "plugins disabled (config=nyash.toml)" should NOT appear in output
|
||||||
|
|
||||||
|
source "$(dirname "$0")/../../../lib/test_runner.sh"
|
||||||
|
export SMOKES_USE_PYVM=0
|
||||||
|
require_env || exit 2
|
||||||
|
|
||||||
|
mkdir -p "$NYASH_ROOT/tmp"
|
||||||
|
|
||||||
|
PASS_COUNT=0
|
||||||
|
FAIL_COUNT=0
|
||||||
|
|
||||||
|
# ===== Test 1: --dump-mir does not show "plugins disabled" =====
|
||||||
|
echo "[INFO] Phase 134 P0: Checking plugins are NOT disabled on --dump-mir"
|
||||||
|
|
||||||
|
INPUT="$NYASH_ROOT/apps/tests/phase132_return_loop_var_min.hako"
|
||||||
|
|
||||||
|
# Run with --dump-mir and capture output
|
||||||
|
set +e
|
||||||
|
"$NYASH_BIN" --dump-mir "$INPUT" > /tmp/phase134_dump.log 2>&1
|
||||||
|
EXIT_CODE=$?
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Check if "plugins disabled (config=nyash.toml)" appears
|
||||||
|
if grep -q "plugins disabled (config=nyash.toml)" /tmp/phase134_dump.log; then
|
||||||
|
echo "[FAIL] Phase 134 P0: plugins disabled found in output (best-effort failed)"
|
||||||
|
FAIL_COUNT=$((FAIL_COUNT + 1))
|
||||||
|
# Show the problematic line for debugging
|
||||||
|
grep "plugins disabled" /tmp/phase134_dump.log
|
||||||
|
else
|
||||||
|
echo "[PASS] Phase 134 P0: plugins NOT disabled (best-effort loading successful)"
|
||||||
|
PASS_COUNT=$((PASS_COUNT + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ===== Test 2: --dump-mir succeeds with exit code 0 =====
|
||||||
|
echo "[INFO] Phase 134 P0: Checking MIR compilation succeeds"
|
||||||
|
|
||||||
|
if [ "$EXIT_CODE" -eq 0 ]; then
|
||||||
|
echo "[PASS] Phase 134 P0: --dump-mir succeeded (exit code 0)"
|
||||||
|
PASS_COUNT=$((PASS_COUNT + 1))
|
||||||
|
else
|
||||||
|
echo "[FAIL] Phase 134 P0: --dump-mir failed (exit code $EXIT_CODE)"
|
||||||
|
FAIL_COUNT=$((FAIL_COUNT + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ===== Summary =====
|
||||||
|
echo ""
|
||||||
|
echo "[RESULT] Phase 134 P0: $PASS_COUNT passed, $FAIL_COUNT failed"
|
||||||
|
if [ "$FAIL_COUNT" -eq 0 ]; then
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user