之前学习了Floodlight的模块加载:
今天来看看控制器是怎么运行的,我们来看看FloodlightProvider这个模块,直接看这个类里面主要的一些代码:
public class FloodlightProvider implements IFloodlightModule {
Controller controller;
public FloodlightProvider() {
//初始化了一个Controller类实例
controller = new Controller();
}
@Run(mainLoop=true)
public void run() throws FloodlightModuleException {
//启动controller
controller.run();
}
}
原来FloodlightProvider里面包含了Controller(控制器),控制器是通过FloodlightProvider模块的加载而启动的。
继续按照代码执行跟踪,看下Controller里面是干什么的,以下为我从Controller类中抽取出来的代码,这样比较清晰:
public class Controller implements IFloodlightProviderService, IStorageSourceListener, IInfoProvider {
//一个更新的队列
protected static BlockingQueue<IUpdate> updates;
//类的内部定义了一个接口
public interface IUpdate {
/**
* Calls the appropriate listeners
*/
public void dispatch();
}
}
//向队列添加一个update
@Override
public void addUpdateToQueue(IUpdate update) {
try {
updates.put(update);
} catch (InterruptedException e) {
// This should never happen
log.error("Failure adding update {} to queue.", update);
}
}
//run方法中是从队列中取出IUpdate实现并调用dispatch方法
@Override
public void run() {
moduleLoaderState = ModuleLoaderState.COMPLETE;
if (log.isDebugEnabled()) {
logListeners();
}
while (true) {
try {
IUpdate update = updates.take();
update.dispatch();
} catch (InterruptedException e) {
log.error("Received interrupted exception in updates loop;" +
"terminating process");
log.info("Calling System.exit");
System.exit(1);
} catch (StorageException e) {
log.error("Storage exception in controller " +
"updates loop; terminating process", e);
log.info("Calling System.exit");
System.exit(1);
} catch (Exception e) {
log.error("Exception in controller updates loop", e);
}
}
}
要明白上面的代码,得先看看IUpdate是做什么的,让我们看看有哪些类实现了IUpdate,如下图,有三个类实现它。
那我们看下SwitchUpdate这个类:
class SwitchUpdate implements IUpdate {
@Override
public void dispatch() {
if (log.isTraceEnabled()) {
log.trace("Dispatching switch update {} {}", swId, switchUpdateType);
}
if (switchListeners != null) {
for (IOFSwitchListener listener : switchListeners) {
switch(switchUpdateType) {
case ADDED:
// don't count here. We have more specific
// counters before the update is created
listener.switchAdded(swId);
break;
case REMOVED:
// don't count here. We have more specific
// counters before the update is created
listener.switchRemoved(swId);
break;
case PORTCHANGED:
counters.switchPortChanged
.increment();
listener.switchPortChanged(swId, port, changeType);
break;
case ACTIVATED:
// don't count here. We have more specific
// counters before the update is created
listener.switchActivated(swId);
break;
case DEACTIVATED:
// Called on master to slave transitions, ROLE_STATUS message.
listener.switchDeactivated(swId);
break;
case OTHERCHANGE:
counters.switchOtherChange
.increment();
listener.switchChanged(swId);
break;
}
}
}
}
}
从上面代码可以看到这个类是用来处理交换机事件的(新增、移除等等),在事件来临的时候,调用listener中对应的方法.
那么我们知道原来IUpdate是Controller类提供给其它类的一个接口,通过调用Controller暴露的addUpdateToQueue方法,将IUpdate实例放入队列中,将它加入Controller的调度当中。所以Controller在这里的作用主要是进行调度,那么控制器是如何与交换机进行交互,交换机的消息是怎样分发到各个模块上的,我们下一节再继续学习.