-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
701 additions
and
186 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
## Version 0.6.0 | ||
* Feature: Add IpfConnection | ||
|
||
## Version 0.5.0 | ||
|
||
## What's Changed | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<RootNamespace>DxFeed.Graal.Net.Samples</RootNamespace> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> | ||
<OutputPath>../../artifacts/Debug/Samples/DxFeedLiveIpfSample/</OutputPath> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> | ||
<OutputPath>../../artifacts/Release/Samples/DxFeedLiveIpfSample/</OutputPath> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\DxFeed.Graal.Net\DxFeed.Graal.Net.csproj" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// <copyright file="Program.cs" company="Devexperts LLC"> | ||
// Copyright © 2022 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/. | ||
// </copyright> | ||
|
||
using System; | ||
using System.Collections.Concurrent; | ||
using System.Collections.Generic; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using DxFeed.Graal.Net.Ipf; | ||
using DxFeed.Graal.Net.Ipf.Live; | ||
|
||
namespace DxFeed.Graal.Net.Samples; | ||
|
||
internal abstract class Program | ||
{ | ||
private static readonly string DXFEED_IPF_URL = "https://demo:[email protected]/ipf"; | ||
|
||
public static async Task Main(string[] args) | ||
{ | ||
if (args.Length > 1) { | ||
Console.WriteLine("usage: DXFeedLiveIpfSample [<ipf-url>]"); | ||
Console.WriteLine("where: <ipf-url> is URL for the instruments profiles, default: " + DXFEED_IPF_URL); | ||
return; | ||
} | ||
|
||
var url = (args.Length > 0) ? args[0] : DXFEED_IPF_URL; | ||
|
||
var collector = new InstrumentProfileCollector(); | ||
var connection = InstrumentProfileConnection.CreateConnection(url, collector); | ||
// Update period can be used to re-read IPF files, not needed for services supporting IPF "live-update" | ||
connection.SetUpdatePeriod(60_000L); | ||
connection.Start(); | ||
|
||
// Data model to keep all instrument profiles mapped by their ticker symbol | ||
var profiles = new ConcurrentDictionary<string, InstrumentProfile>(); | ||
|
||
// It is possible to add listener after connection is started - updates will not be missed in this case | ||
collector.AddUpdateListener(instruments => | ||
{ | ||
Console.WriteLine("\nInstrument Profiles:"); | ||
// We can observe REMOVED elements - need to add necessary filtering | ||
// See javadoc for InstrumentProfileCollector for more details | ||
|
||
// (1) We can either process instrument profile updates manually | ||
instruments.ForEach(profile => | ||
{ | ||
if (InstrumentProfileType.REMOVED.Name.Equals(profile.GetType().Name, StringComparison.Ordinal)) { | ||
// Profile was removed - remove it from our data model | ||
profiles.Remove(profile.Symbol, out _); | ||
} else { | ||
// Profile was updated - collector only notifies us if profile was changed | ||
profiles.TryAdd(profile.Symbol, profile); | ||
} | ||
}); | ||
Console.WriteLine("Total number of profiles (1): " + profiles.Count); | ||
Console.WriteLine("Last modified: " + DateTimeOffset.FromUnixTimeMilliseconds(collector.GetLastUpdateTime())); | ||
}); | ||
|
||
|
||
await Task.Delay(Timeout.Infinite); | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
src/DxFeed.Graal.Net/Ipf/Live/InstrumentProfileCollector.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// <copyright file="InstrumentProfileCollector.cs" company="Devexperts LLC"> | ||
// Copyright © 2022 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/. | ||
// </copyright> | ||
|
||
using System.Collections.Generic; | ||
using DxFeed.Graal.Net.Native.Ipf; | ||
|
||
namespace DxFeed.Graal.Net.Ipf.Live; | ||
|
||
/// <summary> | ||
/// Collects instrument profile updates and provides the live list of instrument profiles. | ||
/// This class contains a map that keeps a unique instrument profile per symbol. | ||
/// This class is intended to be used with InstrumentProfileConnection as a repository | ||
/// that keeps profiles of all known instruments. | ||
/// As set of instrument profiles stored in this collector can be accessed with view method. | ||
/// A snapshot plus a live stream of updates can be accessed with addUpdateListener method. | ||
/// Removal of instrument profile is represented by an InstrumentProfile instance | ||
/// with a type equal to InstrumentProfileType.REMOVED. | ||
/// </summary> | ||
public class InstrumentProfileCollector | ||
{ | ||
private readonly InstrumentProfileCollectorHandle handle = InstrumentProfileCollectorHandle.Create(); | ||
|
||
/// <summary> | ||
/// Gets last modification time (in milliseconds) of instrument profiles or zero if it is unknown. | ||
/// Note, that while the time is represented in milliseconds, the actual granularity of time here is a second. | ||
/// </summary> | ||
/// <returns>Last modification time (in milliseconds) of instrument profiles or zero if it is unknown.</returns> | ||
public long GetLastUpdateTime() => | ||
handle.GetLastUpdateTime(); | ||
|
||
/// <summary> | ||
/// Gets a concurrent view of the set of instrument profiles. | ||
/// Note, that removal of instrument profile is represented by an <see cref="InstrumentProfile"/> instance with a | ||
/// <see cref="InstrumentProfileType"/> equal to | ||
/// <c>InstrumentProfileType.REMOVED</c> | ||
/// Normally, this view exposes only non-removed profiles. However, if iteration is concurrent with removal, | ||
/// then a removed instrument profile (with a removed type) can be exposed by this view. | ||
/// </summary> | ||
/// <returns>A concurrent view of the set of instrument profiles.</returns> | ||
public IEnumerable<InstrumentProfile> View() => | ||
handle.View(); | ||
|
||
/// <summary> | ||
/// Adds listener that is notified about any updates in the set of instrument profiles. | ||
/// If a set of instrument profiles is not empty, then this listener will be immediately notified. | ||
/// </summary> | ||
/// <param name="listener">The profile update listener.</param> | ||
public void AddUpdateListener(InstrumentProfileUpdateListener listener) => | ||
handle.AddUpdateListener(listener); | ||
|
||
/// <summary> | ||
/// Removes listener that is notified about any updates in the set of instrument profiles. | ||
/// </summary> | ||
/// <param name="listener">The profile update listener.</param> | ||
public void RemoveUpdateListener(InstrumentProfileUpdateListener listener) => | ||
handle.RemoveUpdateListener(listener); | ||
|
||
internal InstrumentProfileCollectorHandle GetHandle() => | ||
handle; | ||
} |
Oops, something went wrong.