changeset 14:38f2c997bb93

update chap4
author akahori
date Tue, 19 Feb 2019 22:54:56 +0900
parents 117794d50054
children 2e706e8bb6bd
files final_main/chapter4/chapter4.tex final_main/main.pdf final_main/src/RemoteDataGearManager.java
diffstat 3 files changed, 72 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- a/final_main/chapter4/chapter4.tex	Tue Feb 19 21:49:55 2019 +0900
+++ b/final_main/chapter4/chapter4.tex	Tue Feb 19 22:54:56 2019 +0900
@@ -65,7 +65,7 @@
 \item ノード間で繋がる前にput操作を行うとデータが送られない.
 \end{itemize}
 
-Take, Peek操作でSuperClassの型を持ったデータを取り出す際にNullPointerExceptionが表示される問題に対しては, DataGearでdataを代入する際にSuperClass, interfacesまで比較するように書き換えた. また, 型の不一致が起こった際は例外を投げるようにした. その修正後のコードをソースコード\ref{code:datagear}に示す.
+Take, Peek操作でSuperClassの型を持ったデータを取り出す際にNullPointerExceptionが表示される問題に対しては, DataGearでdataを代入する際にSuperClass, interfacesまで比較するように書き換えた. また, 型の不一致が起こった際は例外を投げるようにした. その修正後のコードをソースコード\ref{code:datagear}に示す. 
 
 \begin{lstlisting}[caption=修正後のDataGearのソースコード,label=code:datagear]
 public class DataGear<T>{
@@ -101,101 +101,14 @@
 }
 \end{lstlisting}
 
