Yes, this can be accomplished with priority mechanism. You should set priority for all subscriptions (call to cdb_subscribe) to reflect desired order. It does not matter if there is one subscription per daemon or there are several subscriptions in one daemon. From ConfD user Guide:
There can be multiple subscription points from different sources,
that is a single client daemon can have many subscriptions and
there can be many client daemons.
If there is more than one subscription per daemon, there can be only one subscription socket, as individual
subscriptions are identified by subscription point.
By looking at ConfD User guide, I think your assumption about cdb_sync_subscription_socket is correct. You can use cdb_sync_subscription_socket(subsock, CDB_DONE_PRIORITY).
Thank you so much, josephm! I finally got the hang of it.
One last thing: priorities are correctly respected except when daemons (re)start. They seem to restart without a particular order, or rather they don’t receive any notification the first time they run. Is there a way to have confd restart itself and application daemons in the same order as they receive notifications?
I see that in the confd folder there is a folder named phases, where each file corresponds a startup phase for each daemon. I don’t understand if within each phase I can define also an order of who starts first among my daemons.
When application that implements some CDB subscriptions (my definition of “daemon” in this case) restarts, you can invoke cdb_trigger_subscriptions() in it, so that it receives all the data for its subscriptions (all it’s subscribers will be invoked, as if all the data is new) from database. This will follow the order defined by the priorities of subscriptions of this daemon.
You may need to handle this in multi-threaded way, as it’s blocking while all the subscriptions process their jobs… (see this procedure’s description in user guide/man page)
Thanks! So basically each of my daemons will have to call cdb_trigger_subscriptions() or only one will? I read the manual, but didn’t understand too much how exactly I can use this function.
Let’s say I have daemons A, B, C and that I want daemons to apply the part of the configuration they’re in charge of in the order A -> B-> C, where B won’t start before A finishes, and C won’t start before B finishes, just like with notifications and priorities.
A daemon will subscribe to its paths as usual, obtain subscription points, and then will call cdb_trigger_subscriptions() on these subscription points. Unless all daemons do exactly the same at the same time (not sure how), how does confd know that it has to notify A, then B, then C? I guess that if A calls that function, it will be notified in the correct order with respect to its own subscription points, and not with respect everybody else’s subscription points.
The description of the procedures is not completely clear in user guide/man page.
A “zero” count of subscribers for the call of procedure says it will be “all” of them, but am not myself completely sure whether “all” means across any subscriber daemons, or “all that this daemon registers”.
Note the “subscription session socket” part of the error message - though not spelled out in the documentation, you are not supposed to use a subscription socket for this call (that couldn’t work, since you are supposed to receive the subscription notifications on the subscription socket…). You need to connect a DATA_SOCKET and use that.
Where do you see that text? As far as I can see, both the C man page and the Python documentation clearly states that the array/list contains subscription points, and thus the “count” (in the C API) is for subscription points - there is no “count of subscribers”. And both of them say that it’s “all subscribers” if the array/list is zero length / empty. The use of “subscription points” vs “subscribers” seems clear to me - they don’t mean the same thing… See also the cdb_subscription/trigger example - it’s only C, but I believe the Python usage is pretty much the same.
Ok, thanks for the clarification. I got confused too.
So now I’m creating a data socket and calling trigger_subscriptions() on it. It seems to work only when I feed it the list of subscription points, but it says “Operation not implemented (51): Unknown CDB operation” when sub_points is an empty list…
OK, this is definitely not “obviously wrong” usage (in fact what you’re doing could make a lot of sense), and pretty useless error info. The problem is the start_session() call - you should (as in the example:-) only do connect() and then trigger_subscriptions(). Once you have started a session towards RUNNING, CDB expects only “data read” operations, i.e. get(), exists(), num_instances() etc.