On Feb 16, 2010 at 14:41, marius zbihlei <marius.zbihlei(a)1and1.ro> wrote:
Andrei Pelinescu-Onciul wrote:
On Feb 16, 2010 at 12:47, marius zbihlei
<marius.zbihlei(a)1and1.ro> wrote:
You need this callback to be called the moment the value is set (1),
in each process, before the updated config is used (2) or once, before
the updated config is use the 1st time (by the first process that needs
to access it) (3)?
If (2) is ok, then use the on_set_child_cb (next field in the cfg_def).
If (3) is ok, then set CFG_CB_ONLY_ONCE among the flag and use the
on_set_child_cb, like for (2).
Hello,
What I really wanted was 1, when the cfg value was change the statistics
are also updated. But I guess this can't be easy done (requires changes
to cfg framework). As I only need the value changed once, and
statistics aren't per process, I guess 3 is the better option.
I don't completely understand the whole "before the updated config is
used". This means a cfg_update() is required or I don't have to do
anything the update being done transparently from the user(myself) point
of view. If I issue a sercmd cfg.set_now_int this will mean that the
child_cb will be called at the time of the update(the value being
changed now ?!) ?!
You need to worry about cfg_update() only if you fork new processes and
want to use the cfg framework from them.
In general the cfg is updated for each "normal" process when a new message
is read.
on_set_child_cb will be called by each process when its config needs
updating (the global config pointer differs from the local one), so the
answer to your question is "yes" (if no message comes, then no
cfg_update() will happen for some time, so the callback might be called
at a later time, at most TIMER_HANDLER_INTERVAL later).
Note also that if you want to use on_change_cb instead of
on_set_child_cb, there is another issue. The cfg can be updated
immediately, or on commit (e.g cfg.set_delayed_int and cfg.commit).
However the cfg variable fixup (on_change_cb) is called immediately in
both cases (because it's supposed to "fix" the value and not do some
other stuff). So if you do something from on_change_cb, then it will
probably break the cfg.set_delayed_int & cfg.commit case (the change
will happen immediately and not at cfg.commit time).
I had this bug in older versions for the sctp options. I used to do
setsockopt()s from the fixup instead of the per child callback. Now they
are done via the per child callback with the CFG_CB_ONLY_ONCE flag set
(see sctp_option.c "autoclose" for an example)
If I need to call cfg_update(), then I can call it from the "save"
function export of the registrar module(and all other function exports
called from ser cfg script). If this will make the child_cb to get
called, then I can update the statistics from there. The window between
the cfg value is changed and the changed is reflected to statistics is
limited by the next call to a registrar function export when a sip
messages is processed.
cfg_update() is called each time a message is received and periodically
by the timer. If you use (3) then you will have at most 1/16 s delay in
the worst case.
If this is not good enough for you, then I think we could add a call to
cfg_update() at the end of cfg_commit() and cfg_set_now() (this would
cause an update immediately after a commit or set_now and so it would
trigger the immediate execution of the per child callbacks).
Another thing. Do I need to use cfg_update() periodically to ensure that
values from cfg framework are consistent in the modules?! After looking
at some examples in modules/tm I presumed that a call to cfg_get(...) is
enough to get the updated value (Note that I don't have any child
processes in the module - if there were children I would call
cfg_update() from the infinite loop of the child).
Yes, you do have to call cfg_update() periodically if you want to make
sure you have the latest config version for the non-atomic declared
config vars. However cfg_update() is already called in all the
processes (e.g.: each time a new message is received in the receiver
processes and each timer tick in the timer process).
In general it means that some of the new config values would be visible
in a process only for future messages and not for the one that is
currently being processed. This is a feature (it's a guarantee that any
non-atomic-marked config var. would not suddenly change while you're
processing a message) and updating more often will break several
things (depending on the process, e.g. there are some tcp config
variables that must not change while a message is processed).
So far I guess nobody had a fixup that didn't
change the value :-)
I can think of two cases when the value is not changed/transformed
1. A change in cfg framework generates some internal module changes
(like a reread of a database, update of statistics). I think this can be
achieved via child_cb.
This one would also conflict with set_delays & commit if it would be
done via the fixups.
2. The fixup tests to see if the value is correct
(like expecting a
string from a already known lists of strings). No changes are possible
and if the user gave smth wrong, sercmd will inform it at once . This
can't be achieved via child_cb.
Yes, this is a valid case. We will have to add another flag for this
type of fixups.
Andrei