asterisk at phreaknet.org
2021-Jun-18 20:31 UTC
[asterisk-users] Generic lookup function for static values
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.