接着上一篇,到MessageRunner执行build_instances, 调用nova/cells/messaging.py中_TargetedMessage的process方法:
在_TargetedMessage(_BaseMessage)的__init__中:
message_type = 'targeted'
if isinstance(target_cell, cells_state.CellState):
# Neighbor cell or ourselves. Convert it to a 'full path'.
if target_cell.is_me:
target_cell = self.our_path_part
else:
target_cell = '%s%s%s' % (self.our_path_part,_PATH_CELL_SEP,target_cell.name)
self.target_cell = target_cell
在_BaseMessage中执行 self._append_hop():
self.routing_path = routing_path + self.our_path_part
self.hop_count += 1
初始化routing_path为None,第一次routing_path为self.our_path_part,和target_cell一样,都是nova.cells.name
由前面知道,此时target_cell就是运行nova-api的cell,一般的就是parent cell,默认从parent cell开始,在process中:
next_hop = self._get_next_hop(),函数中:
f self.target_cell == self.routing_path:
return self.state_manager.my_cell_state #第一次next_hop就是自己
if next_hop.is_me:
# Final destination.
response = self._process_locally() #在自己(nova-api 节点或parent cell)执行:
1. resp_value = self.msg_runner._process_message_locally(self)
2. 执行_process_message_locally(self, message):
3.前面message_type = 'targeted',因此,执行'targeted':_TargetedMessageMethods的方法
4. self.msg_runner.scheduler.build_instances(message, build_inst_kwargs),调用scheduler
5.MessageRunner中定义了scheduler,默认为nova.cells.scheduler.CellsScheduler
6.记住,_process_message_locally时传入的message是刚才提到的_TargetedMessage(_BaseMessage)
7.在scheduler中执行:
return method(message, target_cells, instance_uuids, method_kwargs)
method为_build_instances,target_cells是scheduler中通过_grab_target_cells得到的target_cells
这里有一个比较巧的地方在于使用scheduler来filter child cells时:
def _get_possible_cells(self):
cells = self.state_manager.get_child_cells()
our_cell = self.state_manager.get_my_state()
# Include our cell in the list, if we have any capacity info
if not cells or our_cell.capacities:
cells.append(our_cell)
return cells
如果child cell不为空就用child cell,否则就用当前cell,而 self.state_manager.get_child_cells()执行时,decorator为:@sync_before
其中会从DB或者file重新_refresh_cells_from_dict达到update或者add cells的目的
cell_info.update_db_info(db_dict)
cells_dict[cell_name] = self.cell_state_cls(cell_name) #这里cell_dict为self.parent_cells或self.child_cells,而cell_state_cls实例化时,不曾传入is_me,
使得接下来的操作不是当前节点。
8.再次执行MessageRunner的build_instances方法,不过target_cells已经成为下一跳了,同时is_me不再是true而是false,会使用:
self.driver.send_message_to_cell(self, message)
用rpc driver向target cell发送rpc call
return self._send_response(response)
通过前面看到是同parent到cell一层一层下来的,运行完成返回时执行_send_response,一层一层返回去
待续。。。。