Skip to content

Обработчик прерывания консольного приложения по Ctrl+C#1512

Merged
EvilBeaver merged 2 commits intodevelopfrom
feature/860-ctrl-c-handler
Feb 21, 2025
Merged

Обработчик прерывания консольного приложения по Ctrl+C#1512
EvilBeaver merged 2 commits intodevelopfrom
feature/860-ctrl-c-handler

Conversation

@EvilBeaver
Copy link
Owner

@EvilBeaver EvilBeaver commented Feb 21, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced Ctrl+C handling in console applications for smoother termination.
    • Introduced a new integration point to access the scripting engine’s service container.
    • Extended the engine configuration process to support streamlined event handler registration.
  • Refactor

    • Simplified event processing logic across background tasks and runtime components.
    • Improved thread safety and dependency resolution for more reliable event handling.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 21, 2025

Walkthrough

The changes update the event processing and dependency injection model across several components. The modifications remove redundant event processor assignments and enforce lazy loading in the machine instance. Enhancements include robust handling of the Ctrl+C console event in the console context, updates to console provider construction, and improved thread safety in event handler registration. Additionally, new extension methods for engine building are added, and a service getter is exposed to enable external access to engine services.

Changes

File(s) Change Summary
src/OneScript.StandardLibrary/Tasks/BackgroundTasksManager.cs, src/ScriptEngine.HostedScript/Process.cs, src/ScriptEngine/Machine/Contexts/UserScriptContextInstance.cs, src/ScriptEngine/Machine/MachineInstance.cs Removed redundant local event processor assignments; replaced direct access with dependency resolution and lazy-loaded, private event processor with error handling.
src/OneScript.StandardLibrary/Text/ConsoleContext.cs, src/OneScript.StandardLibrary/Text/ConsoleProvider.cs Added Ctrl+C key handling in ConsoleContext (event constant, handler, execution context) and updated ConsoleProvider constructor and factory method to require an ExecutionContext.
src/ScriptEngine.HostedScript/DefaultEventProcessor.cs Introduced readonly modifiers and a dedicated subscription lock with locking in AddHandler/RemoveHandler methods for enhanced thread safety in event handling.
src/ScriptEngine.HostedScript/Extensions/EngineBuilderExtensions.cs, src/ScriptEngine.HostedScript/HostedScriptEngine.cs, src/oscript/ConsoleHostBuilder.cs Added a new UseEventHandlers extension method, exposed engine services via a new public property, and updated engine builder chaining to integrate event handlers.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant C as Console
    participant CC as ConsoleContext
    participant EC as ExecutionContext
    participant EP as IEventProcessor

    U->>C: Press Ctrl+C
    C->>CC: Trigger CancelKeyPress event
    CC->>EC: TryResolve(IEventProcessor)
    EC-->>CC: Return EP instance (or null)
    alt EP resolved
        CC->>EP: HandleEvent(cancelRef)
        EP-->>CC: Return cancellation decision
        CC->>C: Set e.Cancel based on decision
    else EP not resolved
        CC->>C: Proceed with default cancellation
    end
Loading

Poem

Oh, what a hop, what a bound,
In code where clarity’s found,
With events now safe and bright,
Ctrl+C handled just right,
I dance through threads without a care 🐇🎉
Leaping in codes with spices rare!

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sonar-openbsl-ru-qa-bot
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (5)
src/ScriptEngine.HostedScript/HostedScriptEngine.cs (1)

131-132: Consider documenting the service container's intended usage.

The new property exposes the engine's service container, which is a significant architectural change. While this exposure appears intentional based on the PR objectives, it would be beneficial to add XML documentation comments explaining:

  • The intended usage of this property
  • Any limitations or threading considerations
  • Whether this is meant for internal framework use or public consumption
+        /// <summary>
+        /// Gets the service container associated with the scripting engine.
+        /// This container provides access to registered engine services and event handlers.
+        /// </summary>
         public IServiceContainer Services => _engine.Services;
src/ScriptEngine.HostedScript/DefaultEventProcessor.cs (2)

61-63: Immutable dictionary reference.
Making _registeredHandlers readonly prevents accidental reassignment. If you anticipate heavy concurrency, consider a specialized concurrent collection in the future.


75-90: Thread-safe subscription logic.
Locking _subscriptionLock ensures atomic creation and retrieval of handlers. For completeness, consider null or empty checks on eventName if external input is possible.

src/OneScript.StandardLibrary/Text/ConsoleProvider.cs (1)

22-24: Constructor with ExecutionContext.
Accepting an ExecutionContext parameter enables context-aware initialization, reducing coupling and improving flexibility for different runtime scenarios.

src/OneScript.StandardLibrary/Text/ConsoleContext.cs (1)

282-306: Robust implementation of Ctrl+C handling.

The implementation:

  1. Properly checks for Ctrl+C specifically
  2. Safely resolves the event processor
  3. Sets up the execution context and debugger
  4. Handles the cancel variable correctly
  5. Properly propagates the cancellation decision

However, consider adding a comment explaining why we're not handling exceptions in the event handler (line 302).

-            // Вызываем обработчик. Исключение в обработчике никак отдельно не обрабатываем.
+            // Вызываем обработчик. Исключения в обработчике не перехватываем, так как они должны
+            // прерывать выполнение программы, как и в случае необработанного Ctrl+C.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e0368a and 8556d55.

