Skip to content

Fix/small fixes#15

Merged
YunaBraska merged 25 commits intomainfrom
fix/small_fixes
Nov 9, 2025
Merged

Fix/small fixes#15
YunaBraska merged 25 commits intomainfrom
fix/small_fixes

Conversation

@YunaBraska
Copy link
Copy Markdown
Contributor

@YunaBraska YunaBraska commented Sep 30, 2025

Closes #8

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Motivation

The project had fragmented config logic, spring-specific heuristics, and partial support for newer Java features like virtual threads.
This PR unifies and modernizes key systems: configuration, threading, service infrastructure, and documentation — improving stability, readability, and future compatibility.

Changes

1. Configuration / Profile System

  • Refactored how profiles are discovered and loaded across CLI, system properties, env, and config files.
  • Removed legacy Spring-only heuristics from NanoBase.
  • Unified support for multiple profile key formats (spring.profiles.active, app.profiles, micronaut.environments, etc.).
  • Defined strict override precedence: CLI > System Props > Env > Files.
  • Rewrote placeholder resolution to be recursive-safe, with default fallbacks.
  • Extended and stabilized NanoConfigLoadingTest to cover discovery, precedence, and placeholder chains.

2. Threading & Scheduler

  • Added support for virtual threads and improved thread management within the scheduler.
  • Simplified and optimized thread lifecycle logic for Java 21+ environments.
  • Improved compatibility with older JVMs and service-based thread models.

3. Services & Eventing

  • Enhanced FileWatcher with group-based watching and automatic refresh logic.
  • Improved EVENT_CONFIG_CHANGE behavior for reliable propagation and reactivity.
  • Aligned service initialization with new threading and config systems.
  • Expanded HttpServer regression coverage to prove TLS reload success, failure on invalid cert/key updates, and FileWatcher-triggered refreshes.

4. Documentation & Examples

  • Updated README, CLAUDE.md, and service documentation for better contributor guidance.
  • Added architecture notes on event flow and config overrides.
  • Clarified examples showing config discovery and dynamic reloads.
  • Documented HttpServer TLS hot-reload behavior and added a Context guide on how FileWatcher-driven EVENT_CONFIG_CHANGE keeps configs fresh.

5. Testing & Reliability

  • Reworked tests for determinism and parallel safety.
  • Removed flaky cases and improved test isolation and cleanup.
  • Added tests covering nested placeholder resolution, multi-profile discovery, and overlay order.

Success Check

Validate via CI or local tests:

  • All tests (NanoConfigLoadingTest, NanoSchedulerTest, FileWatcherTest) pass.
  • Config precedence and placeholder resolution behave as expected.
  • Virtual-thread scheduler and grouped file watcher operate correctly.
  • EVENT_CONFIG_CHANGE events broadcast consistently.
  • Documentation and examples build without errors.

YunaBraska and others added 7 commits September 23, 2025 13:16
Resolves config loading limitations where profiles were only read from
application.properties, preventing flexible configuration in deployment environments.

**Core Changes:**
- Simplified profile resolution logic in NanoUtils.readProfiles() (70→25 lines)
- Fixed profile loading order: app_profile → CONFIG_PROFILES → spring → micronaut → generic
- Removed complex Spring external detection logic from NanoBase.java
- Added proper CLI args and system properties profile support

**Framework Compatibility:**
- ✅ Spring: spring.profiles.active, spring_profiles_active
- ✅ Micronaut: micronaut.environments, micronaut_profiles
- ✅ Generic: profiles.active, profiles_active
- ✅ Nano: app.profiles, app_profiles, app.profile

**Testing Improvements:**
- Added @execution(ExecutionMode.SAME_THREAD) to prevent test race conditions
- Expanded test coverage from 6 to 10 tests with comprehensive edge cases
- Removed text block syntax incompatible with older Java versions
- Enhanced test isolation and cleanup procedures

**Precedence Order (Now Working):**
CLI args > System Properties > Environment Variables > Config Files

**Verified Fix:**
- ✅ `export SPRING_PROFILES_ACTIVE=dev,prod` now works
- ✅ `--app.profiles=local,staging` now works
- ✅ `-Dspring.profiles.active=test` now works
- ✅ Mixed sources with correct priority now work

Closes: Profile loading from external sources not supported
Tests: 10/10 config tests passing, all main tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
**Test Improvements:**
- Removed unused SHORT_AWAIT_MS constant from NanoSchedulerTest
- Standardized timeout usage to TEST_TIMEOUT for consistency
- Fixed indentation and formatting in NanoTest
- Moved configFilesTest from NanoTest to NanoConfigLoadingTest (better organization)
- Removed unused imports and variables

**Code Quality:**
- Enhanced test isolation and reliability
- Better test organization by moving config-specific tests to config test class
- Consistent formatting and style improvements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…cle management

Resolves scheduler thread management issues where schedulers weren't using virtual threads
consistently and Nano was terminating immediately after startup due to lack of non-daemon threads.

**Core Changes:**
- ✅ Scheduler now uses GLOBAL_THREAD_FACTORY for consistent virtual thread usage
- ✅ Added per-instance keep-alive thread in NanoThreads constructor to prevent JVM exit
- ✅ Simplified thread naming with NANO_THREAD_PREFIX constant
- ✅ Added proper shutdown hook for keep-alive thread interruption