-TopologyNodeにおいて, 実行するCodeGearをputしておき, 参加するノードがすべて揃ったら, そのCodeGearを実行する. しかし, 実際には実行するCodeGearはCodeGearを継承したものである. Christieは, putされたdataのクラスとTakeされるデータのクラスが一致したならば, dataを代入するという処理を行っている. つまり, SuperClass, interfacesの型までは比較をしない. そのため, 型の不一致が起こり, dataの代入をしないため, NullPointerExceptionが表示されていた. 
-
-
+setDataメソッドの中身を変更した. TopologyNodeにおいて, 実行するCodeGearをputしておき, 参加するノードがすべて揃ったら, そのCodeGearを実行する. しかし, 実際には実行するCodeGearはCodeGearを継承したものである. Christieは, putされたdataのクラスとTakeされるデータのクラスが一致したならばdataを代入し, それ以外なら無視するという処理を行っていた. SuperClass, interfacesの型までは比較をしていなかっため, 型の不一致が起こり, dataの代入をしないため, NullPointerExceptionが表示されていた. 
 
 
-ノード間で繋がる前にput操作を行うとデータが送られない問題に対しては, waitを付け加えた. そのコードをソースコード\ref{code:rdg}に示す. この問題は, ノードが繋がる前にputを行うため, 相手のDataGearに書き込みが行われないために起きた. そのため, 相手とDataGearがつながるまでputメソッドをwaitしておき, つながってからput操作を行うように書き換えた.
-
-\begin{lstlisting}[caption=修正後のDataGearのソースコード,label=code:datagear]
-public class RemoteDataGearManager extends DataGearManager{
-    boolean connect = false;
-    Object lock = new Object();
-
-    public RemoteDataGearManager(final String dgmName, final String address, final int port, CodeGearManager cgm) {
-        this.cgm = cgm;
-        RemoteDataGearManager manager = this;
-        new Thread("Connect-" + dgmName) {
-            public void run() {
-                do {
-                    try {
-                        SocketChannel sc = SocketChannel.open(new InetSocketAddress(address, port));
-                        connection = new Connection(sc.socket(), cgm);
-                        connection.name = dgmName;
-                        connection.socket.setTcpNoDelay(true);
-                        
-                        // add lock
-                        synchronized (lock){
-                            connect = true;
-                            lock.notify();
-                        }
-                    } catch (IOException e) {
-                        try {
-                            Thread.sleep(50);
-                        } catch (InterruptedException e1) {
-                            e1.printStackTrace();
-                        }
-                    }
-                } while (!connect);
-                IncomingTcpConnection in = new IncomingTcpConnection(connection);
-                in.setManager(manager);
-                in.setName(dgmName+"-IncomingTcp");
-                in.setPriority(MAX_PRIORITY);
-                in.start();
-                OutboundTcpConnection out = new OutboundTcpConnection(connection);
-                out.setName(dgmName + "-OutboundTcp");
-                out.setPriority(MAX_PRIORITY);
-                out.start();
-            }
-        }.start();
+ノード間で繋がる前にput操作を行うとデータが送られない問題に対しては, waitを付け加えた. そのコードをソースコード\ref{code:rdgm}に示す. 
 
-    }
-    
-    ...
-
-    @Override
-    public void put(String key, Object data) {
-
-        Command cm = new PutCommand(0, null, key, new DataGear(data));
-        
-        if(!connect) connectWait(); // add wait
+\lstinputlisting[caption=修正後のRemoteDataGearManagerのソースコード,label=code:rdgm]{./src/RemoteDataGearManager.java}
 
-        connection.write(cm);
-    }
-    
-    // add method
-    public void connectWait(){
-        synchronized (lock){
-            while(!connect){
-                try {
-                    lock.wait();
-                } catch (InterruptedException e) {
-                }
-            }
-        }
-    }
-}
-\end{lstlisting}
-
-\section{Aliceと比較したChristieの良い点, 悪い点}
-Christieの元となった分散フレームワークAliceと比較し, Christieの良い点, 悪い点をそれぞれ述べる.
-
-良い点としては次のようなことが挙げられる.
-
-\begin{itemize}
-\item ソースコードの可読性が上がった. Aliceでは動的にDataGearのKeyを変更できるため, 実際に使われているクラスと別のところでKeyが変更されている場合も多かった. しかし, Christieでは変数の名前がKeyとなる. そのため, put操作した変数がどこで使われているかがわかりやすくなった.
-\item データの取り出しが簡単. アノテーションを用いることで, データを簡単に取り出すことができる. また, Aliceでは型をコード内で再定義しなければならなかったが, その操作がなくなった.
-
-\item DGMの操作がわかりやすくなった. 
-\end{itemize}
-
-
-悪い点としては次のようなことが挙げられる
-\begin{itemize}
-\item TakeFrom, PeekFromの使い方が難しい. TakeFrom, PeekFromは引数でDGM nameを指定する. しかし, DGMの名前を静的に与えるよりも, 動的に与えたい場合が多かった.
-\item デバッグが難しい. cgm.setupでCodeGearが実行されるが, keyの待ち合わせで止まり, どこで止まっているかわからないことが多かった. 例えば, putするkeyのスペルミスなどでコードの待ち合わせが起こり, CodeGearが実行されず, エラーなども表示されずにwaitすることがあり, どこで止まっているかわからない事があった.
-\end{itemize}
+具体的にはソースコード\ref{code:rdgm}の17行目から21行目にlockを付け加え, putメソッドの48行目にwaitするメソッドを置き, 54行目から63行目にwaitするメソッドを付け加えた. この問題は, ノードが繋がる前にconnection.writeを行うため, 相手のDataGearに書き込みが行われないために起きた. そのため, 相手とDataGearがつながるまでputメソッドをwaitしておき, つながってからconnection.write操作を行うように書き換えた.
 
 \section{Christieにおけるブロックチェーンの実装の利点と欠点}
 
@@ -203,7 +116,7 @@
 その際, Christieで実装した場合の便利な点を述べる.
 
 \begin{itemize}
