題名:Java Diary-38章

五郎の入り口に戻る

日付:2003/4/28

目次に戻る


GMail-Part10(Ver0.5)

私は通勤電車の中でいつもパソコンを使っている。GMailは大抵立ち上げっぱなし。すると彼は律儀にも指定された時間間隔でメールをダウンロードしようとする。ネットにはつながっていないからもちろんその試みは失敗に終わる。

これ自体は別に問題ではない。ところがその後家に帰ってさあメールチェック、とやると受信がうまく動かないのである。これは元々あった現象ではないので、何かの理由で生じた問題なのだろう。しかしとにかく動かない。というわけで家に帰るとGMailを立ち上げ直すのが習慣になった。起動が遅いことに関してはもっとも問題点に同情的な私ですらいらつく。これはなんとかならぬものか。

それだけならいいのだが、そうした時にコンソールを見ているとtoo many open filesというエラーがわらわらでている。これはなんだろう。とにかく気分が悪い。そのうちぱたっとプログラムが終了したりする。(もちろん私は何の操作もしていない)最初は観て観ぬ振りをしていたがだんだん見過ごせないくらい問題が頻発するようになる。となればなんらかの対処をせねばならぬ。

プログラムの中では受信用のソフトを起動した後、それが終了したかを定期的にタイマーをかけ確認していた。どうもエラーはそこらへんで発生しているようだ。ここらへんをごろっと変える方法はないか。実は受信プログラムを作っている新居氏から別の起動方法を示唆されていたのである。試してみると見事に動くし、これならタイマーをかけて終了確認など必要ない。わーいわーい。これであのエラーともおさらばだ、と思ったのはほんの短い間だった。不思議なことに一度は受信がうまくできるが2度目からできなくなるのである。

はて、これはどうしたことか、、と思いメーリングリストにその内容を投稿してみる。あれこれ論議があった末にその問題に対処したプログラムがリリースされる。やってみると見事に起動ができるが、too many open filesというエラーメッセージはてんこ盛り。これに関しても次のバージョンであらかたフィックスされる。

わーいわーいと思い一人悦に入る。ところがそれも長く続かない。「突然終了する」という問題は依然残っているのだ。ああ、これが「唯一の原因」ではなかったのね。さて、どこがおかしいのやら、とプログラムを観ると、数度の改訂を経て中身がごちゃごちゃになっている。作った本人ですら

「はて、私は何をしようとしたのか」

と頭を傾げる有様だ。ええい、と思い少し紙の上に落書きなどして考えたあげくプログラムを書き直す。そのうちGMailのユーザーからのメールが届く。

そこには「ようやくGMailが起動しました」という言葉とともに、なぜ起動しなかったかの分析、それにいくつかの提言が書かれていた。やれ、うれしや。どこが悪かったまで分析して知らせていただけるとは。さっそくプログラムの該当箇所を直す。それとともにSuggestionいただいた内容を反映しようとあれこれやりだす。

まず最初にやったのが「フォントの種類を選べるようにする」という改善だった。今までフォントのサイズは選択できたのだが、種類までは頭がまわっていなかったのである。しかしここは一つがんばってみるか。そう思いコードをあれこれいじるとまもなく種類の変更が可能になる。確かにフォントの種類をあれこれ変えてみると気分転換にもなるし、好みのフォントを持っている人にとってはこの昨日は必須だろう。しかし私は他のことに気を取られ出していた。

それまでにあったフォント関係の処理がプログラムのあちこちにでたらめに分散しているのである。同じような処理を何度も書いているところもあったし、ようするにぐちゃぐちゃである。とにかく動けばよい、と思って書いていたのだろうが、こうして新しい機能を付け加えようとすると破綻が明らかになる。そこそこ動かすことはできるのだが、ちゃんと動かそうとするとどこを直せばいいのやらさっぱりわからない状況だ。

ええい、かくなる上は、と思いFont関係の処理を一つのクラスにまとめようとする。プログラムのあっちをこっちにもってきて、あら、これは共通だったかではまとめよう、などとやり始める。すると自分が想像していた以上にフォント関係の処理がでたらめにちらばっていたことに気がつく。今までなんとなく動いていたのが奇跡のようだが、とにかく掘っても掘ってもまた関係のあるコードがでてくる。

さて、それがなんとか片づいた、と思ったら今度は起動時に妙なエラーがでて起動に失敗しまくる、という問題につきあたった。やっかいだったのはそのエラーが一種類ではないことだ。

実はこの傾向は以前から存在していた。でも「まあいいや。時々起動に失敗するだけだから」などと目をつむっていたのだが、何の影響かわからないが、その失敗する確率が高くなってきた。それは私が目をつむるのも困難なほど。こうなるとよそを向いているわけにもいかない。しかしその対処が困難なことにも代わりはない。

あれやこれや、とやっているうちに、いくつか原因を推定し出す。あっているかどうかわからないのだが、それに対処をすると起動がすんなりいくようになる。やれ、うれしや、苦労したけどこうやって素直に動いてくれると気持ちがいいなあ、などと思った矢先に再び起動に失敗する。望むことができるのは発生確率が下げることであり、なかなか絶無にはならない。

そしてコードをさわっているといつもの悪い癖で

「ええい。ここをなおしてしまえ」

というのがいくつかでてくる。前述したフォントの大きさおよび文字の種類を変更することもその一つだが、他にもやりたいことはいくつもあった。機能拡張は結構なことだが、それをやると元からあった問題の対処はさらにややこしくなる。実際アプリケーションが異常終了するときには何を言わずに終了するから、本当の原因がわからない。であるから「改良」が新たなバグをうんでいるのかもしれないが、それが事実かどうかすら私にはわからない。

