Skip to content

Commit

Permalink
[EN-7588] Implement PublishProfiles sample
Browse files Browse the repository at this point in the history
  • Loading branch information
ttldtor committed May 21, 2024
2 parents 316ee89 + 70463a6 commit 0575d09
Show file tree
Hide file tree
Showing 34 changed files with 985 additions and 50 deletions.
20 changes: 16 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,24 @@ jobs:
xcode: '15.0'
cc: 'clang'
cxx: 'clang++'
- name: ubuntu-22.04-gcc-13
image: ubuntu-22.04
- name: ubuntu-24.04-clang-18
image: ubuntu-24.04
os: linux
cores: 4
cc: 'clang-18'
cxx: 'clang++-18'
- name: ubuntu-24.04-gcc-14
image: ubuntu-24.04
os: linux
cores: 4
cc: 'gcc-14'
cxx: 'g++-14'
- name: ubuntu-24.04-gcc-12
image: ubuntu-24.04
os: linux
cores: 4
cc: 'gcc-13'
cxx: 'g++-13'
cc: 'gcc-12'
cxx: 'g++-12'
# - name: ubuntu-22.04-gcc-9
# image: ubuntu-22.04
# os: linux
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ jobs:
xcode: '15.0'
cc: 'clang'
cxx: 'clang++'
- name: ubuntu-22.04-gcc-13
image: ubuntu-22.04
- name: ubuntu-24.04-gcc-14
image: ubuntu-24.04
os: linux
cores: 4
cc: 'gcc-13'
cxx: 'g++-13'
cc: 'gcc-14'
cxx: 'g++-14'
- name: macos-14-xcode-15
image: macos-14
os: macos
Expand Down
8 changes: 7 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ project(dxFeedGraalCxxApi)

set(DXFCXX_VERSION "v2.0.0-rc3" CACHE STRING "The dxFeed Graal CXX API package version")

