べにやまぶろぐ

技術寄りの話を書くつもり

『GMO プライベート DMP で ビッグデータ解析をするために アプリクラウドで Apache Spark の検証をしてみた』の資料を公開しました

Apache Spark を今後活用していくに当たって行ったプレ検証の結果について slideshare にアップロードしました。

もう少し詳細な内部の実装や挙動を見ていかないとと思いつつ、いい加減ワードカウントも飽きてきたのでデータ分析にトライしていきたいと考えております。

Slack で発言する Hubot にチャレンジしたらバージョン3系になっててちょっとハマった

最近流行りの ChatOps についていきたい!という純粋なミーハー心と日々のちょっとしたことを自動化したい(ミーティングのリマインダとか、ランチグループ分けとか)という思いから Hubot 使って Slack 連携をさせてみたのですが、最近バージョンが2系から3系に変わったということでウェブ上のドキュメントが微妙に古くなっててハマりました。

特に cron で robot.send() を呼んで定時に発言させたい、というだけだったのですが robot.send {room: "#general"}, "ハロー" とか robot. messageRoom "#general", "ハロー" とかいろいろ試したものの

[Sun Jan 18 2015 23:26:40 GMT+0900 (JST)] ERROR TypeError: Cannot call method 'send' of undefined
2015-01-18T14:26:40.609421+00:00 app[web.1]:   at SlackBot.send (/app/node_modules/hubot-slack/src/slack.coffee:181:16, <js>:216:33)

などとエラーが出てしまい、一瞬そもそも robot.send が呼べていないようにも見えつつ、追ってみると上記エラー内の slack.coffee で

channel = @client.getChannelGroupOrDMByName envelope.room

で channel を取得しているものの特に null チェックをすることなく

channel.send msg

に突入してしまっており、それはそれでまずいのですがそもそも channel が取得できていない様子。

で、色々調べてみると hubot-slack アダプタ v2 から v3 へ – 半月記 に大変よくまとめられていました。

v3 ではちょうど逆になって、ハッシュ(#)を付けないようになりました。これが付いていると正しく動作しません。

ということで cron の書き方もいろいろあって悩んだ挙句に最終的には

cronJob = require('cron').CronJob
module.exports = (robot) ->
  new cronJob
    cronTime: "0 58 9 * * 1-5"
    onTick: ->
      robot.send {room: "general"}, "朝会やりますよ ヽ(´・ω・`)/"
      return
    start: true
    timeZone: "Asia/Tokyo"

このように落ち着きました。npm の方で crontime のパッケージを足してあります。

ちなみに robot.send() が無い、という問題はそれはそれであるようで 橋本商会 » hubot-slackアダプタv3にアップデートしたら色々辛かった

websocket接続するまでrobot.sendが無い

と指摘されており、起動直後に send コマンドを実行するような場合は記事内に書かれている

return if typeof robot?.send isnt 'function'

のようなのを挟んでおくと良さそうです。

これから新規で slack 用 hubot 開発する場合は、まだまだ不安定なバージョン3系だということを意識して調査・開発したほうが良さそうです。

Trello のハッシュタグをもとにカードに色づけしてくれる Chrome プラグイン "Colored Hashtag for Trello" を Yeoman を使って作ってみた(その3)

↑ を作ってみたシリーズ、前回の記事 の続きです。

Yeoman の generator-chrome-extension でプロジェクトを作成すると /app/scripts/ 配下に background.js と chromereload.js という二つのスクリプトが生成されます。今回はこの二つのファイルについて調べたことをまとめてみます。

chromereload.js

chromereload.js は LiveReload というツールを通して、ファイルに変更を加えた時に自動的にブラウザをリロードする機能を提供してくれます。

GitHub - yeoman/generator-chrome-extension: Scaffold out a Chrome extension には

Debug task helps reduce your effors during development extensions. If the task detects your changes of source files, Livereload(chromereload.js) reloads your extension.

とありますが、開発中は grunt debug や grunt watch などを走らせておき、例えば

Running "connect:chrome" (connect) task
Started connect web server on http://localhost:9000

というようなメッセージが出力された場合には http://localhost:9000 にアクセスするとアプリケーションの HTML が表示されます。ここで LiveReload - Chrome ウェブストア のような LiveReload プラグインをブラウザに入れておくと、ソースの改変を grunt のタスクが検知、LiveReload がキックされブラウザに websocket で通知がいき、即時的にリロードが走ります。

ちなみに今回作成したプラグインは画面が無かったせいか

f:id:beniyama:20150109004318p:plain

のような素っ気ないファイル一覧が表示されました。これもリアルタイムで更新されます。

background.js

chromereload.js が開発用途だったのに対し、こちらは拡張機能の根幹となるファイルです。これはその名の通りバックグラウンドで走り続ける処理(イベントハンドリングなど)を記述するもので、以前は background.html と合わせて Background Pages と呼ばれていたようですが、Manage events with background scripts - Chrome Developers

Caution: Consider using event pages instead. Learn more.

とあるように現在は Event Pages に移行されているようです。

例えば Colored Hashtag for Trello では

/*global $:false, chrome:false */

chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
  "use strict";

  if (changeInfo.status === 'complete') {
    chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
      chrome.tabs.sendMessage(tabs[0].id, {message: "onUpdated"}, function (response) {
      });
    });
  }
});

