#ovs agent的 monitor调用
daemon_loop
#返回一个轮询管理单元
polling.get_polling_manager
根据传参minimize_polling,建立接口轮询
InterfacePollingMinimizer
super(InterfacePollingMinimizer, self).__init__
#实际创建一个SimpleInterfaceMonitor
from neutron.agent.common import ovsdb_monitor
_monitor = ovsdb_monitor.SimpleInterfaceMonitor
#封装get events 是从monitor获取
get_events(self)
self._monitor.get_events()
class OvsdbMonitor(async_process.AsyncProcess)
#调用父类AsyncProcess的init
super(OvsdbMonitor, self).__init__
#获取monitor输出信息,并填入events返回,然后清空self.event等待下次
get_events()
self.process_events()
self.new_events = {'added': [], 'removed': [], 'modified': []}
return events
#启动需要监控的命令行,调用父类的start
start()
super(OvsdbMonitor, self).start()
class SimpleInterfaceMonitor(OvsdbMonitor)
#monitor的输出信息置空
self.new_events = {'added': [], 'removed': [], 'modified': []}
#调用父类OvsdbMonitor的init
super(SimpleInterfaceMonitor, self).__init__
#读取monitor输出信息并设置状态
has_updates()
self.process_events()
return bool(self.new_events['added'] or
self.new_events['removed'] or
self.new_events['modified'])
#从monitor命令行的stdout读取
process_events()
devices_added = []
devices_removed = []
devices_modified = []
dev_to_ofport = {}
for row in self.iter_stdout():
class AsyncProcess(object)
#初始化命令行信息
__init__((self, cmd, run_as_root=False, respawn_interval=None,
namespace=None, log_output=False, die_on_error=False)
self._reset_queues()
初始化两个queue,stdout和stderr
_reset_queues()
self._stdout_lines = eventlet.queue.LightQueue()
self._stderr_lines = eventlet.queue.LightQueue()
#判断cmd命令行是否还在执行
is_active():
启动命令行
start(self, block=False):
self._spawn()
common_utils.wait_until_true(self.is_active)
#启动命令行popen和创建两个协程,读取stdout和stderr
_spawn(self):
self._kill_event = eventlet.event.Event()
self._process, cmd = utils.create_process(self._cmd, run_as_root=self.run_as_root)
for reader in (self._read_stdout, self._read_stderr)
eventlet.spawn(self._watch_process, reader, self._kill_event)
#调用callback=reader读取stdout,并填入queue,然后sleep释放cpu
_watch_process(self, callback, kill_event):
output = callback()
eventlet.sleep()
#从stdout到queue
_read_stdout(self):
_read(self._process.stdout, self._stdout_lines)
#从stderr到queue
_read_stderr(self):
self._read(self._process.stderr, self._stderr_lines)
从stream流到put queue
_read(self, stream, queue):
data = stream.readline()
queue.put(data)
#从stdout queue读取
iter_stdout(self, block=False):
self._iter_queue(self._stdout_lines, block)
从stderr queue读取
iter_stderr(self, block=False):
self._iter_queue(self._stderr_lines, block)
从queue读取
_iter_queue(self, queue, block):
yield queue.get(block=block)
python文件执行火焰图
pip install py-spy
py-spy record -o profile.svg --pid 12345
# OR
py-spy record -o profile.svg -- python myprogram.py
py-spy top --pid 12345
# OR
py-spy top -- python myprogram.py
py-spy dump --pid 12345
函数调用关系图
pip3 install pycallgraph
if __name__ == "__main__":
from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput
graphviz = GraphvizOutput()
graphviz.output_file = 'basic.png'
with PyCallGraph(output=graphviz):
LINK_STATE = NicLinkStateCheck()
LINK_STATE.start_check()