月別アーカイブ: 2012年2月

Mac初心者としてMac初心者が知っておいた方が良いと思ったこと

MacBookAirを買ってちょうど1年くらいになります。既に型落ちモデルになっていますし、OSも次の次のバージョンが発表されていますが、バリバリSnow leopardを使っています。僕はこのマシンを買うまで今までMacというものに触ったことがありませんでした。そんな僕が1年間を振り返ってハマったことを書いてみたいと思います。

Finderでフォルダの「置き換え」に注意!

コマンドライン強者の方はFinderなんか使わないのかもしれませんが( ̄^ ̄)、ゆるふわな人はFinderを使います。

が、フォルダを整理していて以下のメッセージが出たら要注意!><

これで「置き換える」を選んでしまうと、移動先にもともとあったフォルダのデータはフォーエバーどこかへ行ってしまいます。( ;∀;)

誰もがやってしまうお決まりミスですね!僕もこれで大事なハードディスクのデータが吹っ飛びました。

遅くなってきたな!と思ったらデフラグではなく、ディスクアクセス権の修復!

Eclipseを使っていたらある日突然、右クリックの反応がものすごく遅くなってしまいました。
Java系のアプリに限定でそうなので、JVM関連の何かがおかしいのだと思いましたが、原因がわかりません。低電圧版のCore2Duoはやっぱり遅いので買い替えかともふと思いました。

しかし、ストレージ容量も少ないので、断片化が進んでいるかもしれないととっさに思ったWindows頭の僕は、「Mac デフラグ」で検索すると、すぐに「Macでデフラグは効果がない」という情報が出てきました。

「マックのデフラグ方法 | OKWave http://okwave.jp/qa/q6705828.html

ということで、僕もディスクユーティリティ・アクセス権の修復を試してみました。

予想通りJVM系のファイルが引っかかります。なんか、修復を何度行っても、エラーが消えないのですが(*´Д`) ひとまずこれで再起動してみます。

ヮ(゚д゚)ォ!

右クリックメニューの表示の遅さが解消しました><

その他

Eclipseを使うならショートカットのControl+SpaceがSpotlightとかぶるのでゴニョゴニョとか、64GB版を買ってしまってSSDが少ないので極限まで節約しようとしたらシステムを壊してしまった話とか、あまり役に立たなそうな上、書く気も起きないので、とりあえず上記二点だけ。

そんなの知ってたよって言われそうですが、前者は大事なデータを失った痛い経験ですし、後者は愛機への愛情を早くも1年で捨てるところでした。ということで、同じ思いをしないために、知らない人は知っておいたほうが良いんじゃないかな。


PostgreSQL で LANケーブルが抜けた場合にConnectionを破棄する方法

TomcatでWebアプリを開発していてDBとの接続はコネクションプーリングを行なっています。コネクションプーリングをしているとはいえ、何らかの原因でConnectionが使い物にならない場合は、再接続をするために、Connection取得時に以下のようなSQLを投げて死活チェックを行なっています。

select 1

ところが、例えばDBサーバへのLANケーブルが抜けた場合、このSQLをいつまでも実行してしまい、結果的にConnectionPoolからの取得待ち行列がたまり、Tomcatのスレッドを消費してDBが不要なサービスにまで影響を及ぼしてしまうという問題があります。

その問題が発生しないように、クエリにタイムアウトを施したいと思い、まずは以下のようにしてみました。

Statement stmt = connection.createStatement();
stmt.setQueryTimeout(1);

ところがこの方法は上手くいきません。

Method setQueryTimeout(int) is not yet implemented.

などのように言われてしまいます。実装されていないのか?(なぜ?)それでは、タイマーを用意して横からcancelをさせることを考えました。

final Statement stmt = connection.createStatement();
Runnable canceler = new Runnable() {
    public void run() {
        try {
            stmt.cancel();
        } catch (SQLException e) {
            // I can do nothing :)
        }
    }
};
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.schedule(canceler, 500, TimeUnit.MILLISECONDS);

この方法は上手くいきませんでした。なにせLANケーブルが抜けているのでcancelすら到達しないようです。

それでは、逆の発想で、別スレッドでテストをさせて、メインのスレッドはjoinをして、制限時間を過ぎればスルーして終了する実装にしてみましょう。

final Statement stmt = connection.createStatement();
class Checker implements Runnable {
    boolean succeeded = false;
    public void run() {
        try {
            try {
                stmt.execute("SELECT 1");
                succeeded = true;
            } finally {
                stmt.close();
            }
        } catch (SQLException e) {
            // I can do nothing :)
        }
    }
}
Checker checker = new Checker();
Thread thread = new Thread(checker);
thread.start();
try {
    thread.join(1000);
} catch (InterruptedException e) {
   // i can do nothing :)
}
return !checker.succeeded;

この方法でとりあえず何とかしましたが、これでもなんだかcheckerのスレッドを消費しそうなのと毎回スレッド生成するので遅くなりそうですね……。背に腹は変えられないということか?