1 前言
在看openstack中的nova代码的时候,创建虚拟机和热迁移的时候,nova侧会创建event时间机制,然后会wait阻塞,直至neutron发送相应的通知消息。代码如下:
def _create_guest_with_network(self, context, xml, instance, network_info,
block_device_info, power_on=True,
vifs_already_plugged=False,
post_xml_callback=None,
external_events=None,
cleanup_instance_dir=False,
cleanup_instance_disks=False):
timeout = CONF.vif_plugging_timeout
if (
CONF.libvirt.virt_type in ('kvm', 'qemu') and
not vifs_already_plugged and power_on and timeout
):
events = (external_events if external_events
else self._get_neutron_events(network_info))
else:
events = []
pause = bool(events)
guest: libvirt_guest.Guest = None
try:
with self.virtapi.wait_for_instance_event(
instance, events, deadline=timeout,
error_callback=self._neutron_failed_callback):
self.plug_vifs(instance, network_info)
with self._lxc_disk_handler(context, instance,
instance.image_meta,
block_device_info):
guest = self._create_guest(
context, xml, instance,
pause=pause, power_on=power_on,
post_xml_callback=post_xml_callback)
.......
上述代码中的virtapi.wait_for_instance_event函数调用的是nova.nova.compute.manager.ComputeVirtAPI.wait_for_instance_event中的函数,该函数的作用是创建相应的事件。
并且将创建的事件用如下形式保存在nova.nova.compute.manager.InstanceEvents对象中
{
"instance_uuid":{
("network-vif-plugged", "vif_uuid1", object:event1)
("network-vif-plugged", "vif_uuid2", object:event2)
}
}
后面neutron组件再通过调用novaclinet接口:nova.nova.api.openstack.compute.server_external_events.ServerExternalEventsController.create,通过instance_uuid,选择某个instance中的event,再根据传入的name和tag,决定调用哪个event进行send。
因为上面用到了with、yield和event等关键字,下面将对这些用法进行分析
2 python中yield的作用
首先应该明白一些基本概念
1. 什么是迭代器,什么是生成器,迭代器和生成器之间有什么区别
迭代器:迭代只是访问集合元素的一种方式,迭代器有两个基本方法:iter()和next()。简单来说,字符串、元组和列表都是迭代器。只不过这些变量(迭代对象)在遍历的时候自动调用next()方法。
生成器:在python中,只要使用了yield的函数,被称为生成器(generator)。和普通函数不同的是,生成