のように chrome.tabs.onUpdated イベントにリスナーを張ってページの URL の変化を検出しています。これは Trello がサイドバーなどでページ遷移して URL が変わってもリロードが走らず Chrome 拡張が読み直されない = 遷移先のページで色をつけられない ことに困ったためで、HTML5 History API の使用も疑ったのですが最終的には tabs のイベントをとることで落ち着きました。

イベントリスナの中で chrome.tabs.sendMessage() としていますが、これは background.js と対をなす content_scripts にイベントの検出を通知し、画面描画処理をキックしています。content_scripts についてはまた次回書こうと思います。

ちなみに background.js に console.log() などを仕込んでも通常の開発者コンソールには出てこないため注意が必要です。デバッグログを見るには、chrome://extensions にアクセスして

f:id:beniyama:20150109011959p:plain

↑ のリンクを押すと下記のようなウィンドウが開きますので、そこで確認することができます。

f:id:beniyama:20150109012037p:plain

まだ Event Pages についての理解が浅いので、引き続き Update: Event Pages and Background Pages - Chrome Developers を読み込んでいこうと思います。


↓ 前回の記事

http://beniyama.hatenablog.jp/

Colored Hashtag for Trello を v1.0.3 に更新しました

こちらの Chrome 拡張ですが、

jQuery のセレクタで無駄に引き直しているところがあったのでそこを修正しました。また、Plus for Trello 拡張を意識して、複数のハッシュタグがある場合に先頭のものを使用するようにしました。

詳しくはこちらの GitHub で。

セレクタの性能改善については、一回 .list-card-title で個々のカードを引きにいった後、そこで取得した shortID でもう一回 .list-card-details で色塗りする親をセレクタで引いていたのが性能劣化を起こしていたので parent() で済ませるようにしました。

実行速度的には timer1 をセレクタで引き直すもの、timer2 を parent() で引くものとしたとき

coloredhashtag.js:95 timer1: 15.673ms
coloredhashtag.js:101 timer2: 0.042ms
coloredhashtag.js:89 ----
coloredhashtag.js:95 timer1: 14.759ms
coloredhashtag.js:101 timer2: 0.028ms
coloredhashtag.js:89 ----
coloredhashtag.js:95 timer1: 17.747ms
coloredhashtag.js:101 timer2: 0.027ms
coloredhashtag.js:89 ----
coloredhashtag.js:95 timer1: 13.844ms
coloredhashtag.js:101 timer2: 0.028ms
coloredhashtag.js:89 ----
coloredhashtag.js:95 timer1: 12.155ms
coloredhashtag.js:101 timer2: 0.029ms
coloredhashtag.js:89 ----
coloredhashtag.js:95 timer1: 13.309ms
coloredhashtag.js:101 timer2: 0.028ms
coloredhashtag.js:89 ----
coloredhashtag.js:95 timer1: 12.999ms
coloredhashtag.js:101 timer2: 0.027ms

