Lua script in FreeSWITCH exits bridge immediately when bypass_media = true - lua

How do I make the script wait for the bridge to terminate before continuing when I have "bypass_media" set to true?
This snippet -
freeswitch.consoleLog("err","session before="..tostring(session:ready()).."\n")
session:execute("set","bypass_media=true")
session:execute("bridge","sofia/gateway/carrierb/12345678")
freeswitch.consoleLog("err","session after="..tostring(session:ready()).."\n")
from an audio perspective, it works perfectly with bridge_media set to either true or false, and a wireshark trace shows the audio either passing through (false) or end to end (true).
But with bypass set to true, the script continues without pausing, and the session is no longer ready (session:ready() == false).
The channel seems to go into a hibernate state, but I have housekeeping to do after the bridge is finished which I simply cannot do.
Same happens if i do the bridge in XML dialplan, immediately carries on causing my housekeeping to fire early.
FreeSWITCH (Version 1.6.20 git 43a9feb 2018-05-07 18:56:11Z 64bit)
Lua 5.2
EDIT 1 -
I can get "api_hangup_hook=lua housekeeping.lua" to work, but then I have to pass tons of variables and it fires up a new process/thread/whatever, which seems a little overkill unless that's the only way.

I have a workaround, but would still like an answer to the question if anyone has one (ie how to stop the bridge exiting immediately).
If I set this before the bridge :
session:execute("set","bypass_media=true")
session:execute("set","session_in_hangup_hook=true")
session:execute("set","api_hangup_hook=lua housekeeping.lua "..<vars>)
then "housekeeping.lua" fires when the bridge actually terminates (which is long after the script does).
In housekeeping.lua I can then do :
session:getVariable("billmsec")
and it seems to have the correct values in them, allowing me to do my housekeeping.
My problem with this is the uncertainty of playing with variables from a session that appears to have gone away from a script that fires at some point in the future.
Anyway, it'll have to do until I can find out how to keep control inside the original script.

Related

Is DRBD split-brain handler called only when after-sb-Xpri is set to disconnect?

I wanted to run a script if a split brain is detected. In the documentation, it is mentioned that we can do that by providing the path of the script like
resource <resource>
handlers {
split-brain <handler>;
...
}
But, below that, for the after-sb-0pri configuration, it is mentioned that
disconnect: Do not recover automatically, simply invoke the
split-brain handler script (if configured), drop the connection and
continue in disconnected mode.
So, my question is that, will the configured script be run only when after-sb-0pri is set to disconnect, or will that run for any set value
Document Link: https://linbit.com/drbd-user-guide/users-guide-drbd-8-4/#s-configure-split-brain-behavior
DRBD should invoke the split-brain handler whenever a split-brain is detected. I.E. Anything that would log a Split-Brain detected ... in the system/kernel logs. The documentation attempts to explain this at the beginning of chapter 5.17.1 with:
DRBD invokes the split-brain handler, if configured, at any time split
brain is detected.
Additionally, disconnect is the default value for after-sb-0pri. So, even if not explicitly set that will still be the behavior.

Detect change in lua stdin/stdout

I have a lua script which is started by an external process - the two then interact through StandardInput and StandardOutput, through a simple loop:
local running = true;
while running do
print('ready'); io.flush(); --the parent process now knows it can interact with the lua script
local input = io.read(); --the parent process, whenever ready, provides the lua script with a given input
if input=="exit" then running=false --this ends the script...
else print(DoStuffWithInput(input)); --...or the lua script responds here
end
I want the lua script to end if it detects that the parent process no longer exists, given that currently CPU usage jumps to 100% when the parent is closed (presumably because io.read() is no longer needing to wait for any input, although I'm not sure what it's reading instead).
What would be an elegant and safe way of detecting if the parent process has closed (presumably changing the stdin and stdout of the lua script)?
I've tried a few things, but io.stdin and io.stdout always seem to be a file, and I'm not sure where to go from here.

PEPPER (SoftBank Robotics): ALSpeechRecognition Engine issue - How to restart it when it doesnìt work?

