ConfD User Community

Transaction hooks missing 'modify' data callback so better off using maapi_diff_iterate only?

based on documentation I think the regular approach to adding transaction hooks is to:
1/ add transaction hook entries in YANG
2/ start daemon who will do following:
2.1/ register transaction callbacks (init, finish) in order to connect and attach to transaction and eventual do cleaning up
2.2/ register data callbacks (create, remove, set_elem).

It works if you accept one hindrance: there’s no ‘modify’ callback ?!?

Now this is strange, because if you do maapi_diff_iterate in your init callback then you are getting ‘modify’ operations.

And sometimes modify is what you need because you need to take one action based on overall change in parent (all children) not individual children. It’s awkward to implement the action if you get set_elem, create or remove on each child separately…

This makes me wonder:
A/ is it possible to somehow get this ‘modify’ callback?
B/ maybe init and finish is all I need to implement hooks by myself (without adding callpoints in YANG and no data callbacks):
B1/ Just keep list of keypaths I’m interested in and use it with maapi_diff_iterate or maapi_keypath_iterate to filter them out in ‘init’ callback.
B2/ I get ‘init’ callback’ for any transaction anyway, right?
B3/ No need to modify/deploy changes in YANG if you need to add another hook, just application needs to be rebuilt and deployed.
B4/ Or is it going to be too slow compared to regular approach because of all that maapi_diff_iterate on each transaction (suppose my app may add hooks anywhere in the YANG in future) ?

or C/ use hybrid approach, that is use regular callpoints for create, remove and set_elem operations and maapi_diff_iterate for the ‘modify’ operations? That seems like the most efficient way?

Instead, see the confd_lib_dp(3) man page and the “write_all()” callback that will be invoked once for a transaction hook specified with tailf:invocation- mode per-transaction. It is the only callback that should be registered for such a hook.
See also the chapter Transformations, Hooks, Hidden Data and Symlinks in the User Guide.

thank you @cohult, but according to the user’s guide:

The kp parameter is currently always NULL, since the callback does not pertain to any particular data node.

So suppose I have several ‘per-transaction’ callbacks defined and all of the nodes are modified in the transaction.

How many times write_all will be called? Once for whole transaction or once per node?

How to tell which node was modified in ‘write_all’ callback other than calling maapi_diff_iterate?

Doesn’t this beats the purpose for me?

Ok, this seems to work:
1/ because p_kp is NULL for write_all callback we must use unique callpoint names for each per-transaction hook (=> path, can’t reuse callpoint names as for other callpoints).
2/ when registering data callbacks we use different write_all callback functions (not scalable) or better we set cb_opaque to different unique identifiers which will enable single write_all callback function to tell which callpoint is it (same thing we do anyway for other types of hooks where p_kp may be ambiguous).
3/ we get single write_all callback no matter how many instances were modified but we are able to tell which callpoint is it by cb_opaque we set in step 2/ or based on which function of ours was invoked. We use this to determine path.
4/ we don’t know keys for each of the instance modified so we do maapi_keypath_diff_iterate(path) to find out actual keypaths and we’re good!

Thank you @cohult for directions! I only wished that ‘modify’ was available in addition to ‘create’, ‘remove’ and ‘set_elem’ to use with a regular transaction hook…