From: Timo Tietavainen Date: Fri, 20 Dec 2019 08:52:49 +0000 (+0200) Subject: Add SDL developer and user guides X-Git-Tag: 1.2.1~11 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=02cf8dfcafb7380cda35beaa2aad783ffea87fa3;p=ric-plt%2Fsdl.git Add SDL developer and user guides 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 Change-Id: Ic23568b44a1560ba59a5466aef2993f95d723894 --- diff --git a/docs/_static/backend_data_storage.png b/docs/_static/backend_data_storage.png new file mode 100644 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 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 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 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 index 0000000..b8dc8e1 --- /dev/null +++ b/docs/developer-guide.rst @@ -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 /libredismodule.so + + 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 diff --git a/docs/index.rst b/docs/index.rst index 4e34b9a..1e66a01 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -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` diff --git a/docs/release-notes.rst b/docs/release-notes.rst index 17ce65e..2efeb12 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -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 index 0000000..ed75ce1 --- /dev/null +++ b/docs/user-guide.rst @@ -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 `. + +.. 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 `_ +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 diff --git a/include/sdl/asyncstorage.hpp b/include/sdl/asyncstorage.hpp index eb7342f..5c3cc6d 100644 --- a/include/sdl/asyncstorage.hpp +++ b/include/sdl/asyncstorage.hpp @@ -292,7 +292,7 @@ namespace shareddatalayer using FindKeysAck = std::function; /** - * 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. diff --git a/include/sdl/syncstorage.hpp b/include/sdl/syncstorage.hpp index eff5032..684690b 100644 --- a/include/sdl/syncstorage.hpp +++ b/include/sdl/syncstorage.hpp @@ -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