During my test on Pepper, I found some difficulties in realizing continuative collaborative dialog.
In particular, after about 10 minutes, it seems that the ALSpeechRecognition engine stops working.
In other words, Pepper dialog panel remains empty and/or the robot does not understand my words, even if the structure worked some minute before.
I tried to stop and restart it (i.e., the engine) via SSH terminal, by using:
qicli call ALSpeechRecognition.pause 1
qicli call ALSpeechRecognition.pause 0
It should restart the engine according to the guidelines shown here, but it does not work.
Thank you so much guys.
Sincerely,
Giovanni
According to the tutorial, starting and stopping the speech recognition engine is done by subscribing/unsubscribing it.
The recommended way to do this is unsubscribing and subscribing back to it. For me it also worked changing the speech reco language and chaging it back to the one you had previously.
Luis is right and to do so just create a function as below given and call it if ActiveListenning event comes false from ALSpeechRecognition module. Note: Use ALMemory module to get data from ALSpeechRecogntion.
asr_service = ALProxy("ALSpeechRecognition",ip,port)
memory = ALProxy("ALMemory",ip,port)
def reset():
asr_service.unsubscribe("ASR_Engine")
asr_service.subscribe("ASR_Engine")
ALS = memory.getData("ALSpeechRecognition/ActiveListening")
if ALS==False:
reset()

Defining "global" behavior in Gulp (measuring task duration)

I'm working on moving us from ant to gulp, and as part of the effort I want to write timing stats to Graphite. We're doing this in ant as well (no idea how, beside the point anyway). My question is, I'd prefer to not have to add some or other plugin manually to every task we have (we have over 60), but rather have some sort of global behavior, where for every task, before the task is run a timer is start, and when it signals completion we push some data to Graphite (over statsd).
Can someone point me in the right direction where to hook into gulp for this? I couldn't find anything particularly useful in the docs / recipes...
We're running gulp#4.
Instead of adding timing code to your numerous tasks, you could make use of the NPM gulp-duration package.
A snippet of an example of it's use is shown below:
function rebundle() {
var uglifyTimer = duration('uglify time')
var bundleTimer = duration('bundle time')
return bundler.bundle()
.pipe(source('bundle.js'))
.pipe(bundleTimer)
// start just before uglify recieves its first file
.once('data', uglifyTimer.start)
.pipe(uglify())
.pipe(uglifyTimer)
.pipe(gulp.dest('example/'))
}
gulp-duration's duration function:
Creates a new pass-through duration stream. When this stream is
closed, it will log the amount of time since its creation to your
terminal.
will then allow you to log the duration of the task.
Whilst this is not a global behaviour solution, at least you can specify the timing code in your gulp file, as opposed to having to modify all 60+ of your tasks.

Why is my Ruby script utilizing 90% of my CPU?

I wrote a admin script that tails a heroku log and every n seconds, it summarizes averages and notifies me if i cross a certain threshold (yes I know and love new relic -- but I want to do custom stuff).
Here is the entire script.
I have never been a master of IO and threads, I wonder if I am making a silly mistake. I have a couple of daemon threads that have while(true){} which could be the culprit. For example:
# read new lines
f = File.open(file, "r")
f.seek(0, IO::SEEK_END)
while true do
select([f])
line = f.gets
parse_heroku_line(line)
end
I use one daemon to watch for new lines of a log, and the other to periodically summarize.
Does someone see a way to make it less processor-intensive?
This probably runs hot because you never really block while reading from the temporary file. IO::select is a thin layer over POSIX select(2). It looks like you're trying to block until the file is ready for reading, but select(2) considers EOF to be ready ("a file descriptor is also ready on end-of-file"), so you always return right away from select then call gets which returns nil at EOF.
You can get a truer EOF reading and nice blocking behavior by avoiding the thread which writes to the temp file and instead using IO::popen to fork the %x[heroku logs --ps router --tail --app pipewave-cedar] log tailer, connected to a ruby IO object on which you can loop over gets, exiting when gets returns nil (indicating the log tailer finished). gets on the pipe from the tailer will block when there's nothing to read and your script will only run as hot as it takes to do your line parsing and reporting.
EDIT: I'm not set up to actually try your code, but you should be able to replace the log tailer thread and your temp file read loop with this code to get the behavior described above:
IO.popen( %w{ heroku logs --ps router --tail --app my-heroku-app } ) do |logf|
while line = logf.gets
parse_heroku_line(line) if line =~ /^/
end
end
I also notice your reporting thread does not do anything to synchronize access to #total_lines, #total_errors, etc. So, you have some minor race conditions where you can get inconsistent values from the instance vars that parse_heroku_line method updates.
select is about whether a read would block. f is just a plain old file, so you when get to the end reads don't block, they just return nil instantly. As a result select returns instantly rather than waiting for something to be appending to the file as I assume you're expecting. Because of this you're sitting in a tight busy loop, so high cpu is to be expected.
If you are at eof (you could either check f.eof? or whether gets returns nil), then you could either start sleeping (perhaps with some sort of back off) or use something like listen to be notified of filesystem changes

Resources