読者です 読者をやめる 読者になる 読者になる

unhurried

コンピュータ関連ネタがほとんど、ときどき趣味も…

Heroku Free DynoのSleepを防止する

Herokuでは月に1000時間の稼働稼働枠がもらえますが、無料プランでは30分アプリにアクセスがないとアプリがSleep状態になってしまいます。New Relicアドオンを使って定期的にリクエストを送信することでアプリがSleep状態になることを防げますので、設定手順をご紹介します。

New Relicアドオンのセットアップ

# Herokuにログインする
$ heroku login
# New Relicアドオンを追加する(wayneは無料プランの名称)
$ heroku addons:add newrelic:wayne -a {app name}
# New Relic設定画面をブラウザで開く
$ heroku addons:open newrelic -a {app name}

New Relicの設定

最初に表示されるプロダクト選択画面で「SYNTHETICS」を選択する。

モニターの作成画面で以下を入力する。

(1) Choose your monitor type:Ping

(2) Enter the details

  • First, name your monitor:(適当な名前を付ける)
  • Enter a URL:(HerokuアプリのURLを入力する。アプリにリクエストが送信されればエラーが返却されても問題ないので https://{app name}.herokuapp.com/ などでよい。)

(3) Select monitoring locations

  • どのロケーションを選択しても大差はないと思うので適当に選択すればよい。

(4) Set the schedule:15min

  • 30分より短く設定する必要があるため。

まんがでわかる 7つの習慣

久々にまんがでわかるシリーズを読みました。今回はかなりブームを過ぎていますが、コヴィーの7つの習慣です。

まんがでわかる 7つの習慣

まんがでわかる 7つの習慣

感想

7つの習慣それぞれについては、この書籍を読めば簡単に要旨を理解できると思いますので、印象に残ったことをまとめてみました。

主体的である

自分のゴールを描いて「すべき」かつ「できる」ことから始める、ある意味では自分の世界に閉じこもることが、ブレずに行動する秘訣なのだと思います。

相手を理解することから始める

仕事でもプライベートでも相手が自分の希望通りに動いてくれないことで不満や苛立ちを感じることは多いと思います。まずは先述した自分の世界を盾に「相手を最終的に理解できなくても大した問題でない」とリラックスして、次に「自分を含め完璧な人間などいない」を前提に、相手の論理を理解しようとする、ということが重要だと思います。

アメリカで購入できる胃薬

胃が弱いのでよく胃薬にお世話になります。 アメリカに来た当初は何を買えばよいかわからなかったので、定番を調べてみました。

  • Tums

    • 気軽に飲める制酸剤。カルシウムの補給用途にも使える。
  • Zantac

    • H2ブロッカーという胃酸分泌を抑制する薬。
    • 日本の薬局で購入できるガスター10と成分は異なるが同様の効果。
  • Nexium

  • Gax-X

    • 腹部膨満時に利用する消泡剤。
    • 日本でよく処方されるガスコンに似た成分が入っている。

JAX-RSアプリをHerokuにデプロイする

Javaで実装したREST APIをHerokuにデプロイするときに少し迷ったため、今後のためにひな形としてサンプルアプリを作成しました。

github.com

ポイント

ローカルで実行する

maven clean package
  • Web Runnerを起動する。
java -jar target/dependency/webapp-runner.jar target/*.war

Open ID Connect Client

I implemented an example of Open ID Connect Relying Party with Play framework (Java). This time only "Core - Authorization Code Flow" and Session Management - RP Initiated Logout" are implemented. I chose "Connect2id : Nimbus OAuth 2.0 SDK with OpenID Connect extensions" as an Open ID Connect library.

github.com

Impression of Connect2id

  • The class architecture is simple and easy to guess the usage.
  • It is not good I/F which needs a cast in the process where analyzing an error of authorization.
    • Cast from AuthenticationResponse to AuthenticationErrorResponse will be happened.
  • There is no function to receive the callback of RP initiated Logout.
    • It is better to provide it to make the unity with other APIs.

MongoDB Node.JS Driver コネクション管理

Java + MySQLではどのフレームワークにも当たり前にあるコネクションプールのようなコネクション管理機能ですが、Node.js + MongoDBではどのように実装するのが常套手段なのかを調べました。

ポイント

  • MongoClient.connectは1度のみ呼び出し、databaseインスタンスを再利用する。
  • コネクション管理はDriverが行ってくれて、MongoClient.connectのオプションにコネクションプール数を指定できる。

サンプルコード

  • db.js
// Keep the mongoDB connection while the application is running.
var db = null;
module.exports.initialize = co.wrap(function*() {
    db = yield MongoClient.connect("mongodb://...");
});

module.exports.getById = co.wrap(function*(id) {
var col = db.collection("collection");
    var row = yield col.findOne({_id:id});
    return row.property;
});
  • app.js
var db = require('./db');

co(function*(){
    db.initialize();
    var result = db.getById(0);
    ...
});

参考

Callback地獄対策 (3) aa generator

今回は、Qiitaで人気のあるCallback地獄対策の記事で紹介されているaaについて調べてみました。

aaもcoと同様にGeneratorの仕組みを利用して簡単に並列・直列処理フローを記述できるようにするライブラリです。 aaはcoと比べるとthunkify/promisifyが同じライブラリにパッケージされていることと、thunkifyAll/promisifyAllでオブジェクト全体にかけれられるの良いところと思います。 一方で、co.wrapに相当する機能はなく、並列・直列処理フローを利用したyieldableな関数を作るときに少し不便と感じました。

const aa = require('aa');

// callbackを引数にとる関数を持つオブジェクト
var callbackObject = {
    func: function(message, timeout, callback) {
        setTimeout(function() {
            console.log(message);
            callback(null, message);
        }, timeout);
    }
};

// aa.promisifyAllはオブジェクト全体に対してpromisifyを適用する
// promisifyはcallbackを引数にとる関数をPromiseを返却する関数に変換する
// Promiseoにはgenerator内でyeild式を適用できる(yeildable)
var promisifiedObject = aa.promisifyAll(callbackObject);

// aa関数はcoと同様にGenerator(function*(){...})を渡すと、
// yeild式に指定されたPromiseの完了を待ってから処理を再開させる
aa(function*() {
    console.log('--- aa start ---');
    
    // 2つの関数を並列処理する
    // 並列処理をするにはyeildにArrayもしくはObjectを指定する
    var response = yield [
        promisifiedObject.funcAsync('aa two', 800),
        promisifiedObject.funcAsync('aa one', 600),
    ];
    console.log("response: " + JSON.stringify(response));

    // 2つの関数を直列処理する
    yield promisifiedObject.funcAsync('aa three', 200);
    yield promisifiedObject.funcAsync('aa four', 400);
    
    // aaを利用した関数の呼び出し(後述)
    yield wrappedFunction();

    console.log('--- aa end ---');

    // Generatorでreturnするとaa.then()に指定した関数が実行される
    return "Generator finished.";

    // いずれかのPromiseでreject関数が呼ばれると
    // aa.error()に指定した関数が実行される
    yield Promise.reject("An error happened.");

}).then(function(value){
    console.log('--- then start ---');
    console.log(value);

}).catch((error) => {
    console.log('--- error start ---');
    console.log(error);
});

// aaにはco.wrapに相当する機能がないため、
// yieldを利用した関数を定義するにはaa(function*(){})を返却する関数を作る
var wrappedFunction = function() {
    return aa(function* () {
        console.log('--- wrap start ---');

        var response = yield [
            promisifiedObject.funcAsync('wrap two', 800),
            promisifiedObject.funcAsync('wrap one', 600),
        ];
        console.log("wrap response: " + JSON.stringify(response));
        yield promisifiedObject.funcAsync('wrap three', 200);
        yield promisifiedObject.funcAsync('wrap four', 400);

        console.log('--- wrap end ---');

        return yield Promise.resolve(null);
    });
};

実行結果

$ node aa_generator.js
--- aa start ---
aa one
aa two
response: ["aa two","aa one"]
aa three
aa four
--- wrap start ---
wrap one
wrap two
wrap response: ["wrap two","wrap one"]
wrap three
wrap four
--- wrap end ---
--- aa end ---
--- then start ---
Generator finished.

参考