之前學習了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在這裏的作用主要是進行調度,那麼控制器是如何與交換機進行交互,交換機的消息是怎樣分發到各個模塊上的,我們下一節再繼續學習.