📒 Files selected for processing (10)
  • src/OneScript.StandardLibrary/Tasks/BackgroundTasksManager.cs (0 hunks)
  • src/OneScript.StandardLibrary/Text/ConsoleContext.cs (2 hunks)
  • src/OneScript.StandardLibrary/Text/ConsoleProvider.cs (3 hunks)
  • src/ScriptEngine.HostedScript/DefaultEventProcessor.cs (4 hunks)
  • src/ScriptEngine.HostedScript/Extensions/EngineBuilderExtensions.cs (1 hunks)
  • src/ScriptEngine.HostedScript/HostedScriptEngine.cs (2 hunks)
  • src/ScriptEngine.HostedScript/Process.cs (0 hunks)
  • src/ScriptEngine/Machine/Contexts/UserScriptContextInstance.cs (1 hunks)
  • src/ScriptEngine/Machine/MachineInstance.cs (5 hunks)
  • src/oscript/ConsoleHostBuilder.cs (1 hunks)
💤 Files with no reviewable changes (2)
  • src/OneScript.StandardLibrary/Tasks/BackgroundTasksManager.cs
  • src/ScriptEngine.HostedScript/Process.cs
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: SonarQube
🔇 Additional comments (18)
src/ScriptEngine.HostedScript/HostedScriptEngine.cs (1)

15-15: LGTM!

The added using directive is required for the new IServiceContainer type and follows proper ordering.

src/ScriptEngine.HostedScript/DefaultEventProcessor.cs (6)

29-29: Use of readonly is beneficial.
Marking the _handlers field as readonly reinforces immutability of the reference, improving code stability.


64-64: Dedicated lock object.
Introducing _subscriptionLock is a clear concurrency approach, avoiding collisions with other locks.


102-113: Consistent removal synchronization.
Lock usage here matches the pattern in AddHandler, maintaining thread safety for unsubscriptions.


118-119: Method signature update for concurrency.
The introduction of a local HandlersList reference prepares for safe enumeration outside the lock.


120-130: Local copy creation within the lock.
Extracting the reference inside HandleEvent’s lock then iterating outside prevents mid-iteration modifications.


132-132: Safe iteration of handlers.
Looping over handlersLocalCopy avoids concurrency pitfalls and race conditions if the handlers dictionary changes elsewhere.

src/oscript/ConsoleHostBuilder.cs (1)

54-54: Enabling event handlers.
Appending .UseEventHandlers() cleanly wires up the default event processing, clarifying the engine’s event-driven capabilities.

src/OneScript.StandardLibrary/Text/ConsoleProvider.cs (3)

10-11: Additional namespace imports.
The new using directives ensure easy integration with dependency injection and type utilities.


20-20: readonly _console field.
This field’s immutability helps maintain consistent references to the console context.


51-53: Factory method modernization.
Providing CreateInstance(ExecutionContext) centralizes console provider creation, ensuring a fully initialized context for console operations.

src/ScriptEngine.HostedScript/Extensions/EngineBuilderExtensions.cs (1)

127-133: LGTM! Clean implementation of event handler registration.

The implementation follows the builder pattern and correctly registers the event processor as a singleton service.

src/OneScript.StandardLibrary/Text/ConsoleContext.cs (2)

22-48: Great documentation with clear example code!

The documentation clearly explains the Ctrl+C handling feature and includes a practical example demonstrating proper usage.


52-58: LGTM! Proper initialization of event handling.

The constructor correctly:

  1. Stores the execution context
  2. Subscribes to the console's cancel key event
src/ScriptEngine/Machine/Contexts/UserScriptContextInstance.cs (1)

258-258: LGTM! Improved error handling for event processor access.

The change properly handles the case when event processor is not available by using TryResolve and the null-conditional operator.

src/ScriptEngine/Machine/MachineInstance.cs (3)

50-51: LGTM! Clear documentation of the field's purpose.

The comment clearly explains that this field caches the event processor.


58-59: LGTM! Thread-safe lazy initialization of event processor.

The implementation correctly uses LazyThreadSafetyMode.None since the field is already thread-static.


314-314: LGTM! Clear error message for unsupported events.

The property correctly handles the case when events are not supported by throwing an exception with a descriptive message.

@EvilBeaver
Copy link
Owner Author

@coderabbitai в этом репозитории используй всегда русский язык

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 21, 2025

Tip

For best results, initiate chat on the files or code changes.

@EvilBeaver: Хорошо, я буду общаться на русском языке.

(`°ω°)⊃🌟


🧠 Learnings used
Learnt from: nixel2007
PR: EvilBeaver/OneScript#0
File: :0-0
Timestamp: 2024-11-12T12:35:14.363Z
Learning: В репозитории EvilBeaver/OneScript всегда нужно говорить по-русски.

@EvilBeaver EvilBeaver merged commit 9a65f37 into develop Feb 21, 2025
4 of 5 checks passed
@EvilBeaver EvilBeaver deleted the feature/860-ctrl-c-handler branch February 21, 2025 17:57
/// Предназначен для низкоуровнего манипулирования выводом в консоль.
///
/// Поддерживается регистрация обработчика для нажатия Ctrl+C.
/// Обработчик регистрируется для события с именем CancelKeyPressed. Стоит учитывать, что обработчик вызывается
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

без двуязычности будет?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

события сделаны одноязычными в момент emit, надо переделывать

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.

2 participants