view chapter3.tex @ 4:14e96778c600

update
author oc
date Mon, 16 Feb 2015 01:03:14 +0900
parents 63ae5aaa2a7a
children 1bc81f8b7517
line wrap: on
line source

\chapter{TreeVNC のリファクタリング}

\section{動的な port 番号の指定}
TreeVNCは複雑な分散アルゴリズムを用いたシステムであり、
デバッグを行う環境を整える必要がある。

従来のTreeVNCでは、固定port番号を複数利用していた。
port番号は一意なので、1台で複数のTreeVNCを立ち上げることができない。

動的にport番号を割り当てることで、
1つのnodeに対して複数のTreeVNCを起動することを可能にした。
最低限のソケットポートを開けることによって、
メモリの使用量を抑えることにも繋がる。

以下に、動的に port 番号を割り当てているソースコードを記述する。

% selectPort する箇所を記述する

\begin{lstlisting}[caption=オプション--fixSize,label=fixsize]
    public int selectPort(int p) {
        int port = p;
        while (true) {
            try {
                servSock = new ServerSocket(port);
                acceptPort = port;
                myAddress = "127.0.0.1";
                nets.getNetworkInterfaces();
                break;
            } catch (BindException e) {
                port++;
                continue;
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("accept port = " + port);
        return port;
    }
\end{lstlisting}


%  messageの説明にportにどんな関係があるのかとから
以前は固定port番号を使用しmessageの通信を行っていたが、
一意なportを割り当てられているnodeが通信を行うことによって、
どのport番号が使用されているかを意識する必要がなくなった。

\newpage

\section{QUALITYモードとSPEEDモード}

高解像度のまま拡大・縮小の処理を行うと、
PCのスペックによって描画処理に時間がかかってしまうことがある。
授業中に TreeVNC を使用する際、
拡大・縮小をしてしまうと描画処理が重くなり遅延が生じていた。

画像描画処理には、品質優先( QUALITY モード)・スピード優先( SPEED モード)がある。
今まで TreeVNC は基本的に QUALITY モードを設定していた。

どちらのモードを使用するかをビューワから変更出来るようにした。
これにより、描画処理の遅延を解決することができた。


\section{ホスト切り替え時の挙動の修正}
画面の切り替えを行う際、新しいホスト側の画面に生じた
ビデオフィードバックが他のユーザに配信されてしまう問題があった。

ホストの切り替えの際、
新しいホスト側のviewerを閉じることで問題を解決した。


\newpage


\section{Tree の構成の変更}

従来のTreeVNCは、クライアントの接続する木構造が単一であった。
そのため、ネットワークインターフェースが違うクライアントが
同じ木に混在している状況が生じた。
速度の遅いクライアントが木に存在すると、
そのクライアント以下の通信速度が遅くなってしまう。

この問題を解決するために、
図\ref{fig:multinetworktree}の様に、ネットワークインターフェース別に
木構造を形成するように設計した。

TreeVNCは、rootがnodeListというリストを保持し、木構造を管理している。
複数のネットワークインターフェースで木構造を形成する場合、
このnodeListをネットワークインターフェース毎に作成しておく。
新しいnodeを接続する際、nodeのネットワークインターフェースを取得し、
どのnodeListに登録されるかが決まる。
こうすることによって、TreeVNCを複数のネットワークインターフェイス別に
木構造を構成することができる。

\begin{figure}[htpd]
  \begin{center}
    \includegraphics[scale=0.4]{./images/chapter3/MultiNetworkTree.pdf}
  \end{center}
  \caption{Multi Network Tree}
  \label{fig:multinetworktree}
\end{figure}


\newpage

\section{切断時の検知方法の変更}

接続していたクライアントとの接続が切れた際の検知方法を変更した。

root は nodeList という TreeVNC のネットワークトポロジーを管理するためのリストを持っている。
root は TreeVNC の接続処理の全てを担っている。
%node が切断された場合、 root は TreeVNC の木構造を崩さないように切断を検知し、
%木構造を崩さないよう、 node 同士の接続を再構成しなければならない。
node の接続が切れた場合、代わりとなる node の接続が必要となるため root に知らせなければならない。

変更前は、lostParent という検知方法を採用していた。
この方法は、親となる node の接続が切れた場合、
子となる node から root に対して lostParent message を送信する。
これにより root は lostParent を検知し、代替 node の接続を行う。

以下に、lostParent の検知・再接続方法を記述する。

\begin{itemize}
  \item 親 node の接続が切れる
  \item 切れた親 node に接続していた子 node が root に LOST\_PARENT message を送信する
  \item root が nodeList の更新を行う
  \item 切れた親 node の代わりに、nodeList の最後尾 node を配置する
  \item 親 node を失った子 node は、新しい親 node に接続する
\end{itemize}

この方法では、子のいない末端の node の接続が切れた際に root にメッセージが送信されない。
root は切断を検知できないと、nodeList の更新を行うことができない。
nodeList が正しく更新されない場合、図\ref{fig:lostparent}のように、
新しい node を既に切断されている node に接続しようと試み、失敗してしまう。

\begin{figure}[htpd]
  \begin{center}
    \includegraphics[scale=0.7]{./images/chapter3/lostParent.pdf}
  \end{center}
  \caption{lostParent}
  \label{fig:lostparent}
\end{figure}

\newpage

末端 node の切断が検知できない問題を解決するために、
lostChild という検知方法に変更した。

TreeVNC は、画像データ(framebufferUpdate)が MulticastQueue という Queue に蓄積される。
node はこの Queue から画像データを取得し、描画している。
lostChild の検出方法は、この MulticastQueue を使用している。
ある一定時間、MulticastQueue から画像データが取得されない場合、
その node との接続が切れたと判断することができる。

以下に、lostChild の検知・再接続方法を記述する。

\begin{itemize}
  \item 子 node の切断を検知した node が root へ LOST\_CHILD message を送信する(図\ref{fig:lostchild1}中, 1:)
  \item LOST\_CHILD message を受け取った root は nodeList の更新を行う(図\ref{fig:lostchild1}中, 2:)
  \item 切断した node を nodeList から消し、nodeList の最後尾の node に切断した node number を割り当てる
  \item root は最後尾の node に、切断した子 node が接続していた親 node に接続する様に CONNECT\_TO message を送信する(図\ref{fig:lostchild1}中, 3:)
  \item 最後尾の node が子 node を失った親 node へ接続しに行く(図\ref{fig:lostchild1}中, 4:)
\end{itemize}

\begin{figure}[htpd]
  \begin{center}
    \includegraphics[scale=0.7]{./images/chapter3/lostChild1.pdf}
  \end{center}
  \caption{lostChild を検知・再接続}
  \label{fig:lostchild1}
\end{figure}

\newpage

lostChild を検知することより、
切断されてしまった全ての node を検知することができるので、
nodeList の更新が正しく行われる。

新しい node からの接続要求 WHERE\_TO\_CONNECT message に対して、
適切な node への接続を提供することができる(図\ref{fig:lostchild2}中, 1,2:)。

\begin{figure}[htpd]
  \begin{center}
    \includegraphics[scale=0.7]{./images/chapter3/lostChild2.pdf}
  \end{center}
  \caption{新 node の接続}
  \label{fig:lostchild2}
\end{figure}