-
Notifications
You must be signed in to change notification settings - Fork 265
feat: Add extensible ReusableObserver implementing IStreamObserver<IReusable> #1894
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
Changes from 5 commits
ccef491
608d471
252a668
938d7d2
37acf0d
c2632b4
52b6378
5eff832
b7900e2
7e271df
98415b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,73 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace Skender.Stock.Indicators; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Flexible IStreamObserver implementation with customizable callbacks for all lifecycle methods. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// All callbacks are optional (nullable). | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| public class ReusableObserver : IStreamObserver<IReusable> | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly Func<bool> _isSubscribed; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly Action<Exception>? _onError; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly Action? _onCompleted; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly Action? _onUnsubscribe; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly Action<IReusable, bool, int?>? _onAdd; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly Action<DateTime>? _onRebuild; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly Action<DateTime>? _onPrune; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly Action? _onReinitialize; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly Action? _rebuild; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly Action<DateTime>? _rebuildTimestamp; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly Action<int>? _rebuildIndex; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| public bool IsSubscribed => _isSubscribed(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+22
to
+33
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clarify the thread-safety guarantee in documentation. The documentation claims "This property is thread-safe" (line 28), but the property simply delegates to the user-provided 📝 Suggested documentation revision /// <remarks>
- /// This property is thread-safe and returns the current subscription state
- /// by invoking the backing delegate <see cref="_isSubscribed"/>.
+ /// Returns the current subscription state by invoking the backing delegate
+ /// <see cref="_isSubscribed"/>. Thread-safety depends on the implementation
+ /// of the provided delegate.
/// The value is determined by the provider at the time of invocation.
/// </remarks>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| public ReusableObserver( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Func<bool> isSubscribed, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action<Exception>? onError = null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action? onCompleted = null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action? onUnsubscribe = null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action<IReusable, bool, int?>? onAdd = null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action<DateTime>? onRebuild = null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action<DateTime>? onPrune = null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action? onReinitialize = null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action? rebuild = null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action<DateTime>? rebuildTimestamp = null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action<int>? rebuildIndex = null) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _isSubscribed = isSubscribed; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _onError = onError; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _onCompleted = onCompleted; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _onUnsubscribe = onUnsubscribe; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _onAdd = onAdd; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _onRebuild = onRebuild; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _onPrune = onPrune; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _onReinitialize = onReinitialize; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _rebuild = rebuild; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _rebuildTimestamp = rebuildTimestamp; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| _rebuildIndex = rebuildIndex; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void OnError(Exception exception) => _onError?.Invoke(exception); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add XML documentation and validate exception parameter. Two issues:
📝 Proposed fix+ /// <summary>
+ /// Invoked when an error occurs in the stream.
+ /// </summary>
+ /// <param name="exception">The exception that occurred.</param>
- public void OnError(Exception exception) => _onError?.Invoke(exception);
+ public void OnError(Exception exception)
+ {
+ ArgumentNullException.ThrowIfNull(exception);
+ _onError?.Invoke(exception);
+ }As per coding guidelines, all public methods require XML documentation. 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void OnCompleted() => _onCompleted?.Invoke(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void Unsubscribe() { _onUnsubscribe?.Invoke(); } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| // OnAdd is called when a new item is added to the hub's cache | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void OnAdd(IReusable item, bool notify, int? indexHint) => _onAdd?.Invoke(item, notify, indexHint); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| // OnRebuild is called when the hub recalculates from a specific timestamp | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void OnRebuild(DateTime fromTimestamp) => _onRebuild?.Invoke(fromTimestamp); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| // OnPrune is called when old items are removed from the hub's cache | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void OnPrune(DateTime toTimestamp) => _onPrune?.Invoke(toTimestamp); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Reinitialize is called to reset the observer state | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void Reinitialize() { _onReinitialize?.Invoke(); } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Rebuild methods trigger recalculation | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void Rebuild() => _rebuild?.Invoke(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void Rebuild(DateTime fromTimestamp) => _rebuildTimestamp?.Invoke(fromTimestamp); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void Rebuild(int fromIndex) => _rebuildIndex?.Invoke(fromIndex); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.