Robust Distributed System Nucleus (rDSN)  ver 1.0.0
Classes | Macros | Typedefs | Enumerations | Functions
Application and Framework Models

Overview

In rDSN, both applications and frameworks must implement a base abstract called dsn_app, which are registered into rDSN's service kernel via dsn_register_app.

Here is an example where we register two applications into rDSN; note we use the C++ wrappers atop our C API in this example.

int main(int argc, char** argv)
{
  // register all app types
  dsn::register_app<test_client>("test");
  dsn::register_app<test_server>("server");
  // run rDSN
  dsn_run(argc, argv, true);
  return 0;
}

After the applications and frameworks are registered, developers specify the concrete instances in config files, and rDSN creates them accordingly on start-up.

[apps.client]
arguments = localhost 20101  
delay_seconds = 1
pools = THREAD_POOL_DEFAULT
type = test
[apps.server]  
pools = THREAD_POOL_TEST_SERVER
ports = 20101  
type = server

Developers usually run this using ./app config.ini, or ./app for more options.

Classes

struct  dsn_app_learn_state
 
union  dsn_app_callbacks
 
struct  dsn_app
 
struct  dsn_app_info
 

Macros

#define DSN_APP_MASK_APP   0x01
 
#define DSN_APP_MASK_FRAMEWORK   0x02
 

Typedefs

typedef void *(* dsn_app_create) (const char *app_name, dsn_gpid id)
 
typedef dsn_error_t(* dsn_app_start) (void *app, int argc, char **argv)
 
typedef dsn_error_t(* dsn_app_destroy) (void *app, bool cleanup)
 
typedef void(* dsn_framework_rpc_request_handler) (void *app, dsn_gpid gpid, bool is_write_operation, dsn_message_t request)
 
typedef void(* dsn_app_on_batched_write_requests) (void *app, int64_t decree, dsn_message_t *requests, int request_count)
 
typedef int(* dsn_app_get_physical_error) (void *app)
 
typedef dsn_error_t(* dsn_app_sync_checkpoint) (void *app, int64_t last_decree)
 
typedef dsn_error_t(* dsn_app_async_checkpoint) (void *app, int64_t last_decree)
 
typedef int64_t(* dsn_app_get_last_checkpoint_decree) (void *app)
 
typedef dsn_error_t(* dsn_app_prepare_get_checkpoint) (void *app, void *request_buffer, int capacity, int *used_size)
 
typedef dsn_error_t(* dsn_app_get_checkpoint) (void *app, int64_t learn_start_decree, int64_t local_last_decree, void *learn_request, int learn_request_size, dsn_app_learn_state *learn_state_buffer, int capacity)
 
typedef dsn_error_t(* dsn_app_apply_checkpoint) (void *app, dsn_chkpt_apply_mode mode, int64_t local_last_decree, const dsn_app_learn_state *learn_state)
 
typedef dsn_error_t(* dsn_app_bridge_t) (int, const char **)
 
typedef union dsn_app_callbacks dsn_app_callbacks
 
typedef struct dsn_app dsn_app
 
typedef struct dsn_app_info dsn_app_info
 

Enumerations

enum  dsn_chkpt_apply_mode { DSN_CHKPT_COPY, DSN_CHKPT_LEARN }
 

Functions

DSN_API bool dsn_register_app (dsn_app *app_type)
 
DSN_API bool dsn_get_app_callbacks (const char *name, dsn_app_callbacks *callbacks)
 
DSN_API bool dsn_mimic_app (const char *app_name, int index)
 
DSN_API bool dsn_run_config (const char *config, bool sleep_after_init DEFAULT(false))
 
DSN_API void dsn_run (int argc, char **argv, bool sleep_after_init DEFAULT(false))
 
NORETURN DSN_API void dsn_exit (int code)
 
DSN_API int dsn_get_all_apps (dsn_app_info *info_buffer, int count)
 
DSN_API bool dsn_get_current_app_info (dsn_app_info *app_info)
 
DSN_API dsn_app_infodsn_get_app_info_ptr (dsn_gpid gpid DEFAULT(dsn_gpid{0}))
 
DSN_API const char * dsn_get_app_data_dir (dsn_gpid gpid DEFAULT(dsn_gpid{0}))
 
DSN_API void dsn_app_loader_signal ()
 
DSN_API void dsn_app_loader_wait ()
 

Typedef Documentation

typedef void*(* dsn_app_create) (const char *app_name, dsn_gpid id)

callback to create the app context

Parameters
app_nametype name registered on dsn_register_app
idassigned global partition id
Returns
the app context used by other APIs to reference this application instance
typedef dsn_error_t(* dsn_app_start) (void *app, int argc, char **argv)

