MINAソース分析ノート1-Writeプロセス


IoSessionからwriteを呼び出すプロセス:
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、これから、データを本当にネットに送信します.