このページは福井県立大学の田中求之が2006年1月まで運用していた Mac のサーバ運用に関する会議室 「Web Scripter's Meeting」の記録です。情報が古くなっている可能性がありますのでご注意ください。

WebCenterにおけるACGIとCGI

発言者:中島としひで
( Date Monday, September 09, 1996 21:56:15 )


現在、WebCenterをサーバーとして運用しています。ホームページ上に複数の
入力画面があるので、それごとにCGIを作るのは大変だったので、1つのCGIで
複数の入力画面を処理するようにしました。「Macintoshインターネットサー
バー構築術に書いてあるように、CGIをアクション定義して、script_nameを
もとに、「入力画面」と「処理内容」を判断して処理をしています。

ところが、複数のホストから同時にアクセスがあると、WebCenterとCGIアプ
リケーションが並行処理をしていまい、Aという入力画面で入力した内容がBに
登録されてしまう現象が発生しました。
これはきっと、CGIアプリケーションが処理の最中に、WebCenterから別の
script_nameでイベントが発生したために、「入力画面」と「処理内容」がご
ちゃまぜになった為だと思います。

CGIアプリケーションの拡張子を.acgiとしてたので、並列処理をしてしまった
のだなと思い、拡張子を.cgiに変更してみたんですが、結果は同じでした(;o;)

私のバイブルである「Macintoshインターネットサーバー構築術」では、
  「CGIアプリケーションの場合、MacHTTPでははsdocイベントで処理を指
  示した後、処理が終了してアプリケーションからreplyが返されるまでいっ
  さいの処理を中断して待機します」
と書いてあります。

もしかすると、WebCenterではMacHTTPとは違い、拡張詞が.cgiでもWebCenter
とアプリケーションは並列処理をしてしまうのでしょうか?

う〜ん、やっぱり、WebStarにしようかなぁ。

田中求之 さんからのコメント
( Monday, September 09, 1996 23:02:05 )

>ところが、複数のホストから同時にアクセスがあると、WebCenterとCGIアプ
>リケーションが並行処理をしていまい、Aという入力画面で入力した内容がBに
>登録されてしまう現象が発生しました。

( CGI は AppleScript でお作りになったのですよね? そうだとして話を
  進めます。)

これは変ですね? WebCenter にせよ、WebSTAR にせよ、ACGI の場合は、
確かに、CGI を必要とするアクセスが来ると、たとえその CGI が実行中で
あっても、CGI を呼び出す(メッセージを送る)ようになっています。
ですから、この点に関しては WebSTAR も同じです。

で、CGI を AppleScript で作った場合、絶対に並列処理は行われません。
これは、AppleScript の仕様です。つまり、

>これはきっと、CGIアプリケーションが処理の最中に、WebCenterから別の
>script_nameでイベントが発生したために、「入力画面」と「処理内容」がご
>ちゃまぜになった為だと思います。

というような現象は、AppleScript の CGI では、起こしたくても起こせない
ものなんですよ。Frontier のような、マルチスレッド対応のスクリプティング
環境であれば並列処理(=マルチスレッド処理)が起こるのですがね。

処理中に届いた新たな処理の命令は、現在実行中の処理が終わるまでは、システムの
イベント・キューの中にためられるようになっています。つまり、店の入り口で順番待ち
をさせられるようになっているわけですよ。

ということで、原因は WebCenter ではなく、スクリプトの方にあるのではないか
と思われます。グローバル変数やプロパティの使用において、何らかのエラーが生じて
いるのではないと思うのですが、いかがでしょうか?

気になるのでしたら、WebSTAR のテスト版を落として試してごらんになると
よいと思いますが。

中島としひで さんからのコメント
( Tuesday, September 10, 1996 00:38:31 )

さっそくのコメントありがとうございます。

>( CGI は AppleScript でお作りになったのですよね? そうだとして話を
>  進めます。)
舌足らずでした。おっしゃるとおりAppleScriptです。

