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

ravelll の日記

よしなに

pixiv Night #02 に行ってきた

pixiv さんが話す画像処理技術、こりゃ面白そう!ということで connpass のページを見つけて即申し込んだ会でした。

画像処理は大学の頃に研究で OpenCV で動画像処理をやって以来惹かれている分野で、Web アプリケーションエンジニアとなった今、pixiv 社が提供する画像処理をコアとする Web サービスの話は興味のど真ん中だった。

pixiv のオフィスに入るのは初めてで、噂の絵馬や巨大な1枚机を見れたのも良かったです。オフィス見学は楽しい。

トークはどれも面白く、個人的には @saturday06 さんの Halide の話と @harukasan さんの jpeg ブロックノイズの話が特に刺激的だった。Halide 遊んでみよう。

懇親会では久しぶりにお会いできた @RooandQoo さんと互いの近状や KAC/DAC の話をしたり。また週末に。

Mackerel で金の買取相場を監視する

去年末、社員旅行での抽選会で純金が当たった。

まだしばらく売る気はないのだけど、ひとまず金相場が見たい、ということで Mackerel で監視することにした。

稼働環境は Amazon EC2Amazon Linux)です。

手順

まずは mackerel-agent をインストール。APIKEY は各自のものに読み換えてください。

$ curl -fsSL https://mackerel.io/file/script/amznlinux/setup-all-yum.sh | MACKEREL_APIKEY='yourmackerelapikey' sh

次に監視するパラメータを取得・設定するスクリプトを設置。

#!/bin/bash

name="GoldPrice"
monitor_time=`date +%s`
market_rate=`curl http://gold.mmc.co.jp/market/gold-price/ | grep -A1 metalType1 | tail -1 | tr -d "\t" | tr -d "," | cut -b 4-7`
echo -e "${name}\t${market_rate}\t${monitor_time}"

設置したスクリプトを使いメトリックを作成するよう mackerel-agent.conf を修正。

$ sudo vim /etc/mackerel-agent/mackerel-agent.conf

[plugin.metrics.process]
command="bash /path/to/script.sh"
type="metric"

これでカスタムメトリックとして金相場のグラフが表示されます。

ラベルはグラフ右上の設定ページで変更できます。今回はストレートに「金相場」としました。

f:id:ravelll:20170214221215p:plain

よさそうです。

グラフが表示されないときは /var/log/mackerel-agent.log を見ると原因が特定できると思います。

今後

金相場の情報を取得しているページの更新が日に1回のようだし、不必要に高頻度なスクレイピングは行儀が悪いのでエージェントのフェッチ間隔を広げたい。

今は1分毎にメトリックに Post されており、ひたすら平坦なグラフが続いていて情報価値が低い。相場が上下する経過が見たいのだ。

plugin.metrics.* の実行間隔は設定できるのかなと mackerel-agent のコードを読んだのだけど、config/config.go#L214 の変数を toml からの入力で変更する箇所は無いように見えるのでできない…?

plugin.checks.* での check_interval や execution_interval のようなパラメータがあるのかなと思ったのだけど無いのかな。会社の有識者の方々に聞いてみよう。

追記

はてな社のセールスエンジニアである id:a-know さんより、サービスメトリックにするとよいとのアドバイスをいただきました。ありがとうございます!!

オブジェクト指向設計実践ガイド 第6章

6章は継承の話。既知の内容も多かったけど、フックメソッドのテクニックは知っておらず、なるほど〜という感じだった。

徐々にサンプルコードのコンテキストが厚くなってきたので写経しつつ読み進めた。

transcriptional_codes/guide_for_object_orient_designing/chapter6 at master · ravelll/transcriptional_codes · GitHub

それにしてもこの本、読み進めているとたびたび唐突に自転車が猛烈プッシュされてきて、著者の抑えきれない自転車愛が伝わってくるのが面白い(知識があるだけなのかもしれないけれど)。まさかリカンベントまで出てくるとは。

6章のホット・バイシクル・センテンシーズはこちらです。

「ハンドルバーのテープはそこまで重要でなさそうですが、
実際には(タイヤやチェーンと)同じくらいに必要とされます。
誇りを持つサイクリストの中に、横れたり破けたりしたバーテープを許す人はいません」

