yandex-tank: "Waiting for aggregator to finish" forever - yandex-tank

I did web search for "site:stackoverflow.com yandex-tank Waiting for aggregator to finish" and found nothing that specific.
I start JMeter via Yandex-Tank (YT) and after JMeter finishes YT continues to write in log "Waiting for aggregator to finish" like forever. I've found some discussion here: https://gitter.im/yandex/yandex-tank?at=5ce2c4e36366992a94ef7826:
Покопал ещё, оказывается эти строки там были, но их убрали в коммите:
47623dd4b7a08e5383cbb4144eecc13edbdf3e96 Видимо закрытие reader нужно
перенести по аналогии с Bfg в plugins/JMeter/plugin.py В функции
end_test и is_test_finished
it is a discussion board in Russian, brief translation for non-russian speakers: "closing of reader should be moved to end_test & is_test_finished like it's done for BFG plugin".
However, as I see in code end_test and is_test_finished reader.close() is already there yandextank/plugins/JMeter/plugin.py:
def is_test_finished(self):
retcode = self.process.poll()
aggregator = self.core.job.aggregator
if not aggregator.reader.jmeter_finished and retcode is not None:
logger.info(
"JMeter process finished with exit code: %s, waiting for aggregator",
retcode)
self.retries = 0
aggregator.reader.jmeter_finished = True
return -1
elif aggregator.reader.jmeter_finished is True:
print("aggregator.reader.jmeter_finished is True")
if aggregator.reader.agg_finished:
self.reader.close()
return retcode
else:
logger.info("Waiting for aggregator to finish")
return -1
else:
return -1
def end_test(self, retcode):
if self.process:
gracefully_shutdown = self.__graceful_shutdown()
if not gracefully_shutdown:
self.__kill_jmeter()
if self.process_stderr:
self.process_stderr.close()
self.core.add_artifact_file(self.jmeter_log)
self.reader.close()
return retcode
How to fix that (to make YT finish cleanly after JM finish)?

Related

How can I know the command used? - Discord.py

I am trying to make a errorhandling for my Discord.py, how do I know what command was used for the error to pop up?
#bot.event
async def on_command_error(ctx, error):
print("error: ",error)
if search("not found", str(error)):
c_f = random.choice([f"`{command used}` was not found, silly.", "Ehm.. Since when do we have `{command used}`?", "I don't know what `{command used}` is?"])
embed=discord.Embed(title=c_f, description=f"Please use existing commands. {ctx.author.mention}", color=error_color)
embed.timestamp = datetime.utcnow()
embed.set_footer(text=bot_name, icon_url=icon_uri)
await ctx.send(embed=embed)
elif search("cooldown", str(error)):
c_d = random.choice(["Did you drink energy drinks!?", "Why are you stressing, buddy.", "Duhh, wait, you're on cooldown!"])
second_remain = round(error.retry_after, 1)
embed=discord.Embed(title=c_d, description=f"Try again after {second_remain}s. {ctx.author.mention}", color=error_color)
embed.timestamp = datetime.utcnow()
embed.set_footer(text=bot_name, icon_url=icon_uri)
await ctx.send(embed=embed)
else:
raise error
Any attribute I can use?
You can use ctx.command
#bot.event
async def on_command_error(ctx, exception):
error = getattr(exception, "original", exception)
if hasattr(ctx.command, "on_error"): # If a command has it's own handler
return
elif isinstance(error, CommandNotFound):
return
if isinstance(error, discord.CommandInvokeError):
print(ctx.command)
Your solution is to add them to the command specifically, this also means it can help diagnose an issue with a command more exact.
You can also add any error events to the specific listener, just like how you done it for all commands, instead add them individually.
#bot.command()
async def command_name(ctx):
# ...
#command_name.error
async def command_name_error(ctx, error):
if isinstance(error, commands.CommandInvokeError):
await ctx.send("An error from this command" + error)
With #command_name.error put your command name before the .error, then this makes an error listener for that command, if it produces an error.

How can I create reliable flask-SQLAlchemy interactions with server-side-events?