>というような現象は、AppleScript の CGI では、起こしたくても起こせない
>ものなんですよ。Frontier のような、マルチスレッド対応のスクリプティング
>環境であれば並列処理(=マルチスレッド処理)が起こるのですがね。
>
>処理中に届いた新たな処理の命令は、現在実行中の処理が終わるまでは、システムの
>イベント・キューの中にためられるようになっています。つまり、店の入り口で順番待ちをさせられるようになっているわけですよ。
具体的に言うと、
on ヌevent WWWスsdocネ path_args ツ
  given ヌclass kforネ:http_search_args, ヌclass postネ:post_args, ヌclass scnmネ:script_name
    から
end ヌevent WWWスsdocネ
のスクリプトは、同時には処理をしないという事なのでしょうか?

念のため、"Display Dialog"をon ヌevent WWWスsdocネ path_args ツの直後と、サーバーへのreturn
の直前に仕込んでみました(原始的ですが...)。並列処理をしないのであれば
on ヌevent WWWスsdocネ path_args ツの直後のDisplay Dialogを表示したあとに、必ずサーバーへreturn
の直前のDisplay Dialogが表示されるはずですよね。
つまり、on ヌevent WWWスsdocネ path_args ツの直後のDisplay Dialogは連続して表示されないはず
です(ややこしくてすみません)。

ところが、2つのブラウザで同時にアクセスをすると、なんと、on ヌevent WWWスsdocネ path_args ツ
の直後のDisplay Dialogが表示されてしまいます。

ということは、on ヌevent WWWスsdocネ path_args ツ以降の処理を、同時(並列?)に処理をしている
のではないか?と推察されます。


>ということで、原因は WebCenter ではなく、スクリプトの方にあるのではないか
>と思われます。グローバル変数やプロパティの使用において、何らかのエラーが生じて
>いるのではないと思うのですが、いかがでしょうか?
さきほども書きましたが「入力画面」と「処理内容」を判定するロジックは
on ヌevent WWWスsdocネ path_args ツ以降にあります。また、「入力画面」と「処理内容」をプログラム
で判定するために、この内容を変数に保管をしていますがこれらはグローバル変数ではなく、ローカル変数
として定義しています。

たぶんどこか、プログラムにミスがあるのかとは思いますがどうしても原因がわかりません。
お忙しいとは思いますが、お助けください。


田中求之 さんからのコメント
( Tuesday, September 10, 1996 02:47:13 )

>ところが、2つのブラウザで同時にアクセスをすると、なんと、on ヌevent WWWスsdocネ path_args ツ
>の直後のDisplay Dialogが表示されてしまいます。

げ、確かにこれは変ですねぇ。

私のサーバー( WebSTAR です)は、ACGI がマルチスレッドで動かないことの影響が
そろそろ出始めている(この会議室以外にも山ほど仕掛けをして、それをたった一つの
CGI で処理してますから)ことから考えても、AppleScript のアプレットが Multi-
thread で動かないというのは確かなんですが…

AppleEvent で sdoc イベントが送られた後は、WebCenter だろうが WebSTAR
だろうが関係ないはずなので、WebCenter の問題とは考えにくいのですが、とりあえず
私の方でも調べてみます。

よかったら、問題のスクリプトを私までメール添付で送ってもらえますか?

mact@antares.ecn.fpu.ac.jp

宛です。(メールを出すのに Netscape は使わないでくださいね)

中島としひで さんからのコメント
( Tuesday, September 10, 1996 15:45:10 )

さっそく、メールしました。よろしくお願いします。詳しくはメールを
ご覧ください。

田中求之 さんからのコメント
( Tuesday, September 10, 1996 18:53:46 )

スクリプトを受け取りました。なかなか凝ったものになっていますね。
何か分かったらお知らせします。

お送りいただいたスクリプトとは直接関係ないのですが、AppleScript
のアプレットの動作について、簡単な実験をしていて面白いことに気が
つきました。

それについては、新しいページとして投稿しておきます。

中島としひで さんからのコメント
( Wednesday, September 11, 1996 22:15:52 )

昨日ついにWebStarを買ってきました!
たぶん、WebStarを買っても今回の件は直らないんだろうなぁ、と
は思ったんですが可能性のあるものはすべて試そう!なんて決意を
して、秋葉原へ行ってきました。