**Thread Management:**
- Scheduler extends ScheduledThreadPoolExecutor with virtual thread factory
- Keep-alive thread runs Thread.sleep(Long.MAX_VALUE) as non-daemon thread
- Graceful shutdown interrupts keep-alive thread during application shutdown
- Thread-safe implementation without complex atomic operations

**Performance Benefits:**
- ✅ All schedulers now use lightweight virtual threads instead of platform threads
- ✅ Consistent thread naming: "nano-thread-" prefixed virtual threads
- ✅ Minimal memory footprint with single keep-alive thread per Nano instance
- ✅ JVM stays alive properly until explicit shutdown

**Verified Fix:**
- ✅ 1280+ scheduler tests passing with virtual thread implementation
- ✅ Application no longer exits immediately after startup
- ✅ Proper graceful shutdown with thread cleanup
- ✅ Virtual thread performance benefits realized

Closes: Scheduler virtual thread inconsistency and immediate JVM exit
Tests: All scheduler and main Nano tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…event acknowledgment

Addresses EVENT_CONFIG_CHANGE reliability issues by providing comprehensive user guidance
instead of framework-level exceptions, maintaining clean architecture principles.

**Documentation Updates:**
- ✅ Added detailed best practices section in `/docs/events/README.md`
- ✅ Clear examples of what NOT to do (acknowledging config events)
- ✅ Clear examples of recommended approach (use payload() without acknowledgment)
- ✅ Alternative solution: use broadcast(true) when sending if acknowledgment needed
- ✅ Added warning link in `/docs/context/README.md` EVENT_CONFIG_CHANGE table entry
- ✅ Enhanced `Event.acknowledge()` javadocs with propagation warning

**Code Improvements:**
- ✅ Fixed NanoBase.java to not acknowledge EVENT_CONFIG_CHANGE (line 74)
- ✅ Minor cleanup in Service.java event handling logic
- ✅ Maintains original event dispatch behavior without special exceptions

**Why This Approach:**
- Clean Design: No hard-coded exceptions for specific event types
- User Education: Comprehensive documentation with clear examples
- Performance: No additional runtime checks or special handling
- Maintainable: Simple, consistent event handling across all event types

**User Guidance:**
- Configuration changes need to reach all services simultaneously
- Database connections, caches, HTTP clients all need config updates
- Acknowledgment stops propagation, causing inconsistent configuration states
- Solution: Use payload() instead of payloadAck() for config events

Resolves: EVENT_CONFIG_CHANGE not reliably broadcast to multiple listeners
Tests: All existing tests continue to pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…omatic config reloading

Transforms FileWatcher into a generic, reusable service with comprehensive file system monitoring
capabilities and automatic EVENT_CONFIG_CHANGE triggering for configuration files.

**Core Enhancements:**
- ✅ Group-based file watching for multi-component reusability
- ✅ Automatic EVENT_CONFIG_CHANGE triggering for application.properties files
- ✅ Thread-safe concurrency with ReentrantReadWriteLock
- ✅ Duplicate prevention with intelligent path deduplication
- ✅ Clean group removal without affecting overlapping groups

**New API Features:**
- EVENT_WATCH_GROUP/EVENT_UNWATCH_GROUP for group-based operations
- CONFIG_CHANGE_GROUP constant for automatic config file monitoring
- getWatchedGroups()/getGroupPaths() for introspection
- Enhanced processFileEvent() with group-specific handling

**Automatic Config Integration:**
- Monitors config/, resources/, .config/ directories automatically
- Parses changed config files and triggers EVENT_CONFIG_CHANGE
- Provides normalized config keys (dot, underscore, uppercase variants)
- Broadcasts config changes to ensure all listeners receive updates

**Concurrency & Performance:**
- Thread-safe group registration/unregistration
- Efficient duplicate path detection
- Handles overlapping groups correctly
- Minimal memory footprint with concurrent data structures

**Comprehensive Testing:**
- 10 test scenarios covering all functionality
- Group-based watching tests with concurrent operations
- Config change trigger verification
- Multi-group overlap and cleanup testing
- Concurrency stress testing with 10 parallel operations

**Documentation:**
- Complete FileWatcher service documentation
- Usage examples for HttpServer certificate reloading
- Kubernetes ConfigMap integration patterns
- Best practices and troubleshooting guide

**Use Cases Enabled:**
- Automatic config reloading without application restart
- SSL certificate hot-swapping for HttpServer/HttpClient
- Multi-environment configuration watching
- Kubernetes ConfigMap/Secret monitoring
- Resource file change detection

**Backward Compatibility:**
- Legacy EVENT_WATCH_FILE/EVENT_UNWATCH_FILE still supported
- Existing file watching behavior unchanged
- All existing tests continue to pass

Resolves: FileWatcher integration for automatic EVENT_CONFIG_CHANGE triggering
Tests: 10/10 FileWatcher tests passing, all main framework tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@YunaBraska YunaBraska force-pushed the main branch 15 times, most recently from 13ab956 to e7dae1f Compare October 2, 2025 09:55
@YunaBraska YunaBraska merged commit 3473245 into main Nov 9, 2025
1 check passed
@YunaBraska YunaBraska deleted the fix/small_fixes branch November 9, 2025 10:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Config change event mishandling

1 participant