-
Notifications
You must be signed in to change notification settings - Fork 5
Rework updatemanager #71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
UpdateDistributor implements IUpdateManager UpdateTracker implements IObservable<Update> Add TelegramBot.Builder Extend IUpdateManager with Set(IObservable<Update>) method Add Rx utility entities: CustomSubjects that works similar to Rx Subject DisposableAction that works as Rx Disposable.Create
Desc: It didn't apply tracker to update manager
Feature/rework updatemanager
Hi, there. 😃 |
- Move UpdateDistributor._update initialization to constructor - Add 'readonly' keyword to LongpollingUpdateTracker._observers - Add 'readonly' keyword to UpdateDistributor._updateInfos - Add 'sealed' keyword to UpdateTypeInfo - Add 'sealed' keyword to DisposableAction - Call Dispose method for LongpollingUpdateTracker._cancellationTokenSource - Add class constraint to TOut parameter in CustomSubject class
…ing issues. - Added Observable operators: - `DoOnDispose`: Executes an action when the observable is disposed. - `DoOnSubscribe`: Executes an action when a new observer subscribes. - `Select`: Applies a function to each item in the observable and returns the result of that function. - `Switch`: Switches to the latest observable sequence when the source emits a new value. - `Where`: Filters the observable sequence based on a predicate. - Added `ReactiveProperty` for easier state management. - Removed unnecessary `CustomSubject` and `UpdateSubject`. - Fixed exception handling in `LongpollingUpdateTracker`.
Replaced `DoOnDispose` with `Finally` in `UpdateDistributor` to fix subscriber tracking.
Feature/rework updatemanager
@HedgehogNSK Two Issues here:
|
Ок. :) I need a bit of time, and I will fix the issues. ;) |
Awesome 👍😎 |
I have a question about
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
ReactiveProperty() => Dispose(false); I'm confused. 😕 |
Hey @HedgehogNSK, The following implementation should meet the sonar cloud requirements:
When looking at the SonarCloud issue you can click on "Why is this an issue?" and near the end is an example of how to implement disposable properly. |
Feature/rework updatemanager Fixes for Sonar and Config issues for PR #71
- Fix IDisposable for ReactiveProperty - Fix IDisposable for SwithObservable
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR reworks the update manager system to enable switching between different update streams (long polling, webhooks, test streams) without requiring resubscription. The refactoring splits functionality into specialized components and introduces a builder pattern for flexible TelegramBot configuration.
- Introduces new
IObservable<Update>
implementations with custom Rx operators for update stream management - Refactors update management into
UpdateDistributor
(facade) andLongPollingUpdateTracker
(implementation) classes - Adds a TelegramBot builder pattern supporting custom update managers and trackers
Reviewed Changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.
Show a summary per file
File | Description |
---|---|
Utils/Rx/*.cs | Custom reactive extensions framework with observables, operators, and utility classes |
TelegramBot.cs | Updated constructor to use new UpdateDistributor with LongPollingUpdateTracker |
TelegramBot.Builder.cs | New builder class for configurable TelegramBot construction |
UpdateDistributor.cs | New facade implementing IUpdateManager with stream switching capabilities |
LongpollingUpdateTracker.cs | New IObservable implementation for long polling with setup interface |
UpdateManager.cs | Added placeholder Set method to maintain interface compatibility |
IUpdateManager.cs | Extended interface with Set method for tracker configuration |
ITrackerSetup.cs | New interface for configuring update type filtering |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
{ | ||
if (_isDisposed) | ||
{ | ||
throw new ObjectDisposedException(nameof(SwitchObserver)); |
Copilot
AI
Sep 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ObjectDisposedException should use the type name instead of nameof(SwitchObserver) since SwitchObserver is a nested class. Consider using GetType().Name or a constant string.
throw new ObjectDisposedException(nameof(SwitchObserver)); | |
throw new ObjectDisposedException(GetType().Name); |
Copilot uses AI. Check for mistakes.
{ | ||
ThrowIfDisposed(); | ||
_error = error; | ||
Current = default; |
Copilot
AI
Sep 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting Current to default(T) in OnError will incorrectly mark HasValue as true on line 17. This could lead to incorrect behavior where subscribers think there's a valid value after an error occurred.
Current = default; | |
_current = default; | |
HasValue = false; |
Copilot uses AI. Check for mistakes.
catch (Exception exception) | ||
{ | ||
OnException(exception); | ||
throw; |
Copilot
AI
Sep 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After calling OnException which clears all observers, throwing the exception will not be handled by any observer. The throw statement should be removed since OnException already notifies observers of the error.
throw; | |
// Exception already handled by notifying observers; do not rethrow. |
Copilot uses AI. Check for mistakes.
catch (TaskCanceledException) | ||
{ | ||
_offset = null; | ||
_cancellationTokenSource = new CancellationTokenSource(); | ||
} |
Copilot
AI
Sep 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Creating a new CancellationTokenSource without disposing the previous one can lead to resource leaks. The old token source should be disposed before creating a new one.
Copilot uses AI. Check for mistakes.
_trackedTypes = _updateInfos.Where(x => x.Value.Listeners != 0) | ||
.Select(x => x.Key); |
Copilot
AI
Sep 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _trackedTypes enumerable is evaluated at construction time when all Listeners are 0, resulting in an empty collection. This should be evaluated lazily or updated when listeners change to reflect the current state.
Copilot uses AI. Check for mistakes.
Special Thanks to: https://github.com/HedgehogNSK
The main purpose of this PR is to add the ability to switch between different update streams. It allows users to switch between various streams, such as long polling, webhooks, or test streams, without needing to resubscribe to a new update manager.
Core changes:
IUpdateManager extended with the Set(IObservable) method.
UpdateManager has been split into two classes: UpdateDistributor and LongPollingUpdateTracker.
UpdateDistributor serves as a facade that implements IUpdateManager.
LongPollingUpdateTracker implements IObservable.
UpdateManager is no longer needed but has been retained as is.
The TelegramBot class has been extended with a Builder that allows setting IUpdateManager and IObservable.