Debuginfo

思考とアウトプット

AngularJSでwindowのresizeイベントでreloadする

ResponsiveのWeb appだとwindowリサイズ時に表示を切り替えたいときありますよね。 例えば、iPhoneを横で見たりとかすると画面が崩れるとか。 こんなときは、resize時にreloadすればいいと思います。そのコードはJQueryですが^^;

あとはこれをどこに置くかというと、全体に響く設定なのでrunに書きました。

angular.module('App', [
    'ngCookies',
.....
  ])
  .run(function(){
      // reload when window resize happens
      $(window).bind('resize', function(e){
        console.log('window resized..');
        this.location.reload(false); /* false to get page from cache */
      });
  })
  .config(function (...) {
....
  })

参考:http://www.sitepoint.com/jquery-refresh-page-browser-resize/

RedisでNotification(通知)を実装する

弊社サービスTraBerryのWebアプリケーションで通知を実装しました。その実装方法の話です。

f:id:shoheik:20140929124437p:plain

Notificationで使ったRedis keyは2つ。Arrayで全体の通知の管理。Hashで中身の格納です。

f:id:shoheik:20140929121331j:plain

  • list:notification:user_id:<user_id>
  • hash:notification:user_id:<user_id>
  • 上記hashのキーは通知タイプによって違う。コンテンツは通知用のメッセージ。

list:notification:usr_id:<user_id>で0を新しい要素。数が多くなる程古い通知メッセージです。

具体例で見ていきます。

ユーザ1がPhoto1にlikeする。このとき、like:photo_id:1:<user_id>:has_read:0 というkeyを作る。 このkeyをlist:notification:user_id:<user_id>に追加。そして、hash:notification:user_id:<user_id>にそれをkey, valueを通知メッセージとして、hashに格納。

my $key = "notification:user_id:" . $notified_user_id;
my $field = "like:photo_id:" . $photo_id . ':user_id:' . $user_id . ':has_read:0' ; 

# Check notification length and then, delete and add 
my $notification_length = $self->cache->llen("list:$key");
$self->cache->rpop("list:$key") if ( $notification_length > 30);

$self->cache->lpush("list:$key", $field);
$self->cache->hset("hash:$key", $field => encode_json($message) }

新しい通知メッセージがあるかどうかは、配列の中のhas_read:0を探せば良い。 そして、通知が読まれたときには、has_read:1のkeyの入れ替えを行う。

sub get_notification {
    my ($self, $user_id) = @_;
    my @notification;
    my $index = 0;
    for my $field ( $self->cache->lrange("list:notification:user_id:${user_id}", 0, 30) ){
        my $message = $self->cache->hget("hash:notification:user_id:${user_id}", $field);
        my $has_read = 1;
        if( $field =~ /has_read\:0/){ # change has_read:0 to has_read:1 
            $self->cache->hdel("hash:notification:user_id:${user_id}", $field);
            $field =~ s/has_read\:0/has_read\:1/;
            $self->cache->lset("list:notification:user_id:${user_id}", $index, $field); 
            $self->cache->hset("hash:notification:user_id:${user_id}", $field, $message);
            $has_read = 0;
        }
        if (defined $message){
            my $m = decode_json( $message );
            $m->{has_read} = $has_read;
            push @notification, $m; 
        }
        $index++;
    }
    return \@notification;
}

通知を削除するときは、その要素を削除するだけ。

LAMYにジェットストリームの替芯を使う一番簡単な方法

f:id:shoheik:20140923070417j:plain

LAMY サファリ イエロー ローラーボール L318 〔正規輸入品〕

LAMY サファリ イエロー ローラーボール L318 〔正規輸入品〕

LAMYのフォルムは好きですが、標準インクはボタボタでかなり使えないです。 書きやすさ以前の問題なので、他のボールペンの替芯に変えてる人は結構いますね。 今回は一番簡単な方法、SXR-5の替芯を買うだけ。(0.5mmじゃなくてもいいかもですが、確認してません)

では、手順。

1. SXR-5の替芯購入

f:id:shoheik:20140923070101j:plain (写真は破いた後^^;;

2. 付属用の保護キャップをLAMYの長さ調節に使う

f:id:shoheik:20140923070122j:plain

f:id:shoheik:20140923070138j:plain

このキャップをLAMYの中に放り込みます。そして、替芯を普段通りに挿入する。完了。 まるでこのためのキャップのようですw

DigitalOceanとAWSを利用し、スタートアップ初期に月額$100以下のインフラコストでサービスを提供する方法

私が勤めるActie, IncではTraBerryというサービスを提供しています(βです)。 弊社ではこのインフラにDigitalOceanと無料枠のAWSを利用しています。 DigitalOceanを利用することで大幅なコスト削減を実現しています。

スタートアップ時にはアクセスも少なく最低限のインフラ構成で良いです。 最低限の冗長化と大きくなっていくときにダウンタイムなしで、スケールアップとスケールアウトできることが必要です。

そのインフラのダイアグラムは、下記のようになります。

f:id:shoheik:20140921182902p:plain

  • Route53で入り口であるnginx(リバースプロキシ)を振り分ける
  • nginxはアプリケーションサーバ群にアクセスを振り分ける
  • アプリケーションは、RedisのキャッシュとMySQLのデータベースにアクセス
  • イメージはcloudfrontを利用し取得(後でブログエントリ書きます)

伝統的なWebアプリケーションのインフラですね^^; RedisとMySQLのスケールアップは、やや手間です。hostnameをうまく使ってMigrationの必要がありますね。 ただDigitalOceanはAWSインスタンスと比べるとかなり早く起動する(1分以内)ので、幾分ストレスなくできます。

で、やっぱ駄目なとこをリストすると

Cons

  • リージョンを挟んでデータベースのミラーリングが難しい
  • したがって、リージョンを挟んだRedundancyを組めない
  • データベース、キャッシュのスケールアウトはやっぱつらい

ま、安いのでしょうがないところでしょう。スケールアップしていって、これで持たないようならば、AWSに移行してもいい予算はあるはずです。

で内訳は、

  • 512M instance x 5 ( nginx x 2 + app x 3) = $25/mo
  • 2G instance x 3 ( MySQL x 2 + Redis x 1) = $60/mo x 20% backup = $72
  • AWS(無料枠もれたもの)= 約$2ぐらい

AWSはアクセスが伸びると$20ぐらい行くかもしれないことは秘密。