では何を「改良」していたかと言えば、受信の進捗状況の表示である。今までは「送受信」というボタンを押すと、そのボタンが「受信中」とかになり、受信終了とともにボタン表示が元に戻る。こういった形でしか受信終了を知ることができなかったのだが、たくさんメールを受け取っている時にはこれが結構長くかかる。

「ああ、たくさん受信しているのね」

とのんびり構えていられるほど私が自分が書いたソフトウェアを信頼していない。(そしてその心配が時々あたっているのも情けない)

この進捗表示をどうしてやろう、、とは前から考えていたしそのために必要な機能もあれこれ作ってはいたのである。でも完成さようと思うと面倒だし、、と思っていたのだが、この際に作ってしまいたいと考え出す。いや、エラー処理の方が先だと思ってもとにかく作り出してしまうから話がややこしくなる。

コードを書くこと自体は結構簡単にできた。時間がかかったのは「どこにどうやって表示するか」を考えることの方だった。最初は他のメーラー(Namera)にならってツールバーにそれらしい表示をつけてやろうかと考えていた。なんたって画面の上の方にあるから見やすいし、いらないと思ったら消してもらうのも簡単。

しかし前述のSuggestionをくれた人はこう書いていた「私はツールバーのボタンを消して使っています」なるほどそういう使い方もあるのか。となるとツールバーに表示する、という案はあまりうれしくない。画面を最大限に広げて使いたい人もいるだろうし。

ではどうするか。あれこれ考えたあげく、落ち着いたのは画面の下に表示エリアをもうける案である。ただ出しっぱなしにしておくと貴重な画面面積を専有してしまうことになるから、受信をしている間だけ表示するようにした。でたり消えたりとはいっても画面の下の方だからさほど気にはならないだろう。

では、と意を決して機能追加にとりかかる。と、思ったより簡単に実装はできてしまった。手直しはもちろんぽこぽこあるのだが、結構ご機嫌にうごく。これまではコンソールなるアプリケーション上で流れるメッセージでしか受信状況の確認はできなかったのだが、画面でみることができるというのは結構快適。とそちらが一段落つくと今度は「不意に終了」の対策である。というか、このトラブルはだんだん頻繁に発生するようになり、デバッグ作業にも支障を来すほどになってきていたのだ。

とはいっても「時々」しかも「ちゃんとしたエラーメッセージを出さず」発生するトラブルだからまず現象を捕まえるのが大変だ。、、などと思っていたが一つ目のトラブルは、エラーメッセージを観ている間になんとなく特定できた。もっともなぜそれが問題になるかは理解できないのだが、とりあえず対処をした。これで起動時に異常終了するトラブルの発生頻度は激減した。(なくなったわけではない)

二つ目の原因とおぼしきものはかなり当てずっぽうである。やたらとプリント文を埋め込み、終了が起きたと思われる箇所を特定する。そこはフォルダ一覧の表示を更新する箇所だった。なぜこんなところで問題が起こる。何の根拠もないのだが、

「きっとこれは短時間に表示更新要求が山のように出され、処理がおいつかないためだ」

と思いこむ。そしてそれに対処する処理を追加すると確かに異常終了の頻度は減ったように感じる。

わーい、問題解決だあ。これでリリースだ、などと考え始めるときっちりとバグが見つかってくれる。最初に気がついたのは

「送受信ボタンをいくら押しても処理が行われない」

という問題だった。何、いままで送受信をすると異常終了してたんだからこれくらいの問題は目をつむろう。そんなに頻度が高いわけでもないし、などと思っているとまた目の前でそのトラブルが起こってくれる。これはなんとかしなければ、と思いまたプリント文を山のように埋め込み状況を確認する。

すると「起こるはずのない状況」が起こっていることに気がつく。何だこれは?さわった覚えがないのに変数の中身が変わっている。CとかC++で変なところに変なデータを書き込むとこのような問題が生じるがJavaではそうしたことは起こりえぬはずなのに、、と思いしばしコードを眺める。そのうち原因に思い当たった。最近導入した並列処理のせいだ。

並列処理というからには複数処理が同時に動いている状態である。従ってプログラムの上で連続した2行があったとしても、それらの処理が連続して実行される、という保証はない。

"私は猫です"と印字する

"私は犬です"と印字する

.....

...

..

(ものすごく離れたところにある別の関数)

"にゃんにゃんにゃん"と印字する。

というプログラムを実行させた場合、ふつうなら

「私は猫です」

「私は犬です」

と印字されるが、並列処理を導入するとそうなるとは限らない。2行の間に「にゃんにゃんにゃん」が印字されるかもしれないし、されないかもしれない。「にゃんにゃんにゃん」くらいなら問題はないが、同じ変数をいじっていたりすると動作は全く思いもよらぬものになる。送受信処理が動かない原因はまさしくそのようなことが起こっているためであった。

なるほど、、と思うが対処はちょっとややこしい。おまけにいったんこうした問題に気がつくと他の部分が怪しく見えてくる。ここでこの処理が動くとすると、、と考えると他に直す部分がわかってしまう。対処はしたがそれがちゃんと動くかどうかはちゃんと検証しなくては。というわけでリリースはまた延びていく。

なんとか動くかな、と思うと会社にある別のMacにインストールして動作チェック。するとまたもや並列処理が原因と思われる別の問題が発生する。ええい、と思い対処。あれこれ試験をしているうちにこの「フォントを変更できる」ってえのは結構おもしろい機能だなあと思い出す。

などとあれこれやったあげくVer0.5は4月の終わりにリリースすとなった。しかし当初予定していた機能強化は今回も見送りになっちゃったなあ。。

前の章 | 次の章


注釈