Skip to content

Commit

Permalink
feat: last events task
Browse files Browse the repository at this point in the history
  • Loading branch information
kosyloa committed Apr 11, 2024
1 parent 8130006 commit e9e126f
Show file tree
Hide file tree
Showing 4 changed files with 287 additions and 192 deletions.
4 changes: 4 additions & 0 deletions DXFeedFramework.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@
64DA26C02AA224EB005B1757 /* NativeIPFConnectionListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64DA26BF2AA224EB005B1757 /* NativeIPFConnectionListener.swift */; };
64DB79342A376E1B00229597 /* DXFeedFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 803BAC0D29BFA50700FFAB1C /* DXFeedFramework.framework */; };
64DB79352A376E1B00229597 /* DXFeedFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 803BAC0D29BFA50700FFAB1C /* DXFeedFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
64DF09332BC80DBB009F1486 /* DXFeed+LastEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64DF09322BC80DBB009F1486 /* DXFeed+LastEvent.swift */; };
64E342502AAB083700457994 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6469F8D22A3B401700846831 /* Colors.swift */; };
64E342522AAB29CF00457994 /* InstrumentProfileType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64E342512AAB29CF00457994 /* InstrumentProfileType.swift */; };
64E3637B2AD83459002E2B0D /* SeriesMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64E3637A2AD83459002E2B0D /* SeriesMapper.swift */; };
Expand Down Expand Up @@ -882,6 +883,7 @@
64DA26BB2AA20B66005B1757 /* InstrumentProfileConnectionState+ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InstrumentProfileConnectionState+ext.swift"; sourceTree = "<group>"; };
64DA26BD2AA20EDB005B1757 /* DXInstrumentProfileConnectionListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DXInstrumentProfileConnectionListener.swift; sourceTree = "<group>"; };
64DA26BF2AA224EB005B1757 /* NativeIPFConnectionListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeIPFConnectionListener.swift; sourceTree = "<group>"; };
64DF09322BC80DBB009F1486 /* DXFeed+LastEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DXFeed+LastEvent.swift"; sourceTree = "<group>"; };
64E342512AAB29CF00457994 /* InstrumentProfileType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstrumentProfileType.swift; sourceTree = "<group>"; };
64E3637A2AD83459002E2B0D /* SeriesMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeriesMapper.swift; sourceTree = "<group>"; };
64EAA1A12B7A38F8005087BC /* DXPromiseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DXPromiseTest.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1698,6 +1700,7 @@
64ACBCDB2A28974900032C53 /* Osub */,
80FC415829C8EE8B00E6B611 /* DXEndpoint.swift */,
64656F5A2A1B9784006A0B19 /* DXFeed.swift */,
64DF09322BC80DBB009F1486 /* DXFeed+LastEvent.swift */,
64656F662A1CCFC2006A0B19 /* DXPublisher.swift */,
64656F6C2A1CFB10006A0B19 /* DXEndpointState.swift */,
641BCBBB2A20ED8100FE23C2 /* DXEndpointListener.swift */,
Expand Down Expand Up @@ -2502,6 +2505,7 @@
80FC415F29CA2C5100E6B611 /* NativeProperty.swift in Sources */,
64656F622A1B9FF7006A0B19 /* EnumException.swift in Sources */,
641BCBC12A21077800FE23C2 /* EventCode.swift in Sources */,
64DF09332BC80DBB009F1486 /* DXFeed+LastEvent.swift in Sources */,
64ACBCE82A28CF9700032C53 /* IndexedEventSubscriptionSymbol.swift in Sources */,
64C004782BA1C25C0009F7C9 /* OtcMarketsOrderMapper.swift in Sources */,
649F48882A615BED0016FDD1 /* CandleType.swift in Sources */,
Expand Down
267 changes: 267 additions & 0 deletions DXFeedFramework/Api/DXFeed+LastEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
//
//
// Copyright (C) 2024 Devexperts LLC. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

import Foundation

