On Sun, 17 Nov 2013, Noah Watkins wrote:
> The ObjectOperation interface in librados is great for performing compound 
> atomic operations. However, it doesn?t seem to be capable of expressing more 
> complex flows. Consider the following set of operations that I one might want 
> to run atomically to optionally initialize an xattr:
> 
>    int ret = getxattr(?foo?)
>    if (ret < 0 && ret != -ENODATA)
>      return ret;
> 
>    if (ret == -ENODATA)
>      /* do some initialization */
>    else
>      /* do something else */
> 
> As it stands, one would need to build a cls_xyz to do this. Alternatively, 
> something like cls_lua could be used, but there is a lot of downsides to 
> that. However, after building several cls_xyz modules, it is clear that the 
> majority of the time is spent doing basic logic, moving some data around, and 
> occasionally doing something like incrementing some counters.
> 
> I?ve put a prototype solution up in github
> 
>     `github.com/ceph/ceph.git obj_op_virt_machine`
> 
> that adds control instructions into the ObjectOperation interface. Using the 
> interface I can express the above logic as follows:
> 
>    ObjectReadOperation op;

Hmm.. I still have a hard time remembering what ObjectReadOperation vs 
ObjectWriteOperation actually mean/enforce.  Especially for these types of 
requests, which could be either (return useful data on read, or if checks 
pass do a mutation).

>    // foo doesn?t exist. the return value
>    // will be placed into a named register ?ret"
>    op.getxattr(?foo?, bl, NULL);

IIRC there is a per-op flag to ignore the return value (or rather, not 
return immediately if it is <0).  

This looks pretty handy!  I think we should be careful about extending 
this interface until we have a pretty good picture of the use-cases, 
though, and at least one user.

sage

> 
>    // jump to label if ?ret? register >= 0
>    op.ois_jge(?ret?, 0, ?has_attr?); 
> 
>    // jump to label if ?ret? register == 0
>    op.ois_jeq(?ret?, -ENODATA, ?no_attr?);
> 
>    // fall through to return any error in the
>    // ?ret? register. returns immediately
>    op.ois_ret(?ret?);
> 
>    // define a label target
>    op.ois_label(?has_attr?);
>    /* ? do some stuff ? */
>    op.ois_ret(0);
> 
>   // defines a label target
>   op.ois_label(?no_attr?);
>   /* ? do initialization ? */
>   op.ois_ret(0);
> 
>   ioctx.operate(?obj?, &op);
> 
> Using only a few instructions, we can get pretty good building blocks. Adding 
> a few to examine some data in primitive ways would add another level of 
> usefulness, too (e.g. atomic counter increment). And, this can also be made 
> safe by ensuring that jumps are always forward, removing any problems like 
> infinite loops.
> 
> - Noah--
> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
> the body of a message to [email protected]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to