という感じでカード一つの処理あたり 10 - 20 ms 程度の性能改善が見込まれます。今回実行速度も測ってみて、クラス名で引きにいくのはコストかかる処理だということを再認識しました。

Trello のハッシュタグをもとにカードに色づけしてくれる Chrome プラグイン "Colored Hashtag for Trello" を Yeoman を使って作ってみた(その2)

↑ を作ってみたシリーズ、前回の記事 の続きです。

タイトルにもありますが、今回初めて Chrome 拡張機能を作るに当たって、以前 勉強会 に参加してから気になっていた YeomanChrome Extension Generator を使ってみました。

node.js のサイト から node.js および npm をインストールし、続いて Getting started with Yeoman | Yeoman にあるように

$ npm install -g yo bower grunt-cli

などとして Yeoman、Bower、Grunt を呼べる状態にします。

続いて Chrome Extension Generator に書いてある通り

$ npm install -g generator-chrome-extension

として準備完了。

$ yo chrome-extension

とするとシェルが起動し、インタラクティブに Chrome Extension のテンプレートを作成することができます。

$ yo chrome-extension
? What would you like to call this extension? Colored Hashtag for Trello
? How would you like to describe this extension? This is my first chrome extension
? Would you like to use UI Action? No
? Would you like more UI Features?
? Would you like to use permissions?
   create Gruntfile.js
   create package.json
identical .gitignore
identical .gitattributes
identical .bowerrc
...
grunt-contrib-imagemin@0.7.2 ../node_modules/grunt-contrib-imagemin
├── pretty-bytes@0.1.2
├── async@0.7.0
├── chalk@0.4.0 (ansi-styles@1.0.0, has-color@0.1.7, strip-ansi@0.1.1)
└── imagemin@0.4.9 (stat-mode@0.2.0, ware@0.3.0, rimraf@2.2.8, image-type@0.1.4, nopt@3.0.1, tempfile@0.1.3, fs-extra@0.10.0, imagemin-svgo@0.1.1, imagemin-pngquant@0.1.3, imagemin-jpegtran@0.1.0, imagemin-gifsicle@0.1.1, imagemin-optipng@0.1.0)

というように Bower と Grunt が走り、Chrome 拡張機能の開発に必要なパッケージ群がセットアップされます。

ディレクトリ構成はこんな感じ。

$ ls -l
total 32
-rw-r--r--   1 beniyama  beniyama  7582  1  4 17:45 Gruntfile.js
drwxr-xr-x   7 beniyama  beniyama   238  1  4 17:45 app
-rw-r--r--   1 beniyama  beniyama   112 10  1 08:36 bower.json
drwxr-xr-x  23 beniyama  beniyama   782  1  4 17:45 node_modules
-rw-r--r--   1 beniyama  beniyama   893  1  4 17:45 package.json
drwxr-xr-x   7 beniyama  beniyama   238  1  4 17:45 test

この状態でもすでに manifest.json などに適当な値が入っている状態ですので、

$ grunt build

などとすると

$ grunt build
Running "clean:dist" (clean) task

Running "chromeManifest:dist" (chromeManifest) task
Build number has changed to 0, 0, 2

Running "useminPrepare:html" (useminPrepare) task
Going through  to update the config
Looking for build script HTML comment blocks

Configuration is now:

  concat:
  { background:
   { src: [ 'app/scripts/background.js' ],
     dest: 'dist/scripts/background.js' } }

  uglify:
  { 'dist/scripts/background.js': 'dist/scripts/background.js' }

  cssmin:
  {}
...

のように バージョン番号のインクリメントや JS ファイルの uglify、結合などをデフォルトで行ってくれます。package ディレクトリ下には Colored Hashtag for Trello-0.0.2.zip というような名前でパッケージが生成されますので、最終的に Chrome ウェブストアに登録するのはこのファイルになります。

開発フェーズでは、Chrome から直接ローカルのプロジェクトを読み込んで開発・テストを行うことができます。Chrome で chrome://extensions/ にアクセスすると『パッケージ化されていない拡張機能を読み込む』というボタンがありますので、そこから manifest.json のある app ディレクトリを指定すると下記のようになります。

f:id:beniyama:20150104182015p:plain

