Hi again
A bit more information on reproducing it: each call using test_transfer will fully occupy one CPU, so on a 4 core machine you need to start 4 of these calls to tie it up, then audio on other calls is broken or completely stopped, CLI stops responding etc. As a workaround I have commented out from switch_ivr.c line 1808 near end of switch_ivr_session_transfer:
/*switch_channel_add_variable_var_check(channel, SWITCH_TRANSFER_HISTORY_VARIABLE, new_profile->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH);*/
Of course that means transfer_history is no longer populated, but it does remove the performance problem, the test_transfer calls now run through so fast I had to start the loop off at 9999 and although they do use a bit of CPU (it is a tight loop with no sleep/IO etc after all) 4 simultaneously do not tie up the server and other calls continue fine. I can think of a few more complete solutions:
- Improve the performance of appending to variables with big values - I think this is ultimately done in switch_event_base_add_header in switch_event.c, though that looks like quite a complex function. In the end, repeated appending to long strings is never going to be efficient.
- Maintain the transfer history as a stack/list/array structure and either render it to the variable string whenever it is changed (still expensive?) or generate the string only on demand - though I'm not sure how that would work with info, uuid_dump and verbose events in event sockets etc.
- Allow channels to opt out of having transfer_history tracked, perhaps by setting it to "suppress" or "false", this could be checked before the line above. Would put the onus on the dialplan to know if it was going to do lots of transfers, but it would be backward-compatible with anyone who needs this variable. Out of interest why was it added?
Once I have managed to log in to Jira I will raise all this there.
Cheers
David