完成得太快时,Ansible Runner 的连续调用会混乱
Ansible Runner consecutive calls mess up when done too fast
我使用官方 Ansible Runner 库制作了一个软件,该软件接收对 运行 1 次或 N 次 1 次或 M 剧本的多次远程调用...
Ansible 运行 配置是顺序的,虽然这不应该与不同的调用相关(如果我理解正确,它只是在同一个剧本 运行 中配置任务)
所以,我 运行 使用 Ansible Runner 的剧本 run_async()
:
runner_async_thread, runner_object = ansible_runner.run_async(
**{k: v for k, v in kwargs.items() if v is not None})
并保持异步线程的 is_alive()
方法循环,检查其他条件
while runner_async_thread.is_alive():
...
如果出现异常,或者线程结束后,我只检查状态结果和return。
问题是,当系统同时接收到很多调用时,它会出现混乱,我会收到如下错误:
The offending line appears to be:
{"username": "operator", "password": "!", "target": "sever_003_linux"}05_linux"}
^ here
We could be wrong, but this one looks like it might be an issue with
unbalanced quotes. If starting a value with a quote, make sure the
line ends with the same set of quotes. For instance this arbitrary
example:
foo: "bad" "wolf"
Could be written as:
foo: '"bad" "wolf"'
错误显然是这样的:
{"username": "new_user", "target": "sever_003_linux"}05_linux"}
我仔细检查了(日志和 env/extravars 文件),但发送的命令是正确的:
{"username": "new_user", "target": "sever_003_linux"}
所以,似乎一个内存区域在没有被清理的情况下被覆盖,可能是 2 运行ners 运行在没有线程安全的情况下在一起(似乎是可能的)?
请问您对如何解决这个问题或防止它发生有什么想法吗?
代码正常工作,使用一些延迟时相同的调用工作,但我认为这不是一个理想的解决方案...
我正在玩 Ansible 配置,但没办法。
ansible 2.9.6
python version = 3.8.10 (default, Jun 2 2021, 10:49:15) [GCC 9.4.0]
我发现更多人在这个 Jira 故事中报告了这个问题:https://jira.opencord.org/browse/CORD-922
Ansible, when used via its API, is not thread-safe.
他们还提出了一个关于如何克服这个问题的想法:
To be safe and avoid such issues, we will wrap invocations of Ansible in a process by invoking a fork() before using it.
但是,就我而言,我必须 return 报告操作的结果。因此,我声明了一个共享队列以进行进程通信,并且我分叉了主要队列。
import ansible_runner
from multiprocessing import Queue
import os
#...
def playbook_run(self, parameters):
#...
runner_async_thread, runner_object = ansible_runner.run_async(
**{k: v for k, v in kwargs.items() if v is not None})
while runner_async_thread.is_alive():
#...
return run_result
shared_queue = Queue()
process_pid = os.fork()
if process_pid == 0: # the forked child process will independently run & report
run_result = self.playbook_run(playbook_name,
parameters)
shared_queue.put(run_result)
shared_queue.close()
shared_queue.join_thread()
os._exit(0)
else: # the parent process will wait until it gets the report
run_result = shared_queue.get()
return run_result
而且,假设缺乏线程安全是问题所在,问题就解决了。
因为我认为它没有被报道,我在 Ansible Runner 开发者中打开了一个问题 GitHub:https://github.com/ansible/ansible-runner/issues/808
我使用官方 Ansible Runner 库制作了一个软件,该软件接收对 运行 1 次或 N 次 1 次或 M 剧本的多次远程调用... Ansible 运行 配置是顺序的,虽然这不应该与不同的调用相关(如果我理解正确,它只是在同一个剧本 运行 中配置任务)
所以,我 运行 使用 Ansible Runner 的剧本 run_async()
:
runner_async_thread, runner_object = ansible_runner.run_async(
**{k: v for k, v in kwargs.items() if v is not None})
并保持异步线程的 is_alive()
方法循环,检查其他条件
while runner_async_thread.is_alive():
...
如果出现异常,或者线程结束后,我只检查状态结果和return。
问题是,当系统同时接收到很多调用时,它会出现混乱,我会收到如下错误:
The offending line appears to be:
{"username": "operator", "password": "!", "target": "sever_003_linux"}05_linux"}
^ here
We could be wrong, but this one looks like it might be an issue with
unbalanced quotes. If starting a value with a quote, make sure the
line ends with the same set of quotes. For instance this arbitrary
example:
foo: "bad" "wolf"
Could be written as:
foo: '"bad" "wolf"'
错误显然是这样的:
{"username": "new_user", "target": "sever_003_linux"}05_linux"}
我仔细检查了(日志和 env/extravars 文件),但发送的命令是正确的:
{"username": "new_user", "target": "sever_003_linux"}
所以,似乎一个内存区域在没有被清理的情况下被覆盖,可能是 2 运行ners 运行在没有线程安全的情况下在一起(似乎是可能的)? 请问您对如何解决这个问题或防止它发生有什么想法吗?
代码正常工作,使用一些延迟时相同的调用工作,但我认为这不是一个理想的解决方案...
我正在玩 Ansible 配置,但没办法。
ansible 2.9.6
python version = 3.8.10 (default, Jun 2 2021, 10:49:15) [GCC 9.4.0]
我发现更多人在这个 Jira 故事中报告了这个问题:https://jira.opencord.org/browse/CORD-922
Ansible, when used via its API, is not thread-safe.
他们还提出了一个关于如何克服这个问题的想法:
To be safe and avoid such issues, we will wrap invocations of Ansible in a process by invoking a fork() before using it.
但是,就我而言,我必须 return 报告操作的结果。因此,我声明了一个共享队列以进行进程通信,并且我分叉了主要队列。
import ansible_runner
from multiprocessing import Queue
import os
#...
def playbook_run(self, parameters):
#...
runner_async_thread, runner_object = ansible_runner.run_async(
**{k: v for k, v in kwargs.items() if v is not None})
while runner_async_thread.is_alive():
#...
return run_result
shared_queue = Queue()
process_pid = os.fork()
if process_pid == 0: # the forked child process will independently run & report
run_result = self.playbook_run(playbook_name,
parameters)
shared_queue.put(run_result)
shared_queue.close()
shared_queue.join_thread()
os._exit(0)
else: # the parent process will wait until it gets the report
run_result = shared_queue.get()
return run_result
而且,假设缺乏线程安全是问题所在,问题就解决了。
因为我认为它没有被报道,我在 Ansible Runner 开发者中打开了一个问题 GitHub:https://github.com/ansible/ansible-runner/issues/808