デフォルトでは Yeoman のアイコン画像をはめておいてくれます。また『リロード』というリンクを押すことで、grunt build し直したプロジェクトをブラウザに反映させることができます。livereload もサポートしているようなのでこの辺はソースを変更すると勝手に反映する、というのもできそうです。

ちなみに IDE ですが、IntelliJ IDEA を試してみたところなんと Grunt 用のコンソールが用意されていたりして、かなり開発しやすかったです。

f:id:beniyama:20150104182841p:plain

この Grunt Console を開くと

f:id:beniyama:20150104182853p:plain

のような小窓が開いて Gruntfile.js に定義されているタスクを GUI から呼べたりします。時代は Gulp という話も昔聞いたのですが、この辺ちゃんとサポートされていて驚きました。なんとなく Java の IDE というイメージを持っていましたが、web 開発全般で活躍してくれそうだったので PHP Storm に引き続き有償版を購入してしまいました。

次回は内部実装の話を書きたいと思います。


↓ 続きの記事

↓ 前回の記事

↓ Yeoman 周りの話題が出た勉強会

Trello のハッシュタグをもとにカードに色づけしてくれる Chrome プラグイン "Colored Hashtag for Trello" を Yeoman を使って作ってみた(その1)

あけましておめでとうございます、今年もよろしくお願いいたします。

年末はインフルエンザで寝込んでいたのですが、休暇中に作りたいものも一杯あったのでちょこちょここんなのを作ったりしていました。何気に元旦リリースです。

Colored Hashtag for Trello - Chrome ウェブストア

ちなみに GitHub はこちら。

GitHub - beniyama/colored-hashtag: Chrome extension plugin to color Trello cards according as their hashtags.

読んでの通り、Trello のタイトルにハッシュタグを含めるとそれに応じてカードの背景色を変えてくれます。

f:id:beniyama:20150104012317p:plain

こんな感じ。

Trello はデフォルトでもハッシュタグを打つと都度色の違うラベルを薦めてくれるようですが、ラベルはラベルで他の用途に使っていたりもするので背景色をまるっと変えてしまいました。

例えば自分のチームだと、ストーリーに紐づくタスクにはストーリー番号をハッシュタグで打って、ラベルでは『障害』とか『ToDo』とかのタスク種別を管理するようにしているのですが、結構(ストーリー)番号で確認するのって確認コストがかかってしまってコミットしたストーリーをきちんと終えるのにどれだけのタスクが残っているのかわかりづらかったりしていました。

なので色づけして、色がついているタスクはストーリーに紐づいているので優先度が高く、かつどのストーリーにどのタスクが紐づいているか色の種類でぱっと見でわかるといいなと思って作ったのが今回の作品になります。

色とか自分で設定できたらいいなとかはあるんですが、一旦リリースしてまずはチームとか、部内からのフィードバックもらいながら改善できればと思います。あと今回は兼ねてから気になっていた Yeoman の generator-chrome-extension を使っての、しかも初のブラウザ(Chrome)拡張機能開発で、コード自体はたいしたことないものの色々勉強することが多かったです。特に Trello って AJAX の極みというか、かなり柔軟な UI なので拡張機能もいろいろ考えること多くてそれはそれで大変でした。

その辺のトピックも追々ブログに書いていければと思います。

↓ 続きの記事を書きました

GitLab 7.5.3 でマージリクエスト時のコミットログが大量に表示される問題が解消

GitLab 7系に上げてから出ていた表記の問題、下記の stackoverflow にあるようにブランチ比較に使われている git ラッパーの Rugged のバグに起因するものでした。マージリクエストを作成するとブランチ間の差分コミットが全履歴分?出てしまって画面で diff を表示できない、そもそもブラクラになってしまうというものでした。

これも stackoverflow に書かれているように Gemfile.lock の Rugged のバージョンを 0.21.2 に手で修正して bundle install をやり直すことで回避できていましたが、ようやく最新の 7.5.3 で正式に解消されたようです。

GitLab 7.5.3 Release | GitLab

GitLab 7.5.3 updates Rugged to 0.21.2 to solve issues with 'finding too many commits'. This issue could cause the PostReceive job triggered by a git push to take a very long time and consume a lot of memory.