public extension DXFeed {
/// Requests the last event for the specified event type and symbol.
///
/// This method works only for event types that implement ``ILastingEvent`` marker interface.
/// This method requests the data from the the uplink data provider,
/// creates new event of the specified ``IEventType``,
/// and Success the resulting task with this event.
/// - Parameters:
/// - type: ``IEventType``.
/// - symbol: ``Symbol``
/// - Returns: Task
/// - Throws: ``GraalException``. Rethrows exception from Java.
@available(iOS 13.0, *)
@available(macOS 10.15, *)
func getLastEvent(type: IEventType.Type,
symbol: Symbol) -> Task<MarketEvent?, Error> {
let task = Task {
let defaultValue: MarketEvent? = nil
if Task.isCancelled {
return defaultValue
}

let promise = try getLastEventPromise(type: type, symbol: symbol)
while !promise.hasResult() {
try? await Task.sleep(nanoseconds: 100_000_000)
if Task.isCancelled {
return defaultValue
}
}
return try promise.getResult()
}
return task
}

/// Requests the last event for the specified event type and symbol.
///
/// This method works only for event types that implement ``ILastingEvent`` marker interface.
/// This method requests the data from the the uplink data provider,
/// creates new event of the specified ``IEventType``,
/// and complete the resulting promis the resulting promise with this event.
/// - Parameters:
/// - type: ``IEventType``.
/// - symbol: ``Symbol``
/// - Returns: ``Promise``
/// - Throws: ``GraalException``. Rethrows exception from Java.
func getLastEventPromise(type: IEventType.Type, symbol: Symbol) throws -> Promise {
let nativePromise = try nativeFeed.getLastEventPromise(type: type, symbol: symbol)
return Promise(native: nativePromise)
}

/// Requests the last events for the specified event type and a collection of symbols.
///
/// This method works only for event types that implement ``ILastingEvent`` marker interface.
/// This method requests the data from the the uplink data provider,
/// creates new events of the specified ``IEventType``,
/// and complete the resulting promise with these events.
/// - Parameters:
/// - type: ``IEventType``.
/// - symbol: The list of ``Symbol``
/// - Returns: The list of Task
/// - Throws: ``GraalException``. Rethrows exception from Java.
@available(iOS 13.0, *)
@available(macOS 10.15, *)
func getLastEventsTasks(type: IEventType.Type, symbols: [Symbol]) throws -> [Task<MarketEvent?, Error>]? {
let promises = try getLastEventPromises(type: type, symbols: symbols)
let tasks = promises?.compactMap { promise in
let task = Task {
let defaultValue: MarketEvent? = nil
if Task.isCancelled {
return defaultValue
}

while !promise.hasResult() {
try? await Task.sleep(nanoseconds: 100_000_000)
if Task.isCancelled {
return defaultValue
}
}
return try promise.getResult()
}
return task
}
return tasks
}

/// Requests the last events for the specified event type and a collection of symbols.
///
/// This method works only for event types that implement ``ILastingEvent`` marker interface.
/// This method requests the data from the the uplink data provider,
/// creates new events of the specified ``IEventType``,
/// and complete the resulting promise with these events.
/// - Parameters:
/// - type: ``IEventType``.
/// - symbol: The list of ``Symbol``
/// - Returns: The list of ``MarketEvent``
/// - Throws: ``GraalException``. Rethrows exception from Java.
@available(iOS 13.0, *)
@available(macOS 10.15, *)
func getLastEvents(type: IEventType.Type, symbols: [Symbol]) async throws -> [MarketEvent] {
let tasks = try getLastEventsTasks(type: type, symbols: symbols)
return await withTaskGroup(of: MarketEvent?.self, returning: [MarketEvent].self) { taskGroup in
tasks?.forEach { task in
taskGroup.addTask {
let result = await task.result
switch result {
case .success(let value):
return value
case .failure:
return nil
}
}
}
var events = [MarketEvent]()
for await result in taskGroup {
if let result = result {
events.append(result)
}
}
return events
}
}

/// Requests the last events for the specified event type and a collection of symbols.
///
/// This method works only for event types that implement ``ILastingEvent`` marker interface.
/// This method requests the data from the the uplink data provider,
/// creates new events of the specified ``IEventType``,
/// and complete the resulting promise with these events.
/// - Parameters:
/// - type: ``IEventType``.
/// - symbol: The list of ``Symbol``
/// - Returns: The list of ``Promise``
/// - Throws: ``GraalException``. Rethrows exception from Java.
func getLastEventPromises(type: IEventType.Type, symbols: [Symbol]) throws -> [Promise]? {
let nativePromises = try nativeFeed.getLastEventPromises(type: type, symbols: symbols)
return nativePromises?.map({ promise in
Promise(native: promise)
})
}

/// Requests a list of indexed events for the specified event type, symbol, and source.
///
/// This method works only for event types that implement ``IndexedEventSource`` marker interface.
/// This method requests the data from the the uplink data provider,
/// creates a list of events of the specified ``IEventType``,
/// and Success the resulting task with this list.
/// The events are ordered by ``IIndexedEvent/index`` in the list.
/// - Parameters:
/// - type: ``IEventType``.
/// - symbol: ``Symbol``
/// - source: ``IndexedEventSource``
/// - Returns: Task
@available(iOS 13.0, *)
@available(macOS 10.15, *)
func getIndexedEvents(type: IEventType.Type,
symbol: Symbol,
source: IndexedEventSource) -> Task<[MarketEvent]?, Error> {
let task = Task {
let defaultValue: [MarketEvent]? = nil
if Task.isCancelled {
return defaultValue
}
let nativePromise = try nativeFeed.getIndexedEventsPromise(type: type,
symbol: symbol,
source: source)
let promise = Promise(native: nativePromise)
while !promise.hasResult() {
try? await Task.sleep(nanoseconds: 100_000_000)
if Task.isCancelled {
return defaultValue
}
}
return try promise.getResults()
}
return task
}

/// Requests a list of indexed events for the specified event type, symbol, and source.
///
/// This method works only for event types that implement ``IndexedEventSource`` marker interface.
/// This method requests the data from the the uplink data provider,
/// creates a list of events of the specified ``IEventType``,
/// and complete the resulting promise with this list.
/// The events are ordered by ``IIndexedEvent/index`` in the list.
/// - Parameters:
/// - type: ``IEventType``.
/// - symbol: ``Symbol``
/// - source: ``IndexedEventSource``
/// - Returns: ``Promise``
/// - Throws: ``GraalException``. Rethrows exception from Java.
func getIndexedEventsPromise(type: IEventType.Type, symbol: Symbol, source: IndexedEventSource) throws -> Promise? {
let nativePromise = try nativeFeed.getIndexedEventsPromise(type: type, symbol: symbol, source: source)
return Promise(native: nativePromise)
}

/// Requests time series of events for the specified event type, symbol, and a range of time.
///
/// This method works only for event types that implement ``ITimeSeriesEvent`` interface.
/// This method requests the data from the the uplink data provider,
/// creates a list of events of the specified ``IEventType``,
/// and Success the resulting task with this list.
/// The events are ordered by ``ITimeSeriesEvent/time``in the list.
/// - Parameters:
/// - type: ``IEventType``.
/// - symbol: ``Symbol``
/// - fromTime: the time, inclusive, to request events from ``ITimeSeriesEvent/time``
/// - toTime: the time, inclusive, to request events to ``ITimeSeriesEvent/time``
/// - Returns: Task
@available(iOS 13.0, *)
@available(macOS 10.15, *)
func getTimeSeries(type: IEventType.Type,
symbol: Symbol,
fromTime: Long,
toTime: Long) -> Task<[MarketEvent]?, Error> {
let task = Task {
let defaultValue: [MarketEvent]? = nil
if Task.isCancelled {
return defaultValue
}
let nativePromise = try nativeFeed.getTimeSeriesPromise(type: type,
symbol: symbol,
fromTime: fromTime,
toTime: toTime)
let promise = Promise(native: nativePromise)
while !promise.hasResult() {
try? await Task.sleep(nanoseconds: 100_000_000)
if Task.isCancelled {
return defaultValue
}
}
return try promise.getResults()
}
return task
}

/// Requests time series of events for the specified event type, symbol, and a range of time.
///
/// This method works only for event types that implement ``ITimeSeriesEvent`` interface.
/// This method requests the data from the the uplink data provider,
/// creates a list of events of the specified ``IEventType``,
/// and complete the resulting promise with this list.
/// The events are ordered by ``ITimeSeriesEvent/time``in the list.
/// - Parameters:
/// - type: ``IEventType``.
/// - symbol: ``Symbol``
/// - fromTime: the time, inclusive, to request events from ``ITimeSeriesEvent/time``
/// - toTime: the time, inclusive, to request events to ``ITimeSeriesEvent/time``
/// - Returns: Task
/// - Throws: ``GraalException``. Rethrows exception from Java.
func getTimeSeriesPromise(type: IEventType.Type, symbol: Symbol, fromTime: Long, toTime: Long) throws -> Promise? {
let nativePromise = try nativeFeed.getTimeSeriesPromise(type: type,
symbol: symbol,
fromTime: fromTime,
toTime: toTime)
return Promise(native: nativePromise)

}
}
Loading

0 comments on commit e9e126f

Please sign in to comment.