comparison final_main/chapter2/chapter2.tex @ 9:a37b7bd13be9

...
author ichikitakahiro <e165713@ie.u-ryukyu.ac.jp>
date Tue, 11 Feb 2020 21:59:14 +0900
parents f71206f427e3
children 5ddb3e41e515
comparison
equal deleted inserted replaced
8:f71206f427e3 9:a37b7bd13be9
1 %\input{/Users/e155753/.tex/setup} 1 %\input{/Users/e155753/.tex/setup}
2 2
3 %%文書開始**************************** 3 %%文書開始****************************
4 \begin{document} 4 \begin{document}
5 %%************************************** 5 %%**************************************
6 \chapter{分散フレームワークChrisiteについて} 6 \chapter{リモートエディタ}
7 ここでは本研究室で開発している分散フレームワークChrisiteについて解説する. Chrisiteは複雑な分散プログラムを簡潔に書くことのできる構成となっている. 7 リモートエディタとは他のマシン上に存在するファイルのバッファを別デバイスから開いて編集, 保存することができる機能である. 加えてこのリモートエディタを複数人が同時に同じファイルを編集し, その上変更がリアルタイムに反映されるように設計する.
8 この章ではリモートエディタの実装の上で踏んだプロセスや, 開発の上で問題となる点と解決策について説明する。
9
10 \section{document listenerによる編集オフセット番号の読み取り}
11 エディタ同士の基本通信環境の構成のため, Chrisitie と同様のjava 言語で作成したエディタのインスタンスを使い, 異なるマシン同士の同期の実現を目指した. 自作エディタは java. swingの機能で構成されており, 追記または削除されたオフセット位置とその内容の取得はDocumentListenrを使用した. DocumentListenerのクラスはswingで実装したエディタ部分の入力と削除を検知し, 動作するメソッドであり, DocumentEvent内に入力されたオフセットとその長さや文字列が入力されるため, それをChrisitie側で検知し処理を行った.
12 insertUpdateメソッドではバッファに入力が行われた際に自動的に実行され, removeUpdateメソッドは同様に削除が行われた際に実行される. 他ノードから送信されてきた命令によるバッファの変更によっても実行され, 意図しないループが発生したため, 受信した命令では実行されないように記述をおこなった.
13
14 \lstinputlisting[caption=DocumentListenerのコード部分, label=code:DocumentListener]{./src/DocumentListener.java}
8 15
9 16
10 \section{Chrisiteとは} 17 \section{Command パターンによる命令オブジェクトの作成}
11 ChristieはJava言語で構成された本研究室独自の分散フレームワークである。同じく本研究室で開発を行っているGearsOSのファイルシステムに組み込む予定があるため, GearsOSを構成している本研究室の独自の言語Continuation based C (以下CbC言語)とにた, Gearというプログラム概念が存在する. 18 リモートエディタを実装する上において, 各エディタは自身に起きたバッファの変更を対応した他ノードに送信する必要がある. この変更の送り合いをCommand パターンとして実装した. Command パターンとは, 命令を一つのオブジェクトとして表現する方法である. コマンドパターンの利点として,
19 \begin{itemize}
20 \item インスタンスを利用して命令を作成するため, ChristieのGearの概念と相性が良い.
21 \item 命令に必要な内容をまとめて送信するため, 相違の発生を防ぐことができる.
22 \item 命令の管理が行いやすい, 行列に並ばせ命令の順番を管理したり, 命令の際実行, 取り消しが容易になる.
23 \end{itemize}
24 といった点が挙げられる. ソースコード:\ref{code:Command}は書き込み, 送信を行う際の命令をクラスとして作成したものである. このクラスのインスタンスを命令オブジェクトとして送信し合う.
25
26 \lstinputlisting[caption=Commandパターンとして実装した命令, label=code:Command]{./src/Command.java}
27
28 \section{命令オブジェクトを実装する際に起きた問題}
29 インスタンス化した命令を他ノードに送信する際にエラーが発生し, 送信に失敗してしまうという問題が発生した. クラスの送信の際のシリアライズはmsgpackクラスを利用していた.
30 msgpackクラスは,シリアライズしたいクラスにMessage アノテーションをつけることにより, シリアライズ化を行う. 原因を調査した結果, 以下の原因が見つかった.
12 31
13 \begin{itemize} 32 \begin{itemize}
14 \item CodeGear(以下 CG) 33 \item Christieのjavaバージョンは11を使用していたが, msgpackバージョン0.6.12はjava11に対して対応していなかった.
15 \item DataGear(以下 DG) 34 \item msgpackの最新版0.8.20はシリアライズ機能が含まれなくなった.
16 \item CodeGearManager(以下 CGM)
17 \item DataGearManager(以下 DGM)
18 \end{itemize} 35 \end{itemize}
19 36
20 CodeGearはクラスやスレッドに相当しする. DataGear は変数データに相当し, javaのアノテーション機能を用いて記述する. CG内に記述したKeyに全てのDGが揃った際に初めてそのCGが動作するという仕組みになっている. CodeGearManager はいわゆるノードに相当し、CG, DG ,DGM を管理する. DataGearManager は DG を管理するもので, put という操作により DG , 要するに変数データを格納することができる。DGM の put 操作を行う際には Local と Remote と 2 つのどちらかを選び, 変数の key とデータを引数に書く. Local であれば, Local の CGM が管理している DGM に対し, DG を格納していく. Remote であれば接続した Remote 先の CGM の DGM に DG を格納できる. put 操作を行ったあとは, 対象の DGM の中に queue として保管される. \\ 37 以上の原因に対処するために以下のことを行った.
21 DG を取り出す際には, CG 内で宣言した変数データにアノテーションをつける. DG のアノテーションには Take, Peek, TakeFrom, PeekFrom の 4 つがある.
22 38
23 \begin{description} 39 \begin{itemize}
24 \item[Take] 先頭のDGを読み込み, そのDGを削除する. DGが複数ある場合, この動作を用いる. 40 \item Christieのjavaバージョンを8まで下げ, msgpackバージョン0.6.12を動作できるようにした.
25 \item[Peek] 先頭のDGを読み込むが, DGが削除されない. そのため, 特に操作をしない場合は同じデータを参照し続ける. 41 \item シリアライズする命令クラスに対し, フィールドをpublic にした.
26 \item[TakeFrom(Remote DGM name)] Takeと同様に読み込んだ後, DGを削除する. Remote DGM nameを指定することで, その接続先(Remote)のDGMからTake操作を行える. 42 \item javassistのバージョンを最新版へ変更した.
27 \item[PeekFrom(Remote DGM name)] Peekと同様に読み込み後もDGが削除されないが, Remote DGM nameを指定することで, その接続先(Remote)のDGMからPeek操作を行える. 43 \end{itemize}
28 \end{description}
29 44
30 \section{プログラムの例} 45 javaのバージョンを下げたのは応急的な処置となってしまったが, これらの処置により問題なくCommandパターンでの命令実装を行うことができた. javaのバージョンに左右されずリモートエディタを実装するには, シリアライズの機能について他のパッケージを使うか, 自信で作成する必要が生まれた。
31 以下のソースコード\ref{code:nStartHelloWorld} , \ref{code:HelloWorldCodeGear}のプログラムはChrisitieの基本動作となる DGM による put 操作を用いた hello world の出力プログラムである. メソッド sreateCGM でポート番号を指定した上で CGM を作成しする. CGM にCG (クラスファイル)を指定した上でsetupすることでCGMが CGを動作させることができる. HelloWorldCodeGear()とFinishHelloWorld()がここではCGに当たる. HelloWorldCodeGear() クラスには String型の"helloWorld" という key が用意され, "helloWorld"に入力された DG(String型の変数データ) をprint するコードである. "helloWorld" に hello と worldというDGをputすることで出力結果がhello world となる.
32 \lstinputlisting[caption=StartHelloWorld,label=code:nStartHelloWorld]{./src/HelloWorld/StartHelloWorld.java}
33
34 \lstinputlisting[caption=HelloWorldCodeGear,label=code:HelloWorldCodeGear]{./src/HelloWorld/HelloWorldCodeGear.java}
35
36 CGM は起動し続けていると処理が自動的に終了しないという問題点がある. そこで役目がなくなったCGM を終了させるための処理を行わなければならない. CGMを終了させるためのプログラムはソースコード\ref{code:FinishHelloWorld} であり, 二つのkeyが揃ったらcgm.getLocalDGM().finish() の処理でcgmを終了させるよう記述されている.
37
38 \lstinputlisting[caption=FinishHelloWorld, label=code:FinishHelloWorld]{./src/FinishHelloWorld.java}
39 46
40 47
41 48 \section{編集位置の相違}
42 49 セッション中のエディタ間の通信で生じうる, 編集結果の相違について説明する. エディタ同士のコマンドの送信はそれぞれが独立して行うため, 編集対象の領域にエディタ間で相違が生じる場合がある. 例としてエディタが一対一の接続となっている時に発生しうる相違を図\ref{fig:difference} を使用して解説する.
43 50 編集対象は各オフセット番号に同じ値の数字が入っているものとする. EditorA ではオフセット番号 3 の 3 という 要素を削除 (テキストエディタ上のため削除されたオフセットにはその後ろの要素が繰り上げられる.), EditorB では オフセット番号 2 に A という要素を挿入するという編集をしたとする. この編集を共通プロトコルとして互いに送信しあった際, 本来編集する予定だったオフセットの中身が異なってしまい編集結果に違いが生じてしまう. これらの問題を解決することのできるエディタ同士の通信手法を作成しなければならない。
44 \section{TopologyManager について}
45 ここではChrstie上でノード同士の接続をより簡潔にするために使われるTopologyManagerという機能について説明する.
46 TopologyManagerとはTopologyを形成するために, 参加を表明したノード, TopologyNodeにlabel を与え, 必要があればノード同士の配線も自動で行う機能である.
47 TopologyManagerのTopologyの形成方法として静的Topologyと動的Topologyの二つの方法がある. 静的Topologyはソースコード: \ref{code:dotFile} のようなdotファイルを与えることでノードの接続を図 \ref{fig:dot} のように接続することができる. 例えばnode0 からはnode1 はright という名前で参照することができ, それぞれのノードが同じCG を実行してもlabel の与え方次第で想定したDG の差し合いを実現することができる. 静的Topologyはdotファイルのノード数と同等のTopologyNodeがあって初めて, CodeGear が実行され, ノード数が合わないとエラーが表示
48 される.
49
50 \lstinputlisting[caption=ringを構成するdotファイル, label=code:dotFile]{./src/ring.dot}
51 51
52 \begin{figure}[H] 52 \begin{figure}[H]
53 \centering 53 \centering
54 \fbox{ 54 \fbox{
55 \includegraphics[scale=1]{./images/ring.pdf} 55 \includegraphics[scale=0.6]{./images/difference_offset.pdf}
56 } 56 }
57 \caption{ソースコード \ref{code:dotFile} のdotファイルを図示化したもの} 57 \caption{通信のすれ違いによる編集位置の相違}
58 \label{fig:dot} 58 \label{fig:difference}
59 \end{figure} 59 \end{figure}
60 60
61 動的Topologyは参加を表明したノードを順番にTopologyの構成要素として接続していく物である. 現在時点で実装済みのTreeの構成を例とすると 61 \section{編集位置の相違解消方法}
62 62 編集するオフセットに相違が発生する条件として, サーバーとノードがお互いにコマンドを送り合った際, その命令コマンドが相手に到着する前に相手が自身のバッファに変更を加えてしまった場合に起きる. したがって, 相違の解消に必要なことは
63 \begin{enumerate} 63 \begin{itemize}
64 \item 参加したノードを順にroot(根)に近い要素として接続する. 64 \item サーバーとノード間のコマンド送信のすれ違いが発生したということを検知する方法
65 \item Topologyの要素に構成されたノードはそれぞれ親, 子のノードを特定の名前(parent, child[n])で参照できる. 65 \item すれ違いが発生した際に編集したオフセットのズレを修正する方法
66 \item 途中参加したノードは, 木の末端要素として接続する. 66 \end{itemize}
67 \end{enumerate} 67 が挙げられる.
68 以上の形でTopologyが形成される. \\
69 コード:\ref{code:SRTE} はTopologyManagerを使用してTopologyを構成するコードである. String型のリスト(今回はmanagerArg)に構成したいTopologyの形状をdotファイル, もしくは実装済みの動的Topologyの構成型を設定し, TopologyManagerCondfigを起動することでTopologyManagerが起動できる. ソースコードではTreeを構成しており, for文でnodeNum 個分のノードを生成し, それぞれmanagerPortを記憶させている. これによりノードすべてがTopologyManagerによりTreeの構成要素として接続される.
70
71 \lstinputlisting[caption=TopologyManagerによるTree型Topologyを構成するコード, label=code:SRTE]{./src/StartPrefixTree.java}
72
73 現状では通信アルゴリズムの構成のため, dotファイルにより接続を行なっているが, 最終的にはStar型の動的Topology機能を作成し, 途中で参加してきたノードを接続が行えるようにする必要がある.
74 68
75 69
76 70
77 %%文書終了**************************** 71 %%文書終了****************************
78 \end{document} 72 \end{document}