I have a flask app that is functioning to expectations, and I am now trying to add a message notification section to my page. The difficulty I am having is that the database changes I am trying to rely upon do not seem to be updating in a timely fashion.
The html code is elementary:
<ul id="out" cols="85" rows="14">
</ul><br><br>
<script type="text/javascript">
var ul = document.getElementById("out");
var eventSource = new EventSource("/stream_game_channel");
eventSource.onmessage = function(e) {
ul.innerHTML += e.data + '<br>';
}
</script>
Here is the msg write code that the second user is executing. I know the code block is run because the redis trigger is properly invoked:
msg_join = Messages(game_id=game_id[0],
type="gameStart",
msg_from=current_user.username,
msg_to="Everyone",
message=f'{current_user.username} has requested to join.')
db.session.add(msg_join)
db.session.commit()
channel = str(game_id[0]).zfill(5) + 'startGame'
session['channel'] = channel
date_time = datetime.utcnow().strftime("%Y/%m/%d %H:%M:%S")
redisChannel.set(channel, date_time)
Here is the flask stream code, which is correctly triggered by a new redis time, but when I pull the list of messages, the new message the the second user has added is not yet accessible:
#games.route('/stream_game_channel')
def stream_game_channel():
#stream_with_context
def eventStream():
channel = session.get('channel')
game_id = int(left(channel, 5))
cnt = 0
while cnt < 1000:
print(f'cnt = 0 process running from: {current_user.username}')
time.sleep(1)
ntime = redisChannel.get(channel)
if cnt == 0:
msgs = db.session.query(Messages).filter(Messages.game_id == game_id)
msg_list = [i.message for i in msgs]
cnt += 1
ltime = ntime
lmsg_list = msg_list
for i in msg_list:
yield "data: {}\n\n".format(i)
elif ntime != ltime:
print(f'cnt > 0 process running from: {current_user.username}')
time.sleep(3)
msgs = db.session.query(Messages).filter(Messages.game_id == game_id)
msg_list = [i.message for i in msgs]
new_messages = # need to write this code still
ltime = ntime
cnt += 1
yield "data: {}\n\n".format(msg_list[len(msg_list)-len(lmsg_list)])
return Response(eventStream(), mimetype="text/event-stream")
The syntactic error that I am running into is that the msg_list is exactly the same length (i.e the pushed new message does not get written when i expect it to). Strangely, the second user's session appears to be accessing this information because its stream correctly reflects the addition.
I am using an Amazon RDS MySQL database.
The solution was to utilize a db.session.commit() before my db.session.query(Messages).filter(...) even where no writes were pending. This enabled an immediate read from a different user session, and my code commenced to react to the change in message list length properly.

Bunny and RabbitMQ - Adapting the WorkQueue tutorial to cancel subscribing when the Queue is completely worked

I fill up my queue, check it has the right number of tasks to work and then have workers in parallell set to prefetch(1) to ensure each just takes one task at a time.
I want each worker to work its task, send a manual acknowledgement, and keep working taking from the queue if there is more work.
If there is not more work, i.e. the queue is empty, I want the worker script to finish up and return(0).
So, this is what I have now:
require 'bunny'
connection = Bunny.new("amqp://my_conn")
connection.start
channel = connection.create_channel
queue = channel.queue('my_queue_name')
channel.prefetch(1)
puts ' [*] Waiting for messages.'
begin
payload = 'init'
until queue.message_count == 0
puts "worker working queue length is #{queue.message_count}"
_delivery_info, _properties, payload = queue.pop
unless payload.nil?
puts " [x] Received #{payload}"
raise "payload invalid" unless payload[/cucumber/]
begin
do_stuff(payload)
rescue => e
puts "Error running #{payload}: #{e.backtrace.join('\n')}"
#failing stuff
end
end
puts " [x] Done with #{payload}"
end
puts "done with queue"
connection.close
exit(0)
ensure
connection.close
end
I want to still make sure I am done when the queue is empty. This is the example from the RabbitMQ site... https://www.rabbitmq.com/tutorials/tutorial-two-ruby.html . It has a number of things we want for our work queue, most importantly manual acknowledgements. But it does not stop running and I need that to happen programmatically when the queue is done:
#!/usr/bin/env ruby
require 'bunny'
connection = Bunny.new(automatically_recover: false)
connection.start
channel = connection.create_channel
queue = channel.queue('task_queue', durable: true)
channel.prefetch(1)
puts ' [*] Waiting for messages. To exit press CTRL+C'
begin
queue.subscribe(manual_ack: true, block: true) do |delivery_info, _properties, body|
puts " [x] Received '#{body}'"
# imitate some work
sleep body.count('.').to_i
puts ' [x] Done'
channel.ack(delivery_info.delivery_tag)
end
rescue Interrupt => _
connection.close
end
How can this script be adapted to exit out when the queue has been completely worked (0 total and 0 unacked)?
From what I understand, you want your subscriber to end if there are no pending messages in the RabbitMQ queue.
Given your second script, you could avoid passing block: true, and that will return nothing when there's no more data to process. In that case, you could exit the program.
You can see that in the documentation: http://rubybunny.info/articles/queues.html#blocking_or_nonblocking_behavior
By default it's non-blocking.

