[asterisk-dev] Generic lookup function for static values

asterisk at phreaknet.org asterisk at phreaknet.org
Fri Jun 18 15:31:54 CDT 2021


I wanted to float the possibility of a new data lookup mechanism in the 
dialplan that could be useful in certain scenarios.

A few ways of doing an "X -> Y" lookup include using ${DB}, ${ODBC}, and 
Gosub (with a lookup subroutine for each "key"). DB requires a literal 
value to exist, while ODBC and Gosub are more flexible.

I toyed with the idea of exploiting HINTs for similar functionality 
recently, whereby a hint could be used as a key/value store. Not at all 
what it was intended for, but I had a script that generated these 
automatically and for infrequently changed data that doesn't need to be 
in AstDB, it worked nicely for some things, e.g. same => 
n,DoSomething(${HINT(5551210 at billing-telnumber)}).

Seems strange (why not same => 
n,DoSomething(${DB(billing-telnumber/5551210)})), but a) native dialplan 
extension pattern matching can be used (without the aid of a Gosub 
wrapper) and b) it performs better. For instance, you could have 
[billing-telnumber] exten => _5551210,hint,5551000 etc. Limited use 
cases but can be handy.

I was informed that HINT has some overhead for abusing it in this 
manner, since device state code will try to use it, which is unnecessary 
for using it for non-device state purposes.

I took the key parts of the HINT function and created a generic LOOKUP 
function (using a non hint/-1 priority) and benchmarked it over 60,000 
tests - here are the average response times, per lookup:

  * ${LOOKUP} - 4.53ms
  * ${DB} - 11.07ms
  * ${ODBC} - 48.16ms
  * Gosub (returning static values) - 33.04ms

So for certain static, rarely changing, non-user mutable data in the 
dialplan where pattern matching on some kind of key is useful, if done, 
performance is 2x-10x better.

With LOOKUP, one could take code like this:
...
same => n,Gosub(billing-telnumber,${CALLERID(num)},1)
same => n,Set(btn=${GOSUB_RETVAL})
same => n,Gosub(feature-group,${CALLERID(num)},1)
same => n,Set(fg=${GOSUB_RETVAL})
same => n,DoSomething(${btn},${fg})

and replace it with:
same => 
n,DoSomething(${LOOKUP(${CALLERID(num)}@btn)},${LOOKUP(${CALLERID(num)}@fg})

There's obviously limited usefulness and value in storing static data in 
the dialplan like this, but in certain scenarios, like non-user mutable 
data that rarely changes, I've found it comes in handy, especially being 
able to leverage pattern matching. Currently, the POC for this works 
quite well, and could be structured in an isolated manner that is 
completely independent from the core.
Interested in any thoughts as to whether or not this would be useful to 
anyone, and how people may currently be doing this kind of thing, or if 
anyone has a better concept.




More information about the asterisk-dev mailing list