Keeping service data between reloads

Services can keep data between reloads in several ways. Note than if a service is purged, its data is deleted (both from the data directory and the registry).

Keeping data in the node registry

Python SDK has no built-in methods to work with the registry, however the registry can be still accessed under the local bus with calls to eva.registry.

Available registry RPC methods are described at https://yedb.bma.ai, section 3.3 (Mandatory methods).

The keys must be kept under eva/svc_data/<SVC_ID> only.

The following example contains a simple service which operates with data from the registry:

#!/opt/eva4/venv/bin/python3

__version__ = '0.0.1'

import evaics.sdk as sdk
import busrt
from evaics.sdk import pack, unpack


def mark_set_up(svc_id, rpc):
    payload = dict(key=f'eva/svc_data/{svc_id}/setup',
                   value=dict(completed=True))
    rpc.call('eva.registry', busrt.rpc.Request('key_set',
                                               pack(payload))).wait_completed()


def run():
    info = sdk.ServiceInfo(author='Bohemia Automation',
                           description='Registry example',
                           version=__version__)
    service = sdk.Service()
    service.init(info)

    # get registry "setup" key
    payload = dict(key=f'eva/svc_data/{service.id}/setup')
    try:
        result = unpack(
            service.rpc.call('eva.registry',
                             busrt.rpc.Request(
                                 'key_get',
                                 pack(payload))).wait_completed().get_payload())
        if result.get('completed') is not True:
            mark_set_up(service.id, service.rpc)
    except busrt.rpc.RpcException as e:
        if e.rpc_error_code == sdk.ERR_CODE_NOT_FOUND:
            # there is no key yet, create it
            mark_set_up(service.id, service.rpc)
        else:
            raise
    # increase service startup counter
    payload = dict(key=f'eva/svc_data/{service.id}/counter')
    counter = unpack(
        service.rpc.call('eva.registry',
                         busrt.rpc.Request(
                             'key_increment',
                             pack(payload))).wait_completed().get_payload())
    service.logger.info(f'The service has been started {counter} time(s)')
    service.block()


run()

Keeping data in files

The field “data_path” of the “service” object contains path to a directory where the service can store its data.

service = sdk.Service()
data_path = service.data_path

If the data path is None, it means that the service is started under “nobody” user and can not use the data path.

Note

To avoid permission problems, the service should always use its data path only after “service.drop_privileges()” method is called.