Capture Variable Changes In Lua

I'm unsure where to look as far as what I could use to capture a variable change in a program loaded within another program.
Here's my code, as messy as it is:
function launch()
shell.run("clear")
print("Preparing for first time run.")
sleep(1)
print("")
local program = netTest()
local file = loadstring(program)
file()
sleep(3)
shell.run("clear")
end
function netTest()
local output = http.get("http://pastebin.com/raw.php?i=hzZv3YH2")
if output then
local contents = output.readAll()
output.close()
return contents
else
print("Empty response")
return false
end
end
local program = netTest()
local file = loadstring(program)
launch()
Here's the code it's calling on:
function ping()
fails = 0
pingResult = 0
print("Testing Internet Connection.")
print("")
oldx, oldy = term.getCursorPos()
print("Connection Test 1")
http.request("http://www.google.com/")
if os.pullEvent() == "http_success" then
local oldx, oldy = term.getCursorPos()
term.setCursorPos(46,oldy-1)
io.write("Passed")
else
local oldx, oldy = term.getCursorPos()
term.setCursorPos(46,oldy-1)
io.write("Failed")
fails = fails+1
end
sleep(1)
print("Connection Test 2")
http.request("http://www.microsoft.com/")
if os.pullEvent() == "http_success" then
local oldx, oldy = term.getCursorPos()
term.setCursorPos(46,oldy-1)
io.write("Passed")
else
local oldx, oldy = term.getCursorPos()
term.setCursorPos(46,oldy-1)
io.write("Failed")
fails = fails+1
end
sleep(1)
print("Connection Test 3")
http.request("http://www.example-failure.com/")
if os.pullEvent() == "http_success" then
local oldx, oldy = term.getCursorPos()
term.setCursorPos(46,oldy-1)
io.write("Passed")
else
local oldx, oldy = term.getCursorPos()
term.setCursorPos(46,oldy-1)
io.write("Failed")
fails = fails+1
end
sleep(1)
if fails == 0 then
print("")
print("")
print("Test Complete, no failures detected.")
sleep(1.5)
elseif fails == 1 then
print("")
print("")
print("1 connection failures detected. A Website Host might be down however connectivity is still there.")
print("")
print("Test Complete.")
sleep(1.5)
elseif fails == 2 then
print("")
print("")
print("2 connection failures detected. Possible limited web connectivity.")
print("")
print("Test Complete.")
sleep(1.5)
elseif fails == 3 then
print("")
print("")
print("Catastrophic connection failure detected. A firewall or improper internet settings may be the problem.")
print("")
print("Test Complete.")
pingResult = __pingResult + 3
sleep(1.5)
end
end
ping()
What it's doing as you can see is running a program externally which will test the connection by making http requests to a couple pages to make sure there's connection to the internet. (I know, it's a bit lame, but I'm still learning).
Basically when and if the connection reads failure on all 3 stages, it'll make my pingResult variable = 3. What I'm wanting to do from the first program that called on my internet utility is record what that variable is set to. If it's set to 3 upon closing, to record that variable being set, and then for simplicity's sake, print that variable so I can see it's either 0 or 3. I'll be doing something with it later but you get the gist of it.
I've tried a couple other things but can't seem to figure out on how I go about doing this. Seeing as I'm still new I tried random stuff but none seemed to work, or I just did them wrong so I don't know what to do with it. Been trying at this one for a couple days to no success.
First of all, most of the code you posted is noise -- print statements, cursor manipulation, fetching Lua code from pastebin (?), all kinds of logic which has absolutely nothing to do with your question, including code which literally does nothing. That's why you haven't got a response yet.
See: How to Ask Questions the Smart Way: Volume is Not Precision.
If we strip all the extraneous stuff from your post, we're left with:
-- main.lua
local file = loadfile('nettest.lua')
file()
-- nettest.lua
pingResult = 123
Now to address your questions:
What it's doing as you can see is running a program externally:
It's not running anything externally. You've grabbed external code, but it's executed locally. Any changes that code makes to the global state is visible to you. In this case, main.lua has access to pingResult. For instance, you can write:
-- main.lua
local file = loadfile('nettest.lua')
file()
print(pingResult)
Of course, if you want a cleaner separation between your script and ping module, you should probably have that code return a value rather than write to a global:
-- main.lua
local file = loadfile('nettest.lua')
local pingResult = file()
print(pingResult)
-- nettest.lua
local pingResult
-- ... code the computes the result an stores it in pingResult ...
return pingResult

