MINAソース分析ノート1-Writeプロセス
IoSessionからwriteを呼び出すプロセス:
IoSession.write(oject message)
本当にこの方法を実現したのはAbstractIoSessionです.
1、writeFutureオブジェクトを作成し、非同期操作のためのリターン
2、入ってきたObjectの対象を、WriteRequestの対象として包装し、IoFilterCharinに処理する.
3、コアの実現はこれらのコードです.
以下はIoFilterCharinを見てどう処理しますか?
まず、IoFilterCharinは双方向リストでそれに含まれるすべてのfilterを保存するもので、大体の構造は以下の通りである.
head<->filter 1<->filter 2<->….<->filterN<->tail
その中のheadとtailは二つの固有、内蔵、特殊なfilterで、主に接続と移行の機能です.テーラーとはIoHandlerを呼び出す機能です.
IoFilterCharinに戻ってwriteの話題をどう処理しますか?
4、IoFilterCharinはリストからtailを見つけ、tailからfilterを検索し、順番に各filterのfilterWriteを呼び出す()方法
典型的な実装:
5、最後に必ずheadというfilterのfilterWriteに落ちます.その実現はちょっと特殊なはずです.IoProcessorにメッセージを送ることができます.
メッセージを送信キューに入れてIoProcessor flashを呼び出します.
プロシーザーがどうやってflashしていくかを見る前に、下のものを準備しておきます.
NOTE 1:このfilter転送中、IoSessionはずっと渡されています.
6、IoProcessorはどうやって処理しますか?
IoProcessorのflush方法はAbstractPollingIoProcessorクラスで実現されます.
これは、fluushingSessionsリストに導入されたsessionオブジェクトを追加します.
プロシーザー内のselector.wakeUpを呼び出します.
AbstractPollingIoProcessorクラスで独立して実行するProcessorスレッドは、select()待ちから呼び覚まされる.
7、AbstractPollingIoProcessorスレッド
呼び覚まされた後、flaushingSessionsからsessionオブジェクトを取り出し、sessionからWriteRequestオブジェクトを取り出します.
WriteRequestオブジェクトがIoBufferタイプの場合、
【この部分は多くの細部を省略しています.詳細については主にAbstractPollingIoProcessor類とNioProcessor類を見ます.】
8、これから、データを本当にネットに送信します.
IoSession.write(oject message)
本当にこの方法を実現したのはAbstractIoSessionです.
1、writeFutureオブジェクトを作成し、非同期操作のためのリターン
2、入ってきたObjectの対象を、WriteRequestの対象として包装し、IoFilterCharinに処理する.
3、コアの実現はこれらのコードです.
// Now, we can write the message. First, create a future
WriteFuture writeFuture = new DefaultWriteFuture(this);
WriteRequest writeRequest = new DefaultWriteRequest(message, writeFuture, remoteAddress);
// Then, get the chain and inject the WriteRequest into it
IoFilterChain filterChain = getFilterChain();
filterChain.fireFilterWrite(writeRequest);
//.....
return writeFuture;
以下はIoFilterCharinを見てどう処理しますか?
まず、IoFilterCharinは双方向リストでそれに含まれるすべてのfilterを保存するもので、大体の構造は以下の通りである.
head<->filter 1<->filter 2<->….<->filterN<->tail
その中のheadとtailは二つの固有、内蔵、特殊なfilterで、主に接続と移行の機能です.テーラーとはIoHandlerを呼び出す機能です.
IoFilterCharinに戻ってwriteの話題をどう処理しますか?
4、IoFilterCharinはリストからtailを見つけ、tailからfilterを検索し、順番に各filterのfilterWriteを呼び出す()方法
典型的な実装:
public void fireFilterWrite(WriteRequest writeRequest) {
Entry tail = this.tail;
callPreviousFilterWrite(tail, session, writeRequest);
}
private void callPreviousFilterWrite(Entry entry, IoSession session,
WriteRequest writeRequest) {
try {
IoFilter filter = entry.getFilter();
NextFilter nextFilter = entry.getNextFilter();
filter.filterWrite(nextFilter, session, writeRequest);
} catch (Throwable e) {
writeRequest.getFuture().setException(e);
fireExceptionCaught(e);
}
}
5、最後に必ずheadというfilterのfilterWriteに落ちます.その実現はちょっと特殊なはずです.IoProcessorにメッセージを送ることができます.
メッセージを送信キューに入れてIoProcessor flashを呼び出します.
public void filterWrite(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest) throws Exception {
AbstractIoSession s = (AbstractIoSession) session;
s.getWriteRequestQueue().offer(s, writeRequest);
if (!s.isWriteSuspended()) {
s.getProcessor().flush(s);
}
}
WriteRequest Queのデフォルトの実現はjava.util.co ncurrent.C.oncurrent LinkedQueで、伝来したsessionの対象を切り捨てます. プロシーザーがどうやってflashしていくかを見る前に、下のものを準備しておきます.
NOTE 1:このfilter転送中、IoSessionはずっと渡されています.
filterWrite(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest)
NOTE 2:実はheadというfilterは二つの方法しか実現していません.つまり、この二つの操作だけに関心を持っています. private class HeadFilter extends IoFilterAdapter {
@SuppressWarnings("unchecked")
@Override
public void filterWrite(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest) throws Exception { }
@SuppressWarnings("unchecked")
@Override
public void filterClose(NextFilter nextFilter, IoSession session)
throws Exception { }
}
6、IoProcessorはどうやって処理しますか?
IoProcessorのflush方法はAbstractPollingIoProcessorクラスで実現されます.
これは、fluushingSessionsリストに導入されたsessionオブジェクトを追加します.
プロシーザー内のselector.wakeUpを呼び出します.
AbstractPollingIoProcessorクラスで独立して実行するProcessorスレッドは、select()待ちから呼び覚まされる.
7、AbstractPollingIoProcessorスレッド
呼び覚まされた後、flaushingSessionsからsessionオブジェクトを取り出し、sessionからWriteRequestオブジェクトを取り出します.
WriteRequestオブジェクトがIoBufferタイプの場合、
if (buf.remaining() <= length) {
return session.getChannel().write(buf.buf());
}
WriteRequestオブジェクトがFileオブジェクトである場合、region.getFileChannel().transferTo(
region.getPosition(), length, session.getChannel());
レギオンはFileRegionの対象です.ファイルの内容をsessionのChannelに転送します.【この部分は多くの細部を省略しています.詳細については主にAbstractPollingIoProcessor類とNioProcessor類を見ます.】
8、これから、データを本当にネットに送信します.