callback to run the app with the app context, similar to main(argc, argv)

Parameters
appcontext returned by dsn_app_create
argcas in traditional main(argc, argv)
argvas in traditional main(argc, argv)
Returns
error code for app start
typedef dsn_error_t(* dsn_app_destroy) (void *app, bool cleanup)

callback to stop and destroy the app

Parameters
appcontext returned by dsn_app_create
cleanupwhether to cleanup the state belonging to this app
Returns
error code for app destroy
typedef void(* dsn_framework_rpc_request_handler) (void *app, dsn_gpid gpid, bool is_write_operation, dsn_message_t request)

callback for framework to handle incoming rpc request, implemented by frameworks

Parameters
appcontext returned by dsn_app_create
gpidglobal partition id
is_write_operationwhether the incoming rpc reqeust is a write operation or not
requestincoming rpc request message
typedef void(* dsn_app_on_batched_write_requests) (void *app, int64_t decree, dsn_message_t *requests, int request_count)

batched rpc request from frameworks, used by frameworks, implemented by apps

Parameters
appcontext returned by dsn_app_create
decreesequence number for this request batch (when request batches are sent to the apps in order)
requestsincoming rpc request array ptr
request_countrequest count in this array
typedef int(* dsn_app_get_physical_error) (void *app)

get physical error (e.g., disk failure) from the app, used by frameworks, implemented by apps

Parameters
appcontext returned by dsn_app_create
Returns
physical error code, e.g., disk failure, that is not always reproducible on another machine with the same input
typedef dsn_error_t(* dsn_app_sync_checkpoint) (void *app, int64_t last_decree)

checkpoint the application synchronously, used by frameworks, implemented by apps

Parameters
appcontext returned by dsn_app_create
last_decreedecree of the last request/request-batch applied to this app
Returns
error code for the checkpoint operation
typedef dsn_error_t(* dsn_app_async_checkpoint) (void *app, int64_t last_decree)

checkpoint the application asynchronously, used by frameworks, implemented by apps

Parameters
appcontext returned by dsn_app_create
last_decreedecree of the last request/request-batch applied to this app
Returns
error code for the checkpoint operation
typedef int64_t(* dsn_app_get_last_checkpoint_decree) (void *app)

get the decree of last done checkpoint, used by frameworks, implemented by apps

Parameters
appcontext returned by dsn_app_create
Returns
decree of the last successfully done checkpoint (see last_decree parameter when doing checkpoint)
typedef dsn_error_t(* dsn_app_prepare_get_checkpoint) (void *app, void *request_buffer, int capacity, int *used_size)

learner prepares a get checkpoint request for better fitting the local state (e.g., for delta learning), the request will be used by dsn_app_get_checkpoint below, used by frameworks, implemented by apps

Parameters
appcontext returned by dsn_app_create
request_buffera memory buffer to be filled with a custom learn request
capcitybuffer size, in bytes
used_sizethis is the output value telling how many bytes are written by this custom learn request
Returns
error code for this operation
typedef dsn_error_t(* dsn_app_get_checkpoint) (void *app, int64_t learn_start_decree, int64_t local_last_decree, void *learn_request, int learn_request_size, dsn_app_learn_state *learn_state_buffer, int capacity)

get checkpoint information from learnee, used by frameworks, implemented by apps

can be used for both delta checkpoint [learn_start_decree, infinite), or full checkpoint.

Parameters
appcontext returned by dsn_app_create
learn_start_decreethe first start decree we want to get for this (if delta) checkpoint
local_last_decreedecree of the last request/request-batched that are applied locally
learn_requestlearn reqeust as prepared by dsn_app_prepare_get_checkpoint above
learn_request_sizebuffer size (in bytes) of the learn request
learn_state_bufferoutput learn state, see dsn_app_learn_state, to be used by dsn_app_apply_checkpoint below
capacityoutput learn state buffer size (in bytes)
Returns
error code for this operation
typedef dsn_error_t(* dsn_app_apply_checkpoint) (void *app, dsn_chkpt_apply_mode mode, int64_t local_last_decree, const dsn_app_learn_state *learn_state)

apply checkpoint from remote nodes, used by frameworks, implemented by apps

Parameters
appcontext returned by dsn_app_create
modesee dsn_chkpt_apply_mode
local_last_decreedecree of the last request/request-batched that are applied locally
learn_stateas returned from dsn_app_get_checkpoint above
Returns
error code for this operation
typedef struct dsn_app dsn_app

developers define the following dsn_app data structure, and passes it to rDSN through dsn_register_app so that the latter can manage the app appropriately.

Click into the corresponding types for what are the callback means.

Enumeration Type Documentation

