From 253302aaa6e0c6e54e563116d5a6c8b3862c9833 Mon Sep 17 00:00:00 2001 From: AKosylo Date: Thu, 4 Jan 2024 15:29:56 +0100 Subject: [PATCH] add documentation --- DXFeedFramework/Api/DXFeedSubcription.swift | 2 - .../Api/DXFeedTimeSeriesSubscription.swift | 17 ++++++++ .../Api/Osub/IObservableSubscription.swift | 23 ++++++++++ ...ObservableSubscriptionChangeListener.swift | 42 +++++++++++++++++++ .../DXTimeSeriesSubscriptionTest.swift | 2 +- DXFeedFrameworkTests/FeedTest.swift | 2 +- 6 files changed, 84 insertions(+), 4 deletions(-) diff --git a/DXFeedFramework/Api/DXFeedSubcription.swift b/DXFeedFramework/Api/DXFeedSubcription.swift index e3ea04bbc..28a17dd89 100644 --- a/DXFeedFramework/Api/DXFeedSubcription.swift +++ b/DXFeedFramework/Api/DXFeedSubcription.swift @@ -125,12 +125,10 @@ extension DXFeedSubcription: IObservableSubscription { return events.contains(eventType) } - /// - Throws: GraalException. Rethrows exception from Java. public func addChangeListener(_ listener: ObservableSubscriptionChangeListener) throws { try native.addChangeListener(listener) } - /// - Throws: GraalException. Rethrows exception from Java. public func removeChangeListener(_ listener: ObservableSubscriptionChangeListener) throws { try native.removeChangeListener(listener) } diff --git a/DXFeedFramework/Api/DXFeedTimeSeriesSubscription.swift b/DXFeedFramework/Api/DXFeedTimeSeriesSubscription.swift index 266de1940..77f9fac04 100644 --- a/DXFeedFramework/Api/DXFeedTimeSeriesSubscription.swift +++ b/DXFeedFramework/Api/DXFeedTimeSeriesSubscription.swift @@ -7,10 +7,21 @@ import Foundation +/// Extends ``DXFeedSubcription`` to conveniently subscribe to time-series of +/// events for a set of symbols and event types. +/// +/// This class decorates symbols +/// that are passed to xxxSymbols methods in ``DXFeedSubcription`` +/// by wrapping them into ``TimeSeriesSubscriptionSymbol`` instances with +/// the current value of fromTime property. +/// +/// Only events that implement ``ITimeSeriesEvent`` interface can be +/// subscribed to with DXFeedTimeSeriesSubscription``. public class DXFeedTimeSeriesSubscription: DXFeedSubcription { /// Subscription native wrapper. private let native: NativeTimeSeriesSubscription? + /// - Throws: ``GraalException`` Rethrows exception from Java, ``ArgumentException/argumentNil`` internal init(native: NativeTimeSeriesSubscription?, events: [EventCode]) throws { if let native = native { self.native = native @@ -20,6 +31,12 @@ public class DXFeedTimeSeriesSubscription: DXFeedSubcription { try super.init(native: native?.subscription, events: events) } + /// Set the earliest timestamp from which time-series of events shall be received. + /// The timestamp is in milliseconds from midnight, January 1, 1970 UTC. + /// + /// - Parameters: + /// - fromTime: fromTime the timestamp + /// - Throws: ``GraalException`` Rethrows exception from Java, ``ArgumentException/argumentNil`` func set(fromTime: Long) throws { try native?.set(fromTime: fromTime) } diff --git a/DXFeedFramework/Api/Osub/IObservableSubscription.swift b/DXFeedFramework/Api/Osub/IObservableSubscription.swift index 2999c4fb5..38212f64b 100644 --- a/DXFeedFramework/Api/Osub/IObservableSubscription.swift +++ b/DXFeedFramework/Api/Osub/IObservableSubscription.swift @@ -22,12 +22,35 @@ public protocol IObservableSubscription { /// Gets a value indicating whether if this subscription contains the corresponding event type. /// /// [Javadoc](https://docs.dxfeed.com/dxfeed/api/com/dxfeed/api/osub/ObservableSubscription.html#containsEventType-java.lang.Class-) + /// /// - Parameters: /// - eventType: The event type. /// - Returns: **true** if this subscription contains the corresponding event type func isContains(_ eventType: EventCode) -> Bool + /// Adds subscription change listener. This method does nothing if the given listener is already + /// installed as subscription change listener for this subscription or if subscription is closed. + /// + /// Otherwise, it installs the + /// corresponding listener and immediately invokes ``ObservableSubscriptionChangeListener/symbolsAdded(symbols:)`` + /// on the given listener while holding the lock for this + /// subscription. This way the given listener synchronously receives existing subscription state and and + /// is synchronously notified on all changes in subscription afterwards. + /// + /// - Parameters: + /// - listener: listener the subscription change listener. + /// - Throws: GraalException. Rethrows exception from Java. func addChangeListener(_ listener: ObservableSubscriptionChangeListener) throws + /// Removes subscription change listener. This method does nothing if the given listener was not + /// installed or was already removed as subscription change listener for this subscription. + /// + /// Otherwise it removes the corresponding listener and immediately invokes + /// ``ObservableSubscriptionChangeListener/subscriptionClosed()`` on the given listener while + /// holding the lock for this subscription. + /// + /// - Parameters: + /// - listener: listener the subscription change listener. + /// - Throws: GraalException. Rethrows exception from Java. func removeChangeListener(_ listener: ObservableSubscriptionChangeListener) throws } diff --git a/DXFeedFramework/Api/Osub/ObservableSubscriptionChangeListener.swift b/DXFeedFramework/Api/Osub/ObservableSubscriptionChangeListener.swift index 263865f55..7e7bfda2c 100644 --- a/DXFeedFramework/Api/Osub/ObservableSubscriptionChangeListener.swift +++ b/DXFeedFramework/Api/Osub/ObservableSubscriptionChangeListener.swift @@ -7,10 +7,52 @@ import Foundation +/// The listener interface for receiving notifications on the changes of observed subscription. +/// All methods on this interface are invoked while holding a lock on ``IObservableSubscription`` instance, +/// thus all changes for a given subscription are synchronized with respect to each other. +/// +/// Decorated symbols +/// The sets of symbols that are passed to ``symbolsAdded(symbols:)`` and ``symbolsRemoved(symbols:)`` +/// are decorated depending on the actual implementation class of ``DXFeedSubscription``. +/// ``DXFeedTimeSeriesSubscription`` decorates original subscription symbols by wrapping them +/// into instances of ``TimeSeriesSubscriptionSymbol`` class. +/// +/// Equality of symbols and notifications +/// +/// Symbols are compared using their equals method. When one symbol in subscription is +/// replaced by the other one that is equal to it, then the decision of whether to issue +/// ``symbolsAdded(symbols:)`` notification is up to implementation. +/// +/// However, the implementation that is returned by +/// ``DXPublisher/getSubscription(_:)`` can generate repeated +/// ``ObservableSubscriptionChangeListener/symbolsAdded(symbols:)`` notifications to +/// its listeners for the same symbols without the corresponding +/// ``ObservableSubscriptionChangeListener/symbolsRemoved(symbols:)`` +/// notifications in between them. It happens when subscription disappears, cached data is lost, and subscription +/// reappears again. On each ``ObservableSubscriptionChangeListener/symbolsAdded(symbols:)`` +/// notification data provider shall ``DXPublisher/publish(events:)`` the most recent events for +/// the corresponding symbols. +/// +/// Wildcard symbols +/// +/// The set of symbols may contain ``WildcardSymbol/all`` object. +/// See ``WildcardSymbol`` for details. public protocol ObservableSubscriptionChangeListener: AnyObject { + /// Invoked after a collection of symbols is added to a subscription. + /// Subscription's set of symbols already includes added symbols when this method is invoked. + /// The set of symbols is decorated. func symbolsAdded(symbols: Set) + /// Invoked after a collection of symbols is removed from a subscription. + /// Subscription's set of symbols already excludes removed symbols when this method is invoked. + /// The set of symbols is decorated. + /// Default implementation is empty. func symbolsRemoved(symbols: Set) + /// Invoked after subscription is closed or when this listener is + /// ``DXFeedSubcription/removeChangeListener(_:)`` from the subscription. + /// ``DXPublisher`` ``DXPublisher/getSubscription(_:)`` is considered to be closed + /// when the corresponding ``DXEndpoint`` is ``DXEndpoint/close()``. + /// Default implementation is empty. func subscriptionClosed() } diff --git a/DXFeedFrameworkTests/DXTimeSeriesSubscriptionTest.swift b/DXFeedFrameworkTests/DXTimeSeriesSubscriptionTest.swift index 4132790a4..643a2fed8 100644 --- a/DXFeedFrameworkTests/DXTimeSeriesSubscriptionTest.swift +++ b/DXFeedFrameworkTests/DXTimeSeriesSubscriptionTest.swift @@ -21,7 +21,7 @@ final class DXTimeSeriesSubscriptionTest: XCTestCase { func testCreateWithNil() throws { XCTAssertThrowsError(try DXFeedTimeSeriesSubscription(native: nil, events: [.candle])) { error in XCTAssertTrue(error is ArgumentException) - } + } } func createSubscriptionFor(multiple: Bool) throws { diff --git a/DXFeedFrameworkTests/FeedTest.swift b/DXFeedFrameworkTests/FeedTest.swift index 4b9148a20..94474ecf9 100644 --- a/DXFeedFrameworkTests/FeedTest.swift +++ b/DXFeedFrameworkTests/FeedTest.swift @@ -57,7 +57,7 @@ final class FeedTest: XCTestCase { let testString = TimeSeriesSubscriptionSymbol(symbol: symbol1, fromTime: 10).stringValue print(testString) } - + func testCreateSubscriptionWithSymbol() throws { try createMultipleSubscriptionWithSymbol(symbols: ["ETH/USD:GDAX"]) }