[Openais] Ideas for a cleaner/easier to use objdb API

Steven Dake sdake at redhat.com
Tue Jul 28 15:27:22 PDT 2009


On Wed, 2009-07-29 at 07:30 +1200, Angus Salkeld wrote:
> Hi
> 
> Here is a first attempt at an easier to use API for objdb.
> 
> 1) remove the need for parent_handles.

big improvement

> 2) Each object/key must have a unique name (as a string)
> 2.1) So no child objects named the same (service, logging,...)

need more thought around this as a use case

> 3) support persistent & runtime keys to better support IMM

this is good.  RUNTIME should probably be called "REPLICATED" or "SYNC"
something.:)

> 4) assume all objects/keys are synronised (no special attribute for it)

I prefer during creation of the object to specify whether it is
replicated or not.  This allows keys and objects for things like config
files not to be replicated (since that wouldn't make any sense anyway).
A key replication always follows the decision of the created parent.

A child object can't be created in replicated mode if its parent is not
replicated mode.

> 5) less/(no) need for iterators as you can directly asses key using it's path.
>    eg objdb->key_get("/logging/NTF/debug", &debug_on, &debug_on_len);
> 


> Discussion:
> 1) what is the best API for searching?
> 2) import for corosync.conf/xml/... (perhaps a separate tool to parse?)
> 3) export to corosync.conf/xml/...
> 4) what about basic typing for keys? (int8,int16,int32,int64,string,any)
> 
> Lots of feedback please :)
> 
> Regards
> Angus Salkeld
> 
> 
> typedef enum {
>         OBJECT_TRACK_DEPTH_ONE,
>         OBJECT_TRACK_DEPTH_RECURSIVE
> } objdb_track_depth_t;
> 
> typedef enum {
>         OBJECT_CREATE,
>         OBJECT_REPLACE,
>         OBJECT_DELETE,
>         OBJECT_READ,
>         OBJECT_WRITE
> } objdb_callback_type_t;
> 
> #define OBJDB_ATTR_MEMORY     0x01
> #define OBJDB_ATTR_PERSISTENT 0x02
> #define OBJDB_ATTR_RUNTIME    0x04
> #define OBJDB_ATTR_READONLY   0x08
> #define OBJDB_ATTR_READWRITE  0x10
> 
> typedef int (*data_notification_fn_t) (
>         const char *path_pt,
>         objdb_callback_type_t type,
>         const void *value, size_t value_len,
>         void *priv_data_pt);
> 
> typedef int (*path_notification_fn_t) (
>         const char *path_pt,
>         objdb_callback_type_t type,
>         void *priv_data_pt);
> 
> struct objdb_iface_ver_2_0 {
>         int (*objdb_init) (void);
> 
>         int (*object_create) (
>                 hdb_handle_t *object_handle,
>                 const char *path,
>                 path_notification_fn_t child_validator,
>                 data_notification_fn_t data_validator);
> 

imo makes more sense to seperate out the notifications changes from the
object creation.  I can see a case where someone may want a callback
that an object has changed without actually creating it.

What about object referencing (accessing an existing object?)

>         int (*object_destroy) (
>                 const char *path);
> 
>         int (*object_path_get) (
>                 hdb_handle_t object_handle,
>                 char *path,
>                 size_t *path_len);
> 
>         int (*key_create_runtime) (
>                 const char *path,
>                 const uint8_t attributes,
>                 data_notification_fn_t read_write,
>                 void * priv_data_pt);
> 
>         int (*key_create) (
>                 const char *path,
>                 const uint8_t attributes,
>                 const void *value,
>                 size_t value_len);
> 

Why are two different types of key create required?  Makes more sense to
me to create objects as synced/unsynced rather then keys.

>         int (*key_get) (
>                 const char *path,
>                 void **value,
>                 size_t *value_len);
> 
>         int (*key_delete) (const char *path);
> 
>         int (*track_start) (
>                 const char *path,
>                 hdb_handle_t *track_handle,
>                 objdb_track_depth_t depth,
>                 data_notification_fn_t data_changed_notify_fn,
>                 path_notification_fn_t path_changed_notify_fn,
>                 void * priv_data_pt);
> 
>         void (*track_stop) (hdb_handle_t track_handle);
> 
> };

Looks decent for an initial pass.  Need the ability to unlink an object
to be really useful for sa forum services.  Also objects need duration
and expiration timer support.  Finally you mentioned object searching..
I think what you need to handle the unlink/duration timer functionality
is a 

object_get (path)

object_put (path)

The model is object_create sets refcount to 1
object_get increases by 1
object_put decreases by 1
object_unlink decreases by 1 disallows further references on object

When refcount = 0, retention duration is started.

Example use case:
ckptOpen:
if create flag
	object_create (object name)
else
	object_get

ckptClose
object_put

ckptUnlink
object_unlink


A duration timer for an object keeps an object around from the time the
last reference on the object was released until the timer expires, at
which time the object/keys/children are deleted.

An expiration timer deletes the object (like an unlink) at a specific
time.  New references are not allowed.  Existing references are allowed.
New creates are allowed.


> _______________________________________________
> Openais mailing list
> Openais at lists.linux-foundation.org
> https://lists.linux-foundation.org/mailman/listinfo/openais



More information about the Openais mailing list