HLCC Documentation 3.0.0
Loading...
Searching...
No Matches
hlcc::oldbmux::CiiOldbDataPointAsync< T > Class Template Reference

CiiOldbDataPointAsync is a wrapper for class CiiOldbDataPoint, to allow asynchronous writes to the OLDB. All other methods (read etc) are delegating in the same thread, but could be made async as well in the future. More...

#include <ciiOldbDataPointAsync.hpp>

Classes

struct  OldbData
 Value type for data for buffering and writing to OLDB. This base class is used as an interface toward the client of CiiOldbDataPointAsync. More...
 
struct  OldbDataWithPromise
 Value type for data for buffering and writing to OLDB. This subclass is used internally by CiiOldbDataPointAsync. More...
 

Public Member Functions

 CiiOldbDataPointAsync (std::string name, std::shared_ptr< elt::oldb::CiiOldbDataPoint< T > > delegate, boost::asio::thread_pool &async_exec, const log4cplus::Logger &logger, std::size_t buffer_capacity=1)
 Constructor.
 
virtual ~CiiOldbDataPointAsync ()
 
std::shared_ptr< elt::oldb::CiiOldbDpValue< T > > ReadValue (bool check_bad_quality=true)
 
boost::future< typename CiiOldbDataPointAsync< T >::OldbData > WriteValue (const T &value, int64_t timestamp=elt::oldb::CiiOldbUtil::Now(), elt::oldb::CiiOldbDpQuality quality=elt::oldb::CiiOldbDpQuality::OK, bool is_disable_publishing=false)
 
boost::future< typename CiiOldbDataPointAsync< T >::OldbData > SetQuality (elt::oldb::CiiOldbDpQuality quality, bool is_disable_publishing=false)
 

Detailed Description

template<typename T>
class hlcc::oldbmux::CiiOldbDataPointAsync< T >

CiiOldbDataPointAsync is a wrapper for class CiiOldbDataPoint, to allow asynchronous writes to the OLDB. All other methods (read etc) are delegating in the same thread, but could be made async as well in the future.

Note that once a CiiOldbDataPoint has been wrapped by this class, it should no longer be used directly, because that would mean calling CiiOldbDataPoint method from 2 different threads (client thread and async pool worker thread).

CiiOldbDataPoint::SetQuality internally first reads the current value from OLDB and, without locking, later writes both value and quality data. This creates a race condition that could overwrite in the OLDB a new value that was set using the WriteValue method. Eventually CII may make SetQuality thread-safe, because it looks atomic, even though generally OLDB access is not meant to support transactions.

Design and optimizations used for async writing of value or quality:

  • We use an external thread pool for the async writes, which is shared across CiiOldbDataPointAsync instances. This helps to limit the number of threads that an application uses for async OLDB writes.
  • Async writing from separate threads is only necessary because the OLDB client API offers only sync writes. If it exposed the async writes feature that the underlying Redis database provides, then our CiiOldbDataPointAsync would be less useful.
  • When a client tries to write faster than the remote OLDB allows, then we drop intermediate writes and write as fast as possible, using only the latest data available at that time. This makes it necessary that the worker thread maintains access to the data queue, rather than separating it by just passing a copy of the data. As a consequence, we have to block the destructor ~CiiOldbDataPointAsync() until the worker thread has left its code, to avoid data access after destruction. Once the object is being destructed, no new write calls must be made.
  • Dopping of data is smart in the sense that it merges missing fields. If for example a record that writes a value but not a quality gets dropped, then the value is transferred to the newer record if that one has no value (but only a quality).
  • The async write methods return a future, so that the client can optionally wait for successful write, or can check for an exception such as data dropped (std::out_of_range)

Constructor & Destructor Documentation

◆ CiiOldbDataPointAsync()

template<typename T>
hlcc::oldbmux::CiiOldbDataPointAsync< T >::CiiOldbDataPointAsync ( std::string name,
std::shared_ptr< elt::oldb::CiiOldbDataPoint< T > > delegate,
boost::asio::thread_pool & async_exec,
const log4cplus::Logger & logger,
std::size_t buffer_capacity = 1 )

Constructor.

◆ ~CiiOldbDataPointAsync()

Member Function Documentation

◆ ReadValue()

template<typename T>
std::shared_ptr< elt::oldb::CiiOldbDpValue< T > > hlcc::oldbmux::CiiOldbDataPointAsync< T >::ReadValue ( bool check_bad_quality = true)

◆ SetQuality()

template<typename T>
boost::future< typename CiiOldbDataPointAsync< T >::OldbData > hlcc::oldbmux::CiiOldbDataPointAsync< T >::SetQuality ( elt::oldb::CiiOldbDpQuality quality,
bool is_disable_publishing = false )

◆ WriteValue()

template<typename T>
boost::future< typename CiiOldbDataPointAsync< T >::OldbData > hlcc::oldbmux::CiiOldbDataPointAsync< T >::WriteValue ( const T & value,
int64_t timestamp = elt::oldb::CiiOldbUtil::Now(),
elt::oldb::CiiOldbDpQuality quality = elt::oldb::CiiOldbDpQuality::OK,
bool is_disable_publishing = false )

Note that for using nested class CiiOldbDataPointAsync<T>::OldbData as a template parameter, the "typename" keyword has to be added. Somehow because OldbData depends on template parameter T only through its outer type CiiOldbDataPointAsync. See also upcoming C++ change http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0634r3.html


The documentation for this class was generated from the following files: