Add SDL developer and user guides 84/2084/3
authorTimo Tietavainen <timo.tietavainen@nokia.com>
Fri, 20 Dec 2019 08:52:49 +0000 (10:52 +0200)
committerTimo Tietavainen <timo.tietavainen@nokia.com>
Fri, 3 Jan 2020 18:14:40 +0000 (20:14 +0200)
Add the first versions of SDL Developer and User guides, which will
be published on the ORAN SC documentation page (under RIC project):
https://docs.o-ran-sc.org.

Signed-off-by: Timo Tietavainen <timo.tietavainen@nokia.com>
Change-Id: Ic23568b44a1560ba59a5466aef2993f95d723894

docs/_static/backend_data_storage.png [new file with mode: 0644]
docs/_static/sdl_intro.png [new file with mode: 0644]
docs/_static/sdl_namespaces.png [new file with mode: 0644]
docs/_static/simple_notifications.png [new file with mode: 0644]
docs/developer-guide.rst [new file with mode: 0644]
docs/index.rst
docs/release-notes.rst
docs/user-guide.rst [new file with mode: 0644]
include/sdl/asyncstorage.hpp
include/sdl/syncstorage.hpp

diff --git a/docs/_static/backend_data_storage.png b/docs/_static/backend_data_storage.png
new file mode 100644 (file)
index 0000000..e01a311
Binary files /dev/null and b/docs/_static/backend_data_storage.png differ
diff --git a/docs/_static/sdl_intro.png b/docs/_static/sdl_intro.png
new file mode 100644 (file)
index 0000000..164fac0
Binary files /dev/null and b/docs/_static/sdl_intro.png differ
diff --git a/docs/_static/sdl_namespaces.png b/docs/_static/sdl_namespaces.png
new file mode 100644 (file)
index 0000000..fd339f2
Binary files /dev/null and b/docs/_static/sdl_namespaces.png differ
diff --git a/docs/_static/simple_notifications.png b/docs/_static/simple_notifications.png
new file mode 100644 (file)
index 0000000..3d5f812
Binary files /dev/null and b/docs/_static/simple_notifications.png differ
diff --git a/docs/developer-guide.rst b/docs/developer-guide.rst
new file mode 100644 (file)
index 0000000..b8dc8e1
--- /dev/null
@@ -0,0 +1,300 @@
+..
+..  Copyright (c) 2019 AT&T Intellectual Property.
+..  Copyright (c) 2019 Nokia.
+..
+..  Licensed under the Creative Commons Attribution 4.0 International
+..  Public License (the "License"); you may not use this file except
+..  in compliance with the License. You may obtain a copy of the License at
+..
+..    https://creativecommons.org/licenses/by/4.0/
+..
+..  Unless required by applicable law or agreed to in writing, documentation
+..  distributed under the License is distributed on an "AS IS" BASIS,
+..  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+..
+..  See the License for the specific language governing permissions and
+..  limitations under the License.
+..
+
+
+###############
+Developer Guide
+###############
+
+.. raw:: pdf
+
+   PageBreak
+
+.. contents::
+   :depth: 3
+   :local:
+
+.. raw:: pdf
+
+   PageBreak
+
+Introduction
+************
+
+This is the developer guide of O-RAN SC SDL C++ library.
+SDL implementation downloading (execute command in such directory where you want
+to download SDL repository).
+
+Without commit hook::
+
+    git clone "https://gerrit.o-ran-sc.org/r/ric-plt/sdl"
+
+With commit hook::
+
+    git clone "https://gerrit.o-ran-sc.org/r/ric-plt/sdl" && (cd "sdl" && mkdir -p .git/hooks && curl -Lo `git rev-parse --git-dir`/hooks/commit-msg https://gerrit.o-ran-sc.org/r/tools/hooks/commit-msg; chmod +x `git rev-parse --git-dir`/hooks/commit-msg)
+
+
+SDL has only few dependencies to other components and therefore SDL should be
+quite simple to build and install to almost any modern Linux environment by
+following instructions below.
+
+If not otherwise mentioned, commands in this document are executed in the
+directory where the SDL repository has been cloned into.
+
+.. raw:: pdf
+
+   PageBreak
+
+Compilation
+***********
+
+**Dependencies**
+
+C++ compiler supporting C++14 is required for compiling SDL.
+
+Currently, the following library is required while building:
+
+* boost
+* hiredis
+* doxygen (optional)
+
+Commands to install dependent packages in Fedora::
+
+    sudo dnf install boost-devel
+    sudo dnf install hiredis-devel
+    sudo dnf install doxygen
+
+Commands to install dependent packages in Debian/Ubuntu::
+
+    sudo apt install libboost-all-dev
+    sudo apt install libhiredis-dev
+    sudo apt install doxygen
+
+**Compilation in the Source Directory**::
+
+    ./autogen.sh
+    ./configure
+    make all
+    make test
+
+**Compilation in a Separate Build Directory**
+
+Both *configure* and *make* can be executed in a separate directory
+(or directories) for keeping the source directory clean or for testing
+different configuration options in parallel. For example::
+
+    ./autogen.sh
+    mkdir build
+    cd build
+    ../configure
+    make all
+    make test
+
+Note that if you compile SDL this way, all coming *configure* and *make*
+commands are executed in the build directory like above.
+
+.. raw:: pdf
+
+   PageBreak
+
+Installation
+************
+
+By default the shared library is installed to */usr/local/lib* and headers into
+to */usr/local/include*. If this is not desired, then provide different path
+when running *configure*, for example::
+
+    ./configure --prefix=$HOME
+
+Note that *configure* command allows plethora of additional options. For more
+info::
+
+    ./configure --help
+
+After configuration has been done, run::
+
+    make install
+
+.. raw:: pdf
+
+   PageBreak
+
+.. _building_sdl_api_doc:
+
+Building SDL API Document
+*************************
+
+SDL API Documentation is a Doxygen document generated from SDL public header
+files.
+
+One can generate Doxygen documentation locally by running commands::
+
+    ./autogen.sh
+    ./configure
+    make doxygen-doc
+
+in the directory where the SDL repository has been cloned to.
+
+
+By default make doxygen-doc creates HTML, PDF and PS documents (if the needed
+tools are available, check the output of *./configure* command to get the names
+of missing tools). The documents are created to (paths are relative to the
+directory where the SDL repository has been cloned to):
+
+* doxygen-doc/html/index.html
+* doxygen-doc/shareddatalayer.pdf
+* doxygen-doc/shareddatalayer.ps
+
+
+Creation of different document formats can be controlled with various
+--enable-doxygen-* and --disable-doxygen-* configuration options. For example
+if only HTML document is needed, then run::
+
+    ./configure --disable-doxygen-pdf --disable-doxygen-ps
+    make doxygen-doc
+
+.. raw:: pdf
+
+   PageBreak
+
+Running Tests
+*************
+
+Unit Tests
+==========
+
+Unit tests are compiled and executed by simply running::
+
+    make test
+
+By default all unit tests are executed. If *valgrind* is installed, then by
+default unit test execution is analyzed with *valgrind*.
+
+Running specific test cases can be achieved by using *GTEST_FILTER* environment
+variable. For example::
+
+    make test GTEST_FILTER=AsyncStorageTest*
+
+If *valgrind* is not desired (even if installed), then it can be disabled with
+*USE_VALGRIND* environment variable::
+
+    make test USE_VALGRIND=false
+
+Additional *valgrind* arguments can be specified with *VALGRIND_EXTRA_ARGS*
+environment variable. For example::
+
+    make test VALGRIND_EXTRA_ARGS='--track-fds=yes --log-file=mylog.txt'
+
+It is also possible to use the *testrunner* binary directly (after it has been
+compiled). The *testrunner* binary supports all the command line options gtest
+supports, for example::
+
+    make testrunner
+    ./testrunner --help
+    ./testrunner
+    ./testrunner --gtest_filter=AsyncStorageTest*
+
+Functional Tests
+================
+
+Functional tests are not yet available.
+
+.. raw:: pdf
+
+   PageBreak
+
+Debugging SDL Binaries
+**********************
+
+The testrunner and other binaries created by make into the working
+directory are not real binaries but shell scripts (generated by automake)
+used for running the real binaries. The real binaries are in .libs directory.
+Normally this is not important, but when using gdb or other debugger/analyzer
+tools it is important to use the real binary instead of the generated shell
+script.
+
+Examples below demonstrate how one can run testrunner binary (unit tests) in
+gdb debugger::
+
+    LD_LIBRARY_PATH=.libs gdb --args .libs/testrunner
+    LD_LIBRARY_PATH=.libs gdb --args .libs/testrunner --gtest_filter=AsyncStorageTest*
+
+.. raw:: pdf
+
+   PageBreak
+
+Redis
+*****
+
+When Redis type backend data storage is used, SDL requires Redis v4.0 or
+greater. Older versions do not support extension modules.
+
+Redis Modules
+=============
+
+When Redis type backend data storage is used, SDL requires that the following
+Redis extension commands have been installed to runtime environment:
+
+* MSETPUB
+* SETIE
+* SETIEPUB
+* SETNXPUB
+* DELPUB
+* DELIE
+* DELIEPUB
+
+Implementation for these commands is produced by RIC DBaaS. In official RIC
+deployments these commands are installed by DBaaS service to Redis
+container(s). In development environment you may want install commands
+manually to pod/container which is running Redis.
+
+**Manual Redis module installing**
+
+Redis module implementation downloading (execute command in such directory
+where you want to download redis module implementation)::
+
+    git clone "https://gerrit.o-ran-sc.org/r/ric-plt/dbaas"
+
+Installation to default system directory::
+
+    cd redismodule
+    ./autogen.sh
+    ./configure
+    make install
+
+Following line should be added to *redis.conf* file::
+
+    loadmodule <path>/libredismodule.so
+
+<path> should be replaced to match library installation directory path.
+
+*redis-server* must be restarted after configuration file update.
+
+Notice that *redis-server* takes path to configuration file as an argument.
+If not given, *redis-server* will start with default parameter values and above
+made *loadmodule* option is not effective. Refer to::
+
+    redis-server --help
+
+SDL API will check in connection setup phase that all required Redis extension
+commands are available, if not then execution is aborted and error log is
+written to identify which commands are missing.
+
+.. raw:: pdf
+
+   PageBreak
index 4e34b9a..1e66a01 100644 (file)
@@ -23,6 +23,8 @@ Welcome to O-RAN Shared Data Layer (SDL) in C++ Documentation
    :caption: Contents:
 
    overview.rst
+   user-guide.rst
+   developer-guide.rst
    release-notes.rst
 
 * :ref:`genindex`
index 17ce65e..2efeb12 100644 (file)
@@ -15,7 +15,7 @@
 ..  limitations under the License.
 ..
 
-Release-Notes
+Release Notes
 =============
 
 This document provides the release notes for O-RAN SC Amber release of
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
new file mode 100644 (file)
index 0000000..ed75ce1
--- /dev/null
@@ -0,0 +1,519 @@
+..
+..  Copyright (c) 2019 AT&T Intellectual Property.
+..  Copyright (c) 2019 Nokia.
+..
+..  Licensed under the Creative Commons Attribution 4.0 International
+..  Public License (the "License"); you may not use this file except
+..  in compliance with the License. You may obtain a copy of the License at
+..
+..    https://creativecommons.org/licenses/by/4.0/
+..
+..  Unless required by applicable law or agreed to in writing, documentation
+..  distributed under the License is distributed on an "AS IS" BASIS,
+..  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+..
+..  See the License for the specific language governing permissions and
+..  limitations under the License.
+..
+
+
+##########
+User Guide
+##########
+
+.. raw:: pdf
+
+   PageBreak
+
+.. contents::
+   :depth: 3
+   :local:
+
+.. raw:: pdf
+
+   PageBreak
+
+Introduction
+************
+
+This is the user guide of O-RAN SC SDL C++ library.
+Shared Data Layer (SDL) provides a lightweight, high-speed interface (API) for
+accessing shared data storage. SDL can be used for storing and sharing any
+data. Data can be shared at VNF level. One typical use case for SDL is sharing
+the state data of stateful application processes. Thus enabling stateful
+application processes to become stateless, conforming with, e.g., the
+requirements of the fifth generation mobile networks.
+
+Figure below illustrates some main points of SDL:
+
+.. image:: ./_static/sdl_intro.png
+    :align: center
+    :alt: SDL introduction
+
+SDL has been implemented in many languages:
+
+* C++ Linux shared library
+* Golang package
+* Python package
+
+This document focuses on C++ implementation of SDL but general principles are
+the same in all implementations.
+
+.. raw:: pdf
+
+   PageBreak
+
+Key Concepts
+************
+
+**Backend Data Storage**
+
+Backend data storage refers to data storage technology behind SDL API which
+handles the actual data storing. SDL API hides the backend data storage
+implementation from SDL API clients, and therefore backend data storage
+technology can be changed without affecting SDL API clients. Currently, Redis
+database is the most commonly used backend data storage implementation.
+
+Figure below illustrates how SDL API hides backend data storage technology
+from application:
+
+.. image:: ./_static/backend_data_storage.png
+    :align: center
+    :alt: SDL API hides backend data storage technology from application
+
+`SDL Deployment section <#sdl-deployment>`_ provides further information
+about backend data storage deployment options.
+
+**Namespace**
+
+Namespaces provide data isolation within SDL data storage. That is, data in
+certain namespace is isolated from the data in other namespaces. Each SDL
+client uses one or more namespaces.
+
+Namespaces can be used, for example, to isolate data belonging to different
+use cases.
+
+Figure below shows an example of the SDL namespace concept. There are two SDL
+clients, both accessing SDL backend data storage using an SDL API instance
+(C++ object). Client 1 uses both namespaces: A and B, while client 2 uses only
+namespace: B. Therefore, data in the namespace: A is visible only to client 1
+and data in namespace: B is shared between clients 1 and 2:
+
+.. image:: ./_static/sdl_namespaces.png
+    :align: center
+    :alt: SDL namespace concept example
+
+Namespace management is planned to be moved under a managing entity which
+enforces some control over how the namespaces are created. For now, however,
+namespace naming needs to be manually coordinated between clients.
+
+**Keys and Data**
+
+Clients save key-data pairs. Data is passed as byte vectors. SDL stores the
+data as it is. Any structure that this data may have (e.g. a serialized JSON)
+is meaningful only to the client itself. Clients are responsible for managing
+the keys. As namespaces provide data isolation, keys in different namespaces
+always access different data.
+
+.. raw:: pdf
+
+   PageBreak
+
+APIs
+****
+
+SDL provides currently following APIs:
+
+* Asynchronous API for accessing SDL storage *shareddatalayer::AsyncStorage*
+* Synchronous API for accessing SDL storage shareddatalayer::SyncStorage
+
+Same SDL client can use one or more SDL APIs. There should rarely be need to
+create several instances of the same SDL API though. All individual operations
+done using SDL API functions are targeted to one namespace (accessing several
+namespaces requires multiple operations).
+
+SDL API functions are not thread-safe, meaning that same SDL instance must
+not be shared between multiple threads without explicit locking in SDL client.
+
+SDL API functions are atomic unless otherwise indicated. Indication of the
+non-atomic behavior of certain function can be found from one or many of the
+following:
+
+* Function name
+* Function parameters
+* Function doxygen documentation (see below)
+
+Refer to doxygen generated SDL API documentation below for further information
+about SDL APIs and the functions they contain.
+
+Doxygen Generated SDL API Documentation
+=======================================
+
+Pre-built online version of SDL API Doxygen documentation is not yet available.
+
+Doxygen documentation can be generated manually. Follow instructions found from
+:ref:`SDL developer guide <building_sdl_api_doc>`.
+
+.. raw:: pdf
+
+   PageBreak
+
+Building Clients Using SDL
+**************************
+
+SDL API functions can be used by including SDL public headers and by linking
+SDL shared library.
+
+The necessary compilation and linker flags can be acquired with the
+*pkg-config* tool::
+
+    pkg-config --cflags libsdl
+    pkg-config --libs libsdl
+
+SDL internal implementation uses C++14, thus SDL clients need to be build
+using a C++ compiler supporting C++14. However, SDL public API header files
+contain only features which are available in C++11, thus SDL clients do not
+need to be implemented (and compiled) using C++14 (C++11 is enough). The
+compiler just needs to have support for C++14.
+
+.. raw:: pdf
+
+   PageBreak
+
+Using SDL in Application Pod
+****************************
+
+SDL binary artifacts including Debian (.deb) and RPM Package Manager (.rpm)
+packages are available in O-RAN-SC PackageCloud.io repository.
+
+In runtime environment SDL needs also a database backend service, currently
+SDL supports only Redis database. Recommended solution is to use DBaaS
+component of the official RIC platform deployment.
+
+**Deploying SDL database backend with DBaaS service in the RIC**
+
+Download RIC deployment artifacts::
+
+    git clone "https://gerrit.o-ran-sc.org/r/it/dep"
+
+The **ric-platform** directory contains Helm chart and scripts to deploy RIC
+platform components, including also DBaaS component.
+
+RIC DBaaS service must be running before starting application pod which is
+using SDL API. DBaaS defines environment variables which are used to contact
+DBaaS service (offering backend for SDL). Those environment variables are
+exposed inside application container only if DBaaS service is running when
+application container is started. Refer to
+`Database Backend Configuration section <#database-backend-configuration>`_,
+for information about available environment variables.
+You may test SDL connectivity to its backend with the *sdltool* command inside
+your application container::
+
+    sdltool test-connectivity
+
+*sdltool* comes in SDL binary artifacts which are available in O-RAN-SC
+PackageCloud.io repository.
+
+For more information, see also `README <https://gerrit.o-ran-sc.org/r/gitweb?p=ric-plt/dbaas.git;a=blob;f=README.md;h=6391fc45ea762a5b606dcf9f867fac8087b1222f;hb=HEAD>`_
+file of the *dbaas* O-RAN-SC gerrit repository.
+
+.. raw:: pdf
+
+   PageBreak
+
+Configuration
+*************
+
+Certain aspects in SDL functionality can be configured by using environment
+variables.
+
+Database Backend Configuration
+==============================
+
+Database backend configuration can be used to configure, to which database
+backend SDL instance connects. A list of available environment variables to
+configure database backend:
+
+* DBAAS_SERVICE_HOST
+* DBAAS_SERVICE_PORT
+* DBAAS_SERVICE_SENTINEL_PORT
+* DBAAS_MASTER_NAME
+
+After DBaaS service is installed, environment variables are exposed to
+application containers. SDL library will automatically use these environment
+variables. If DBaaS service is not used, above environment variables needs to
+be set manually so that SDL backend can connect to correct database.
+
+**Examples**
+
+An example how environment variables can be set in bash shell, when standalone
+Redis server is running in a Kubernetes Pod with k8s service name of *dbaas* and
+port *6379*::
+
+   export DBAAS_SERVICE_HOST=dbaas
+   export DBAAS_SERVICE_PORT=6379
+
+Besides hostname, IPv4 and IPv6 addresses can be set to *DBAAS_SERVICE_HOST*.
+
+An example how environment variables can be set in bash shell, when Redis
+HA deployment is used. Please note that DBaaS does not support yet HA
+deployment option. Below environment variables are only in the form of an
+example to show how HA deployment would be configured::
+
+   export DBAAS_MASTER_NAME=my-master-sentinel
+   export DBAAS_SERVICE_HOST=dbaas
+   export DBAAS_SERVICE_SENTINEL_PORT=23550
+
+.. raw:: pdf
+
+   PageBreak
+
+Errors
+******
+
+`Doxygen generated SDL API documentation <#doxygen-generated-sdl-api-documentation>`_
+describes which error codes are returned and which exceptions are thrown from
+each SDL API function. Generally, asynchronous SDL APIs return error codes and
+synchronous SDL APIs throw exceptions in error situations.
+
+Handling Error Codes Returned From Asynchronous SDL APIs
+========================================================
+
+Asynchronous SDL APIs return *std::error_code* based error codes in error
+situations. Typically, error code is returned as a parameter in the related
+callback function.
+
+Returned error code contains detailed information about the error which has
+occurred. This information is valuable for SDL developers in case the issue
+needs further investigation, but usually this information is too detailed for
+SDL client error handling logic. For SDL client error handling purposes SDL
+provides *shareddatalayer::error* constants and the returned *std::error_code*
+can be compared against these constants.
+
+Therefore SDL clients are recommended to store the returned *std::error_code*
+somewhere (for example to the log) and implement the error handling logic based
+on *shareddatalayer::error* constants. C++ code example below illustrates this:
+
+.. code-block:: c++
+
+    if (error)
+    {
+        log.error() << "SDL operation failed, error: " << error
+                    << " message: " << error.message() << std::endl;
+
+        if (error == shareddatalayer::Error::NOT_CONNECTED)
+            // Error handling logic for shareddatalayer::Error::NOT_CONNECTED
+        else if (error == shareddatalayer::Error::OPERATION_INTERRUPTED)
+            // Error handling logic for shareddatalayer::Error::OPERATION_INTERRUPTED
+        else if (error == shareddatalayer::Error::BACKEND_FAILURE)
+            // Error handling logic for shareddatalayer::Error::BACKEND_FAILURE
+        else if (error == shareddatalayer::Error::REJECTED_BY_BACKEND)
+            // Error handling logic for shareddatalayer::Error::REJECTED_BY_BACKEND
+    }
+
+*error* in the code block above is *std::error_code* type variable which is
+returned from some asynchronous SDL API function. *log* is a logging service
+what an SDL client is using. Note that this is a simple and incomplete example
+for demonstration purposes and not meant to be used as such in real
+environment. Complete error handling implementation depends on SDL client and
+SDL API function which returned the error. For example, in some cases common
+handling for several *shareddatalayer::error* constants might be sufficient.
+
+**Instructions for Error Handling Logic Implementation**
+
+Doxygen documentation contains detailed description for all
+shareddatalayer::Error constants. This information helps to design error
+handling logic for each shareddatalayer::Error constant. For example, following
+information can be found from there:
+
+* What has happened
+* Is data modified in the backend data storage
+* How to recover from error situation
+
+
+Handling Exceptions Thrown by Synchronous SDL APIs
+==================================================
+
+Synchronous SDL APIs throw exceptions in error situations. There are
+corresponding exceptions for all *shareddatalayer::error* constants returned
+by asynchronous APIs (see previous section). All exceptions thrown by SDL are
+derived from *shareddatalayer::Exception*.
+Therefore, a client can catch *shareddatalayer::Exception* in case the client
+wants to implement common handling for some SDL originated exceptions. Note
+that external services, which SDL uses, can throw exceptions which are not
+derived from *shareddatalayer::Exception*.
+
+Below is a C++ code example of a scenario where SDL client does common error
+handling for all exceptions thrown from synchronous SDL API:
+
+.. code-block:: c++
+
+    try
+    {
+        //Code which executes synchronous SDL API function
+    }
+    catch (const shareddatalayer::Exception& e)
+    {
+        log.error() << "SDL operation failed, error: " << e.what() << std::endl;
+        //Common error handling logic for all SDL errors
+    }
+    //Catch also non-SDL exceptions (like std::exception) if needed
+
+Below C++ code example has separate handling for shareddatalayer::BackendError
+exception and common handling for all other exceptions thrown by SDL:
+
+.. code-block:: c++
+
+    try
+    {
+        //Code which executes synchronous SDL API function
+    }
+    catch (const shareddatalayer::BackendError& e)
+    {
+        log.error() << "SDL operation failed, error: " << e.what() << std::endl;
+        //Error handling logic for BackendError
+    }
+    catch (const shareddatalayer::Exception& e)
+    {
+        log.error() << "SDL operation failed, error: " << e.what() << std::endl;
+        //Common error handling logic for all other SDL errors than BackendError
+    }
+    //Catch also non-SDL exceptions (like std::exception) if needed
+
+*log* is a logging service what an SDL client is using. Note that these are
+simple and incomplete examples for demonstration purposes and they are not
+meant to be used as such in real environment.
+
+**Instructions for Error Handling Logic Implementation**
+
+Doxygen documentation contains documentation for all exceptions thrown by SDL.
+This documentation contains information which helps to design error handling
+logic for each exception. For exceptions having corresponding error code,
+exception documentation is usually a reference to corresponding error code
+documentation.
+
+Each SDL API function, which throws exceptions, has a link to the documentation
+of those exceptions. This link can be found from the Doxygen documentation of
+given SDL API function.
+
+.. raw:: pdf
+
+   PageBreak
+
+SDL Properties
+**************
+
+This chapter discusses how certain general data storage related aspects work in
+SDL. Discussed subjects include, for example, concurrency control and data
+persistency.
+
+SDL Deployment
+==============
+
+Production environments are typically deployed so that SDL backend data storage
+and SDL clients are in different nodes (e.g. VM, container).
+
+There are two different supported deployment modes for SDL backend data
+storage:
+
+* Standalone (single DB node without redundancy)
+* Redundant (DB node pair working in master/slave redundancy model)
+
+SDL does not currently have any intelligent logic (e.g. dynamic scaling) on
+which storage node each namespace data is stored. This area might be developed
+further in the future.
+
+SDL does not prevent backend data storage to be deployed in the same node with
+the SDL client. Such deployments are, however, typically used only in
+development/testing type of environments.
+
+Concurrency Control
+===================
+
+SDL does not support transactions doing one or more units of work in ACID
+manner (pessimistic concurrency control).
+
+SDL supports optimistic concurrency control by providing Check and Set (CAS)
+type conditional functions. These conditional functions provide possibility
+to do certain data modification operations only if data value matches the SDL
+client's last known value. Thus a SDL client can check that someone else has
+not changed the data after it was read by the SDL client. If the data would
+have been changed, SDL does not do the modification operation and this is
+indicated to the SDL client. The SDL client can then decide how to handle the
+situation (for example read the latest data and retry modification).
+
+*AsyncStorage::setIfAsync* is an example of a conditional function discussed
+above. Other conditional functions exist as well.
+
+Data Persistency
+================
+
+Currently all data stored to SDL is stored to in-memory backend data storage.
+Meaning that, data is not preserved over DB node restart. DB node restart does
+not necessarily cause data loss for SDL client though. Refer to
+`SDL Deployment section <#sdl-deployment>`_, for information about SDL backend
+data storage redundancy models.
+
+.. raw:: pdf
+
+   PageBreak
+
+Best Practices
+**************
+
+This chapter gives recommendations on how to use SDL.
+
+Building Clients Using SDL
+==========================
+
+* Use *pkg-config* tool to acquire needed compilation and linking flags,
+  instead of hardcoding them. This ensures that flags are always up-to-date.
+  See more information from `here <#building-clients-using-sdl>`_.
+
+Using SDL APIs
+==============
+
+* SDL APIs are not thread-safe. If same SDL API instance is shared between
+  multiple threads, SDL client has to use explicit locking to ensure that only
+  one thread at time executes SDL API functions.
+* Each SDL instance establishes own connection to backend data storage, which
+  requires resources (how heavy this exactly is depends on used backend data
+  storage type). Thus, from performance point of view, only one SDL instance
+  per one SDL API should be used if reasonably possible. One SDL instance can
+  access multiple SDL namespaces when using *AsyncStorage* and *SyncStorage*
+  APIs.
+* Use waitReadyAsync() function before doing first operation via asynchronous
+  APIs to ensure that SDL and backend data storage are ready to handle
+  operations. See waitReadyAsync() function
+  `doxygen documentation <#doxygen-generated-sdl-api-documentation>`_
+  for corresponding asynchronous API for details.
+* Avoid using heavy search functions (for example: *AsyncStorage::findKeys()*).
+  Rather define your keys so that you know which keys should be read.
+
+Using SDL Namespaces
+====================
+
+* As namespace naming is currently on SDL client's responsibility, use enough
+  specific namespace names that same name is surely not used by someone else
+  (unless you want to share given namespace data with that someone else).
+* Data entities related to each other should be placed under the same
+  namespace (unless there is a good reason not to). For example, accessing
+  multiple data entities with one SDL operation is possible only for data
+  entities belonging to same namespace.
+* Identically named keys can be used in different namespaces. Creating own
+  namespaces for different use cases and unrelated data provides more freedom
+  into key name selection.
+
+Data Management
+===============
+
+* Writing or reading one big junk of data at once is more efficient than
+  writing/reading the same amount of data in small steps. For example, create a
+  key list and read it once, rather than reading each key in a loop.
+* If rolling upgrade needs to be supported, consider using Google Protocol
+  Buffers (or something similar) to make it possible to parse data which is
+  written by older or newer application version.
+
+.. raw:: pdf
+
+   PageBreak
index eb7342f..5c3cc6d 100644 (file)
@@ -292,7 +292,7 @@ namespace shareddatalayer
         using FindKeysAck = std::function<void(const std::error_code& error, const Keys& keys)>;
 
         /**
-         * Find all keys matching search pattern under the namespace. No prior knowledge about the keys in the given
+         * Find all keys matching search key prefix under the namespace. No prior knowledge about the keys in the given
          * namespace exists, thus operation is not guaranteed to be atomic or isolated.
          *
          * @param ns Namespace under which this operation is targeted.
index eff5032..684690b 100644 (file)
@@ -211,7 +211,7 @@ namespace shareddatalayer
                               const Data& data) = 0;
 
         /**
-         * Find all keys matching search pattern under the namespace. No prior knowledge about the keys in the given
+         * Find all keys matching search key prefix under the namespace. No prior knowledge about the keys in the given
          * namespace exists, thus operation is not guaranteed to be atomic or isolated.
          *
          * Exceptions thrown (excluding standard exceptions such as std::bad_alloc) are all derived from