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

Miklos Tirpak miklos at iptel.org
Wed Feb 17 09:48:02 CET 2010


Hi,

On 02/16/2010 05:08 PM, Andrei Pelinescu-Onciul wrote:
> 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).

if the changes are committed at all. More changes can be prepared and 
committed at once, but they can also be revoked.

I have seen several times that the on_change_cb callback is confusing. 
Shall I rename it to something else, for example fixup_cb? So that the 
name would not indicate that the variable is changed.

> 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).

Indeed. So calling cfg_update() is necessary only if a new process is 
forked, otherwise do not call it.

> 
>>> 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.

The above two approaches can be used together:
1. Validate the value at the time it is fixed up (on_change_cb).
2. Apply any local changes from the on_set_child_cb.


In general, I see two problems with the cfg framework right now that 
could be improved, I appreciate any idea:

1) The problem Marius mentioned, i.e. those variables that have fixup 
function cannot be read via sercmd. The fixup function can perform quite 
simple tasks, for example data validation only, but it can also convert 
the values to some internal form that the framework is not aware of.

One possible solution would be to store also the original, not yet fixed 
up values and print them via sercmd. This is fine if the value was set 
via the framework, but the default values are not available in original 
form.

Another solution is to introduce a kind of reverse-fixup function that 
can convert the values back to human-readable form. This would require 
changes in the modules not only in the framework but the advantage is 
that really the value would be printed that is being used. For the 
simple cases we could have prepared reverse-fixups available that could 
re reused.

2) Some modules update local or even shared memory variables based on 
cfg variable changes. It would be nice to solve as many cases within the 
framework as possible. For example the modules could have write access 
to their variables during fixup, or more complicated structures could be 
stored not only int and str vars. If you miss any feature therefore you 
keep variables outside of the framework then please speak up!

Thanks,
Miklos


> 
> 
> Andrei
> 
> _______________________________________________
> sr-dev mailing list
> sr-dev at lists.sip-router.org
> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev



More information about the sr-dev mailing list