checkpoint apply mode, see dsn_app_apply_checkpoint, used by frameworks

Enumerator
DSN_CHKPT_COPY 

simply a checkpoint from remote machine is given, do not change the local state

DSN_CHKPT_LEARN 

given a checkpoint from remote machine, prepare to change the local state

Function Documentation

DSN_API bool dsn_register_app ( dsn_app app_type)

register application/framework into rDSN runtime

Parameters
app_typerequried app type information.
Returns
true if it succeeds, false if it fails.

An example is as follows:

    dsn_app app;
    memset(&app, 0, sizeof(app));
    app.mask = DSN_APP_MASK_APP;
    strncpy(app.type_name, type_name, sizeof(app.type_name));
    app.layer1.create = service_app::app_create<TServiceApp>;
    app.layer1.start = service_app::app_start;
    app.layer1.destroy = service_app::app_destroy;
    dsn_register_app(&app);
DSN_API bool dsn_get_app_callbacks ( const char *  name,
dsn_app_callbacks callbacks 
)

get application callbacks registered into rDSN runtime

Parameters
nameapp type name
callbacksoutput callbacks
Returns
true it it exists, false otherwise
DSN_API bool dsn_mimic_app ( const char *  app_name,
int  index 
)

mimic an app as if the following execution in the current thread are executed in the target app's threads.

Parameters
app_namename of the application, note it is not the type name
indexone-based index of the application instances
Returns
true if it succeeds, false if it fails.

This is useful when we want to leverage 3rd party library into rDSN application and call rDSN service API in the threads that are created by the 3rd party code.

For cases we simply want to use a rDSN-based client library in a non-rDSN application, developers can simply set [core] enable_default_app_mimic = true in configuration file. See more details at enable_default_app_mimic.

Parameters
app_namespecified in config file as [apps.${app_name}]
indexstart from 1, when there are multiple instances
DSN_API bool dsn_run_config ( const char *  config,
bool sleep_after_init   DEFAULTfalse 
)

start the system with given configuration

Parameters
configthe configuration file for this run
sleep_after_initwhether to sleep after rDSN initialization, default is false
Returns
true if it succeeds, false if it fails.
DSN_API void dsn_run ( int  argc,
char **  argv,
bool sleep_after_init   DEFAULTfalse 
)

start the system with given arguments

Parameters
argcargc in C main convention
argvargv in C main convention
sleep_after_initwhether to sleep after rDSN initialization, default is false
Returns
true if it succeeds, false if it fails.

Usage: config-file [-cargs k1=v1;k2=v2] [-app_list app_name1;app_name2]

Examples:

  • config.ini -app_list replica@1 to start the first replica as a new process
  • config.ini -app_list replica to start ALL replicas (count specified in config) as a new process
  • config.ini -app_list replica -cargs replica-port=34556 to start ALL replicas with given port variable specified in config.ini
  • config.ini to start ALL apps as a new process

Note the argc, argv folllows the C main convention that argv[0] is the executable name.

NORETURN DSN_API void dsn_exit ( int  code)

exit the process with the given exit code

Parameters
codeexit code for the process

rDSN runtime does not provide elegant exit routines. Thereafter, developers call dsn_exit to exit the current process to avoid exceptions happending during normal exit.

DSN_API int dsn_get_all_apps ( dsn_app_info info_buffer,
int  count 
)

get rDSN application (instance)s information in the current process

Parameters
info_bufferbuffer for storing information data.
countcapacity of the buffer
Returns
how many rDSN application( instance)s are running in the current processs.

The returned value may be larger than count - in this casse, developers need to allocate a new buffer that is enough to hold the information of returned number of applications.

DSN_API bool dsn_get_current_app_info ( dsn_app_info app_info)

get current rDSN application information.

Parameters
app_infobuffer for storing information data.
Returns
true if it succeeds, false if the current thread does not belong to any rDSN app.
DSN_API const char* dsn_get_app_data_dir ( dsn_gpid gpid   DEFAULTdsn_gpid{0})

get current application data dir.

Returns
null if it fails, else a pointer to the data path string.
DSN_API void dsn_app_loader_signal ( )

signal the application loader that application types are registered.

in rDSN, app types must be registered via dsn_app_register. before dsn_run is invoked. in certain cases, a synchonization is needed to ensure this order. for example, we want to register an app role in python while the main program is in C++ to call dsn_run. in this case, we need to do as follows (in C++)

   new thread([]{
      [ python program
          dsn_app_register(...)
          dsn_app_loader_signal()
      ]
   });
   dsn_app_loader_wait();
   dsn_run(...)
   ].
DSN_API void dsn_app_loader_wait ( )

wait signal from dsn_app_loader_signal.