第6章 継承によって振る舞いを獲得する

6.1 クラスによる継承を理解する

  • 継承:メッセージの自動委譲の仕組み
    • あるオブジェクトが受け取ったメッセージに応答できないとき他のオブジェクトにそのメッセージを委譲する

6.2 継承を使うべき箇所を識別する

  • オブジェクトの属性による分岐
    • ダックタイピングが解決する問題と同じパターン
    • 「自身の分類を保持する属性を確認し、自身に送るメッセージを決定する」
  • type, category という変数名はその根底にあるパターンへの気づきを促している
  • 継承は共通の振る舞いを持つもののいくつかの面においては異なるという強く関連した型の問題を解決する
  • サブクラスはスーパークラスの全てであり、スーパークラスを上回るものである

6.3 継承を不適切に適用する

6.4 抽象を見つける

  • 継承が効果を発揮するために必要な2つのルール
    1. モデル化しているオブジェクトが “一般 - 特殊” の関係を持っていること
    2. 正しいコーディングテクニックを使っていること
  • Ruby は他者を信頼する性質から Java における abstract 等ののキーワードを持たず、制約を加えることもない
  • 抽象クラスはサブクラスが作られるためだけに存在する
    • 抽象クラスがサブクラス間で共有される振る舞いの格納場所を提供する
    • サブクラスがそれぞれに特化した振る舞いを用意する
  • サブクラスを1つだけもつ抽象クラスを作ることはほぼまったく意味がない
  • 階層構造を進める決断は、正しい設計のための情報が未だ無いかもしれない、というリスクを受け入れること
    • 今2種類のカテゴリは3種類になる見込みがあるなら階層構造を作ったほうがいいかもしれない
    • 2種類から増えないならば階層構造を作らないほうが低コストかもしれない
    • 可能なら判断を待つ。しかし最善だと思えるならば進む
  • 既存のコードはスーパークラスに昇格させるよりサブクラスに降格させる方が簡単
    • 抽象クラスを作るときは一度全体を降格させてから必要な分の実装を昇格させるのがよい
  • リファクタリングやその他の戦略を決める際は「もし間違っているなら何が起こるか」を質問するのが有用
  • 信頼できない階層構造は、それと関わるオブジェクトに階層構造の癖を知るよう強要する
    • そのときよく使われる手段が、オブジェクトのクラスの明示的な確認
  • 設計者の決断に常に伴う2つのコスト
    1. 実装コスト
    2. 実装が間違いと分かったときの変更コスト
  • Bicycle クラスは初期値をメソッドで包み、それをオーバーライドすることで何かに特化できる機会をサブクラスに与えている
    • スーパークラス無いで基本構造を定義し、サブクラス固有の情報を得るためにメッセージを送る
    • このようなテクニックをテンプレートメソッドパターンという
  • テンプレートメソッドをサブクラスで特化させる必要があると明示的に示すには、スーパークラスのメソッドで未実装と分かるようなエラーを出す

6.5 スーパークラスとサブクラス間の結合度を管理する

  • サブクラスは自身を特化する振る舞いについて知っているのは良いが、super で抽象スーパークラスとの関わり方まで知るよう強制するのは良くない
    • 全てのサブクラスが正確に同じ箇所で super する必要があるのは、新たにサブクラスを書くときにエラーを作る可能性を高める
    • サブクラスが super を送ることは、サブクラスはスーパークラスの処理を知っていて、その知識に依存しているということ
  • super を送ることをサブクラスに求めるのではなく、フックメッセージを用意してスーパークラスから情報を取得する
    • サブクラスは自身について「何を」特化する必要があるかについては責任を負うが、「いつ」特化するかについては責任がなくなる

まとめ

  • 継承は共通の振る舞いを持ちつつも、いくつか相違点のある型に関する問題を解決する
  • 抽象的なスーパークラスを作る最も良い方法は具象的なサブクラスからコードを押し上げること
  • 正しい抽象の設計が最も簡単なのは存在する具象クラスが少なくとも3つあるとき
  • サブクラスはフックメソッドによってスーパークラスアルゴリズムを知らなくとも特化できるようになる