set(DXFEED_GRAAL_NATIVE_SDK_VERSION "1.1.12" CACHE STRING "")
set(DXFEED_GRAAL_NATIVE_SDK_VERSION "1.1.16" CACHE STRING "")
set(FMTLIB_VERSION "10.2.1")
set(BOOST_VERSION "1.84.0")
set(UTFCPP_VERSION "3.2.3")
Expand Down Expand Up @@ -191,6 +191,9 @@ set(dxFeedGraalCxxApi_Exceptions_Sources

set(dxFeedGraalCxxApi_Isolated_Sources
src/isolated/api/IsolatedDXEndpoint.cpp
src/isolated/api/IsolatedDXPublisher.cpp
src/isolated/api/IsolatedDXPublisherObservableSubscription.cpp
src/isolated/api/osub/IsolatedObservableSubscriptionChangeListener.cpp
src/isolated/internal/IsolatedString.cpp
src/isolated/internal/IsolatedTimeFormat.cpp
)
Expand All @@ -199,13 +202,15 @@ set(dxFeedGraalCxxApi_Api_Sources
src/api/DXEndpoint.cpp
src/api/DXFeed.cpp
src/api/DXFeedSubscription.cpp
src/api/DXPublisherObservableSubscription.cpp
src/api/DXPublisher.cpp
)

set(dxFeedGraalCxxApi_ApiOsub_Sources
src/api/osub/WildcardSymbol.cpp
src/api/osub/TimeSeriesSubscriptionSymbol.cpp
src/api/osub/IndexedEventSubscriptionSymbol.cpp
src/api/osub/ObservableSubscriptionChangeListener.cpp
)

set(dxFeedGraalCxxApi_Ipf_Sources
Expand Down Expand Up @@ -461,6 +466,7 @@ endif ()

if (DXFCXX_BUILD_SAMPLES)
add_subdirectory(samples/cpp/PrintQuoteEvents)
add_subdirectory(samples/cpp/PublishProfiles)
add_subdirectory(samples/cpp/DxFeedSample)
add_subdirectory(samples/cpp/WriteTapeFile)
add_subdirectory(samples/cpp/ConvertTapeFile)
Expand Down
4 changes: 2 additions & 2 deletions DEPENDENCIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Compile-time

- [dxFeed Graal Native SDK](https://github.com/dxFeed/dxfeed-graal-native-sdk) v1.1.6
- [dxFeed Graal Native SDK](https://github.com/dxFeed/dxfeed-graal-native-sdk) v1.1.16
- [Boost](https://github.com/boostorg/boost) v1.84.0
- Boost.Stacktrace 1.0
- [utfcpp](https://github.com/nemtrif/utfcpp) v3.2.3
Expand All @@ -24,7 +24,7 @@
- addr2line \[opt] (Diagnostic backtraces)
## Run-time

- [dxFeed Graal Native SDK](https://github.com/dxFeed/dxfeed-graal-native-sdk) v1.1.6
- [dxFeed Graal Native SDK](https://github.com/dxFeed/dxfeed-graal-native-sdk) v1.1.16
- [doctest](https://github.com/doctest/doctest) v2.4.11 (Tests)


Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ versions):
is a simple demonstration of how to get Instrument Profiles
- [x] [DxFeedLiveIpfSample](https://github.com/dxFeed/dxfeed-graal-cxx-api/blob/main/samples/cpp/DxFeedLiveIpfSample/src/main.cpp)
is a simple demonstration of how to get live updates for Instrument Profiles
- [x] [PublishProfiles](https://github.com/dxFeed/dxfeed-graal-cxx-api/blob/main/samples/cpp/PublishProfiles/src/main.cpp) is a simple demonstration of how to publish market events
- [x] [ScheduleSample](https://github.com/dxFeed/dxfeed-graal-cxx-api/blob/main/samples/cpp/ScheduleSample/src/main.cpp)
is a simple demonstration of how to get various scheduling information for instruments
- [x] [OnDemandSample](https://github.com/dxFeed/dxfeed-graal-cxx-api/blob/main/samples/cpp/OnDemandSample/src/main.cpp)
Expand Down
3 changes: 3 additions & 0 deletions include/dxfeed_graal_cpp_api/api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251 4996)
#include "exceptions/GraalException.hpp"

#include "isolated/api/IsolatedDXEndpoint.hpp"
#include "isolated/api/IsolatedDXPublisher.hpp"
#include "isolated/api/IsolatedDXPublisherObservableSubscription.hpp"
#include "isolated/api/osub/IsolatedObservableSubscriptionChangeListener.hpp"
#include "isolated/internal/IsolatedString.hpp"
#include "isolated/internal/IsolatedTimeFormat.hpp"
#include "isolated/internal/IsolatedTools.hpp"
Expand Down
1 change: 1 addition & 0 deletions include/dxfeed_graal_cpp_api/api/ApiModule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251)
#include "DXEndpoint.hpp"
#include "DXFeed.hpp"
#include "DXFeedSubscription.hpp"
#include "DXPublisherObservableSubscription.hpp"
#include "DXPublisher.hpp"
#include "FilteredSubscriptionSymbol.hpp"
#include "osub/OsubModule.hpp"
Expand Down
3 changes: 0 additions & 3 deletions include/dxfeed_graal_cpp_api/api/DXFeed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,6 @@ struct DXFCPP_EXPORT DXFeed : SharedEntity {

private:
JavaObjectHandle<DXFeed> handle_;

std::unordered_set<std::shared_ptr<DXFeedSubscription>> subscriptions_{};

static std::shared_ptr<DXFeed> create(void *feedHandle);

protected:
Expand Down
3 changes: 1 addition & 2 deletions include/dxfeed_graal_cpp_api/api/DXFeedSubscription.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251)
#include "../internal/Common.hpp"
#include "../internal/Handler.hpp"
#include "../internal/JavaObjectHandle.hpp"
#include "../symbols/StringSymbol.hpp"
#include "../symbols/SymbolWrapper.hpp"
#include "osub/WildcardSymbol.hpp"

#include <concepts>
#include <memory>
Expand Down Expand Up @@ -693,6 +691,7 @@ class DXFCPP_EXPORT DXFeedSubscription : public SharedEntity {
/**
* Returns `true` if this subscription contains the corresponding event type.
*
* @param eventType The type of event that is checked.
* @return `true` if this subscription contains the corresponding event type.
*
* @see DXFeedSubscription::getEventTypes()
Expand Down
33 changes: 29 additions & 4 deletions include/dxfeed_graal_cpp_api/api/DXPublisher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ DXFCPP_BEGIN_NAMESPACE

struct DXEndpoint;
class EventTypeEnum;
class ObservableSubscription;
struct ObservableSubscription;

/**
* Provides API for publishing of events to local or remote DXFeed.
Expand Down Expand Up @@ -69,13 +69,15 @@ struct DXFCPP_EXPORT DXPublisher : SharedEntity {
friend struct DXEndpoint;

private:
mutable std::recursive_mutex mutex_{};
JavaObjectHandle<DXPublisher> handle_;
std::shared_ptr<ObservableSubscription> subscription_{};

static std::shared_ptr<DXPublisher> create(void *handle);
void publishEventsImpl(void *graalEventsList) const noexcept;

protected:
DXPublisher() noexcept : handle_{} {
DXPublisher() noexcept {
if constexpr (Debugger::isDebug) {
Debugger::debug("DXPublisher()");
}
Expand Down Expand Up @@ -184,7 +186,7 @@ struct DXFCPP_EXPORT DXPublisher : SharedEntity {
/**
* Publishes events to the corresponding feed.
*
* @param collection The collection of events to publish.
* @param events The collection of events to publish.
*/
void publishEvents(std::initializer_list<std::shared_ptr<EventType>> events) noexcept {
publishEvents(std::begin(events), std::end(events));
Expand Down Expand Up @@ -217,7 +219,30 @@ struct DXFCPP_EXPORT DXPublisher : SharedEntity {
EventMapper::freeGraalList(list);
}

std::shared_ptr<ObservableSubscription> getSubscription(const EventTypeEnum &);
/**
* Returns observable set of subscribed symbols for the specified event type.
* Note, that subscription is represented by SymbolWrapper symbols. Check the type of each symbol
* in ObservableSubscription using SymbolWrapper::isStringSymbol(), SymbolWrapper::isWildcardSymbol(),
* SymbolWrapper::isIndexedEventSubscriptionSymbol(), SymbolWrapper::isTimeSeriesSubscriptionSymbol(),
* SymbolWrapper::isCandleSymbol().
*
* <p> The set of subscribed symbols contains WildcardSymbol::ALL if and
* only if there is a subscription to this wildcard symbol.
*
* <p> If DXFeedTimeSeriesSubscription is used to subscribe to time-service of the events of this type, then
* instances of TimeSeriesSubscriptionSymbol class represent the corresponding subscription item.
*
* <p> The resulting observable subscription can generate repeated ObservableSubscriptionChangeListener::onSymbolsAdded_ notifications to
* its listeners for the same symbols without the corresponding ObservableSubscriptionChangeListener::onSymbolsRemoved_
* notifications in between them. It happens when subscription disappears, cached data is lost, and subscription
* reappears again. On each ObservableSubscriptionChangeListener::onSymbolsAdded_
* notification data provider shall @ref DXPublisher::publishEvents() "publish" the most recent events for
* the corresponding symbols.
*
* @param eventType The event type.
* @return Observable subscription for the specified event type.
*/
std::shared_ptr<ObservableSubscription> getSubscription(const EventTypeEnum &eventType);

std::string toString() const noexcept override;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2024 Devexperts LLC.
// SPDX-License-Identifier: MPL-2.0

#pragma once

#include "../internal/Conf.hpp"

DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251)

#include "../entity/EntityModule.hpp"
#include "../event/EventTypeEnum.hpp"
#include "../internal/JavaObjectHandle.hpp"
#include "osub/ObservableSubscription.hpp"

#include <memory>
#include <unordered_set>

DXFCPP_BEGIN_NAMESPACE

struct DXFCPP_EXPORT DXPublisherObservableSubscription : RequireMakeShared<DXPublisherObservableSubscription>,
ObservableSubscription {
static constexpr std::size_t FAKE_LISTENER_ID{static_cast<std::size_t>(-1)};

private:
inline static std::atomic<std::size_t> lastListenerId_{};

JavaObjectHandle<DXPublisherObservableSubscription> handle_;
std::unordered_map<std::size_t, std::shared_ptr<ObservableSubscriptionChangeListener>> listeners_;
std::recursive_mutex listenersMutex_{};

public:
DXPublisherObservableSubscription(LockExternalConstructionTag,
JavaObjectHandle<DXPublisherObservableSubscription> &&handle);
~DXPublisherObservableSubscription() override;

static std::shared_ptr<DXPublisherObservableSubscription>
create(JavaObjectHandle<DXPublisherObservableSubscription> &&handle);

bool isClosed() override;
std::unordered_set<EventTypeEnum> getEventTypes() override;
bool containsEventType(const EventTypeEnum &eventType) override;
std::size_t addChangeListener(std::shared_ptr<ObservableSubscriptionChangeListener> listener) override;
void removeChangeListener(std::size_t id) override;
};

DXFCPP_END_NAMESPACE

DXFCXX_DISABLE_MSC_WARNINGS_POP()
54 changes: 53 additions & 1 deletion include/dxfeed_graal_cpp_api/api/osub/ObservableSubscription.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,66 @@ DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251)

#include "../../event/IndexedEventSource.hpp"
#include "../../symbols/SymbolWrapper.hpp"
#include "ObservableSubscriptionChangeListener.hpp"

#include <cstdint>
#include <memory>
#include <unordered_set>
#include <utility>

DXFCPP_BEGIN_NAMESPACE

class ObservableSubscription {};
/**
* Observable set of subscription symbols.
*/
struct DXFCPP_EXPORT ObservableSubscription {
virtual ~ObservableSubscription() = default;

/**
* @return `true` if this subscription is closed.
* The observable subscription that is returned as a result of DXPublisher::getSubscription() is closed when the
* corresponding DXEndpoint is closed.
*/
virtual bool isClosed() = 0;

/**
* @return a set of event types for this subscription. The resulting set cannot be modified.
* The observable subscription that is returned as a result of DXPublisher::getSubscription() has a singleton set
* of event types.
*/
virtual std::unordered_set<EventTypeEnum> getEventTypes() = 0;

/**
* Returns `true` if this subscription contains the corresponding event type.
*
* @param eventType The type of event that is checked.
* @return `true` if this subscription contains the corresponding event type.
* @see #getEventTypes()
*/
virtual bool containsEventType(const EventTypeEnum &eventType) = 0;

/**
* Adds subscription change listener. This method does nothing if subscription is closed.
* Otherwise, it installs the corresponding listener and immediately
* invokes ObservableSubscriptionChangeListener::symbolsAdded() on the given listener while holding the lock for
* this subscription. This way the given listener synchronously receives existing subscription state and is
* synchronously notified on all changes in subscription afterwards.
*
* @param listener The subscription change listener.
* @return The listener id
*/
virtual std::size_t addChangeListener(std::shared_ptr<ObservableSubscriptionChangeListener> listener) = 0;

/**
* Removes subscription change listener by id. This method does nothing if the listener with the given id 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.
*
* @param id The subscription change listener id.
*/
virtual void removeChangeListener(std::size_t id) = 0;
};

DXFCPP_END_NAMESPACE

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) 2024 Devexperts LLC.
// SPDX-License-Identifier: MPL-2.0

#pragma once

#include "../../internal/Conf.hpp"

DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251)

#include "../../symbols/SymbolWrapper.hpp"

#include <memory>
#include <unordered_set>

DXFCPP_BEGIN_NAMESPACE

struct DXFCPP_EXPORT ObservableSubscriptionChangeListener : RequireMakeShared<ObservableSubscriptionChangeListener> {
explicit ObservableSubscriptionChangeListener(LockExternalConstructionTag);
~ObservableSubscriptionChangeListener() noexcept override;

static std::shared_ptr<ObservableSubscriptionChangeListener>
create(std::function<void(const std::unordered_set<SymbolWrapper> &symbols)> onSymbolsAdded);

static std::shared_ptr<ObservableSubscriptionChangeListener>
create(std::function<void(const std::unordered_set<SymbolWrapper> &symbols)> onSymbolsAdded,
std::function<void(const std::unordered_set<SymbolWrapper> &symbols)> onSymbolsRemoved,
std::function<void()> onSubscriptionClosed);

const JavaObjectHandle<ObservableSubscriptionChangeListener> &getHandle() const;

private:
mutable std::recursive_mutex mutex_{};
JavaObjectHandle<ObservableSubscriptionChangeListener> handle_;
SimpleHandler<void(const std::unordered_set<SymbolWrapper> &symbols)> onSymbolsAdded_{};
SimpleHandler<void(const std::unordered_set<SymbolWrapper> &symbols)> onSymbolsRemoved_{};
SimpleHandler<void()> onSubscriptionClosed_{};

struct Impl;

std::unique_ptr<Impl> impl_;
};

DXFCPP_END_NAMESPACE

DXFCXX_DISABLE_MSC_WARNINGS_POP()
Loading

0 comments on commit 0575d09

Please sign in to comment.