Hello,
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?
or
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.
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…