How do I catch SocketExceptions in MonkeyRunner?

When using MonkeyRunner, every so often I get an error like:
120830 18:39:32.755:S [MainThread] [com.android.chimpchat.adb.AdbChimpDevice] Unable to get variable: display.density
120830 18:39:32.755:S [MainThread] [com.android.chimpchat.adb.AdbChimpDevice]java.net.SocketException: Connection reset
From what I've read, sometimes the adb connection goes bad, and you need to reconnect. The only problem is, I'm not able to catch the SocketException. I'll wrap my code like so:
try:
density = self.device.getProperty('display.density')
except:
print 'This will never print.'
But the exception is apparently not raised all the way to the caller. I've verified that MonkeyRunner/jython can catch Java exceptions the way I'd expect:
>>> from java.io import FileInputStream
>>> def test_java_exceptions():
... try:
... FileInputStream('bad mojo')
... except:
... print 'Caught it!'
...
>>> test_java_exceptions()
Caught it!
How can I deal with these socket exceptions?
You will get that error every odd time you start MonkeyRunner because the monkey --port 12345 command on the device isn't stopped when your script stops. It is a bug in monkey.
A nicer way to solve this issue is killing monkey when SIGINT is sent to your script (when you ctrl+c). In other words: $ killall com.android.commands.monkey.
Quick way to do it:
from sys, signal
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
device = None
def execute():
device = MonkeyRunner.waitForConnection()
# your code
def exitGracefully(self, signum, frame=None):
signal.signal(signal.SIGINT, signal.getsignal(signal.SIGINT))
device.shell('killall com.android.commands.monkey')
sys.exit(1)
if __name__ == '__main__':
signal.signal(signal.SIGINT, exitGracefully)
execute()
Edit:
as an addendum, I also found a way to notice the Java errors: Monkey Runner throwing socket exception broken pipe on touuch
Edit:
The signal seems to require 2 parameters, not sure it's always the case, made the third optional.
Below is the workaround I ended up using. Any function that can suffer from adb failures just needs to use the following decorator:
from subprocess import call, PIPE, Popen
from time import sleep
def check_connection(f):
"""
adb is unstable and cannot be trusted. When there's a problem, a
SocketException will be thrown, but caught internally by MonkeyRunner
and simply logged. As a hacky solution, this checks if the stderr log
grows after f is called (a false positive isn't going to cause any harm).
If so, the connection will be repaired and the decorated function/method
will be called again.
Make sure that stderr is redirected at the command line to the file
specified by config.STDERR. Also, this decorator will only work for
functions/methods that take a Device object as the first argument.
"""
def wrapper(*args, **kwargs):
while True:
cmd = "wc -l %s | awk '{print $1}'" % config.STDERR
p = Popen(cmd, shell=True, stdout=PIPE)
(line_count_pre, stderr) = p.communicate()
line_count_pre = line_count_pre.strip()
f(*args, **kwargs)
p = Popen(cmd, shell=True, stdout=PIPE)
(line_count_post, stderr) = p.communicate()
line_count_post = line_count_post.strip()
if line_count_pre == line_count_post:
# the connection was fine
break
print 'Connection error. Restarting adb...'
sleep(1)
call('adb kill-server', shell=True)
call('adb start-server', shell=True)
args[0].connection = MonkeyRunner.waitForConnection()
return wrapper
Because this may create a new connection, you need to wrap your current connection in a Device object so that it can be changed. Here's my Device class (most of the class is for convenience, the only thing that's necessary is the connection member:
class Device:
def __init__(self):
self.connection = MonkeyRunner.waitForConnection()
self.width = int(self.connection.getProperty('display.width'))
self.height = int(self.connection.getProperty('display.height'))
self.model = self.connection.getProperty('build.model')
def touch(self, x, y, press=MonkeyDevice.DOWN_AND_UP):
self.connection.touch(x, y, press)
An example on how to use the decorator:
#check_connection
def screenshot(device, filename):
screen = device.connection.takeSnapshot()
screen.writeToFile(filename + '.png', 'png')