さっそく、インストールをして例の同時アクセスのテストをしまし
た。結果は...、
やはり、あの現象が発生しました。う〜ん、やっぱり。アップルイ
ベントはシステムが管理しているものであって(ですよね?)、
WWWサーバーソフトが管理しているものではないんですよね。

とりあえず今は緊急措置として、CGIを競合しそうな処理の数分コピー
をして、それぞれを別々に動かしています。とはいえ、このまま処理が
増える度に、CGIを独立させてたのではメモリがいくらあっても足りなく
なるだろうし。はぁ、困りました。

少ない脳みそでもうちょっと悩んでみます。はい。

田中求之 さんからのコメント
( Thursday, September 12, 1996 01:29:04 )

送っていただいたスクリプトをじっくり見る時間がとれないでいるのですが、
WebSTAR でも同じ症状が出たということは、たぶん、スクリプト側で
問題が起きている可能性が高いですね。

それから、一つ確認ですが、

>とりあえず今は緊急措置として、CGIを競合しそうな処理の数分コピー
>をして、それぞれを別々に動かしています。

この策をとることで、問題の解決になりましたか? とすれば、もともとの
原因は、スクリプト内での処理の分岐がうまくいっていなかったという可能性も
高くなるのですが。

なお、一つの CGI の中で多くの処理をこなすようにするときの CGI の作り方
として、

1:処理毎にハンドラーに分けて、分岐部分をコンパクトにまとめる。

   if myCmd = "view" then
      return view()
   else if myCmd = "post" then
      return post()
   else if ...

   end if

というように、分岐の条件と、それがどの処理を呼び出すかを、なるべき狭い
範囲で確認できるようにします。また、if then else if ...  のネスト
にすることで、かならず一つの処理しか呼ばれないようにします。
( EasyBBS DX と STAR の正式版がこのスタイルでスクリプトを書いています。
ただし、分岐部分が若干変則的になっていますが)。


2:さらに処理が多くなった場合は、ハンドラーをスクリプト・オブジェクトに
わけて、それを呼び出すようにする。

機能毎にハンドラーを分けて、スクリプト・オブジェクトにわけておき、それを
load script で読み込んで処理を行わせます(あらかじめ property として
読み込んでおくのがよい)。

現在の私のこのサーバーの CGI が、この方法になっています。コーナー毎に
ハンドラーをまとめてスクリプト・オブジェクトに入れておき、それを呼び出す
スタイルになっています。

こうしておけば、スクリプトサイズの制限にも引っかかりませんし、部分の変更
も比較的楽になります(ただし、面倒になる部分もある)。

ちなみに、このサーバーの CGI は、9つのスクリプト・オブジェクトを読み込ん
で処理をやってます。


このように、処理が複雑になっても、それをマネージメントする方法はいくつか
ありますので、いろいろと試してみてください。



中島としひで さんからのコメント
( Thursday, September 12, 1996 10:41:21 )

なるほど、確かに私のスクリプトはなるべくネストをしないように作ってあります。
仕事柄、ネストをしているプログラムを作るのがいやだったので。やはりApple
Scriptの流儀っていうのがありますからね。
とりあえず、時間はかかると思いますが、ハンドラー化にチャレンジして見ようか
と思います。

>機能毎にハンドラーを分けて、スクリプト・オブジェクトにわけておき、それを
>load script で読み込んで処理を行わせます(あらかじめ property として
>読み込んでおくのがよい)。
>
>現在の私のこのサーバーの CGI が、この方法になっています。コーナー毎に
>ハンドラーをまとめてスクリプト・オブジェクトに入れておき、それを呼び出す
>スタイルになっています。

>こうしておけば、スクリプトサイズの制限にも引っかかりませんし、部分の変更
>も比較的楽になります(ただし、面倒になる部分もある)。

Apple Scriptのスクリプト・オブジェクトについてはなんとか理解できると思いま
す。恥ずかしながらload scriptというのは、初めて聞きました。とりあえず、今日
は、AppleScriptのもっと詳しい参考書をもともてふたたび秋葉原に行ってきます。
いま持っているApple Scriptの本はあくまで入門本ですので。
もう少し勉強してきます!