2013年3月23日土曜日

実行中 Common Lisp アプリのホットディプロイ


このエントリーをはてなブックマークに追加


Practical Common Lisp の一節にこんな文章があります。

2. Lather, Rinse, Repeat: A Tour of the REPL


An even more impressive instance of remote debugging occurred on NASA's 1998 Deep Space 1 mission. A half year after the space craft launched, a bit of Lisp code was going to control the spacecraft for two days while conducting a sequence of experiments. Unfortunately, a subtle race condition in the code had escaped detection during ground testing and was already in space. When the bug manifested in the wild--100 million miles away from Earth--the team was able to diagnose and fix the running code, allowing the experiments to complete.14 One of the programmers described it as follows:

Debugging a program running on a $100M piece of hardware that is 100 million miles away is an interesting experience. Having a read-eval-print loop running on the spacecraft proved invaluable in finding and fixing the problem.

You're not quite ready to send any Lisp code into deep space, but in the next chapter you'll take a crack at writing a program a bit more interesting than "hello, world."

1998年に打ち上げられたDeep Space 1が、打ち上げ後に問題が見つかり、遠隔でCommon Lispアプリケーションをホットディプロイしたという内容。

実際にCommon Lispでは稼働中のアプリケーションのコードを書き換えることができます。


簡単に試してみます。コマンドラインから処理系を起動します。

最初にswankをロードし、ローカルポート5555で起動しておきます。
? (ql:quickload :swank)
? (swank:create-server :port 5555 :style :spawn :dont-close t)

テスト用のコードを実行します。
? (defparameter *num* 1)
? (defun foo () (format t "~a~%" *num*))
? (loop 
    (foo)
    (sleep 1))
こんな感じでずっと1が表示されます。
1
1
1
1
1
1
1



別ターミナルから、処理系を起動します。

swankへ接続するのに、swank-clientを使います。
? (ql:quickload :swank-client)

まず *num* の値を書き換えてみます。
? (swank-client:with-slime-connection (conn "localhost" 5555)
    (swank-client:slime-eval '(setf *num* 2) conn))

書き換わりました。
1
1
;; swank:close-connection: Unexpected end of file on #<BASIC-TCP-STREAM UTF-8 (SOCKET/6) #x3020014B7D7D>
2
2
2
2


次に関数の定義を書き換えてみます。
? (swank-client:with-slime-connection (conn "localhost" 5555)
    (swank-client:slime-eval '(defun foo () (format t "~a~%" (+ *num* 10))) conn))

書き換わりました。
2
2
;; swank:close-connection: Unexpected end of file on #<BASIC-TCP-STREAM UTF-8 (SOCKET/7) #x3020014BDC8D>
12
12
12
12


SLIMEを使ってREPL開発をしているのと同じ感覚で、コードの書き換えをすぐに試すことができます。

以下の記事のホットディプロイの話を読んで、Practical Common Lisp を思い出したので、このエントリーを書いてみました。

Quickdocs.org で学ぶCommon LispのWebアプリ運用ノウハウ

0 件のコメント:

コメントを投稿