-\item ブロック, トランザクションを送るのが簡単. ChristieはDataGearという単位でデータを保持する. そのため, ブロックやトランザクションはDataGearに包めばいい.
+\item データの取り出しが簡単. ChristieはDataGearという単位でデータを保持する. そのため, ブロックやトランザクションはDataGearに包めばいいため, どう送るかという問題を考えなくてすむ. 
 \item TopologyManagerでのテストが便利. dotファイルが有れば, TopologyManagerが任意の形でTopologyを作れる. そのため, ノードの配置については理想の環境を作れるため, 理想のテスト環境を作ることができる. 
 \item 機能ごとにファイルが実装できるため, 見通しが良い. ChristieはCbCのgotoと同じように関数が終わるとsetupによって別の関数に移動する. そのため自然に機能ごとにファイルを作るため, 見通しが良くなる.
 \end{itemize}
@@ -211,7 +124,8 @@
 不便な点を以下に述べる.
 
 \begin{itemize}
-\item デバッグが難しい. 4.4の「Christieの良い点, 悪い点」で述べたが, keyのスペルミスなどが起こると, CodeGearが実行されず, waitされる問題が出る.
+\item デバッグが難しい. cgm.setupでCodeGearが実行されるが, keyの待ち合わせで止まり, どこのCGで止まっているかわからないことが多かった. 例えば, putするkeyのスペルミスでコードの待ち合わせが起こり, CGが実行されず, エラーなども表示されずにwaitすることがある. その時に, どこで止まっているか特定するのが難しい.
+\item TakeFrom, PeekFromの使い方が難しい. TakeFrom, PeekFromは引数でDGM nameを指定する. しかし, DGMの名前を静的に与えるよりも, 動的に与えたい場合が多かった.
 \item Takeの待ち合わせでCGが実行されない. 2つのCGで同じ変数をTakeしようとすると, setupされた時点で変数がロックされる. このとき, 片方のCGはDGがすべて揃っているのに, すべての変数が揃っていないもう片方のCGに同名の変数がロックされ, 実行されない場合がある. 
 \end{itemize}
 
Binary file final_main/main.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/final_main/src/RemoteDataGearManager.java	Tue Feb 19 22:54:56 2019 +0900
@@ -0,0 +1,64 @@
+public class RemoteDataGearManager extends DataGearManager{
+    boolean connect = false;
+    Object lock = new Object();
+
+    public RemoteDataGearManager(final String dgmName, final String address, final int port, CodeGearManager cgm) {
+        this.cgm = cgm;
+        RemoteDataGearManager manager = this;
+        new Thread("Connect-" + dgmName) {
+            public void run() {
+                do {
+                    try {
+                        SocketChannel sc = SocketChannel.open(new InetSocketAddress(address, port));
+                        connection = new Connection(sc.socket(), cgm);
+                        connection.name = dgmName;
+                        connection.socket.setTcpNoDelay(true);
+                        
+                        // add lock
+                        synchronized (lock){
+                            connect = true;
+                            lock.notify();
+                        }
+                    } catch (IOException e) {
+                        try {
+                            Thread.sleep(50);
+                        } catch (InterruptedException e1) {
+                            e1.printStackTrace();
+                        }
+                    }
+                } while (!connect);
+                IncomingTcpConnection in = new IncomingTcpConnection(connection);
+                in.setManager(manager);
+                in.setName(dgmName+"-IncomingTcp");
+                in.setPriority(MAX_PRIORITY);
+                in.start();
+                OutboundTcpConnection out = new OutboundTcpConnection(connection);
+                out.setName(dgmName + "-OutboundTcp");
+                out.setPriority(MAX_PRIORITY);
+                out.start();
+            }
+        }.start();
+
+    }
+    
+     public void put(String key, Object data) {
+
+        Command cm = new PutCommand(0, null, key, new DataGear(data));
+        
+        if(!connect) connectWait(); // add wait
+
+        connection.write(cm);
+   }
+    
+    // add method
+    public void connectWait(){
+        synchronized (lock){
+            while(!connect){
+                try {
+                    lock.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+}
\ No newline at end of file