[sr-dev] Question about config framework (ser)

Andrei Pelinescu-Onciul andrei at iptel.org
Tue Feb 16 17:08:19 CET 2010


On Feb 16, 2010 at 14:41, marius zbihlei <marius.zbihlei at 1and1.ro> wrote:
> Andrei Pelinescu-Onciul wrote:
> >On Feb 16, 2010 at 12:47, marius zbihlei <marius.zbihlei at 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



More information about the sr-dev mailing list