| @技術/プログラミング

DSC_4022.jpeg

Amazon Product Advertising API ( PA API )が 5.0 になるらしい。 4.0 は 3 月で廃止になるそうだ(当初は 2 月 11 日と言われていたが、 3 月まで伸びたみたい)。

最近 4.0 に対応させたのにな、と思って調べてみたら何と 4.0 対応したのは 10 年以上前だった。

PA API 4.0 までは AWS アカウントで利用する感じ1だったが、 PA API 5.0 では AWS から独立して Product Advertising API 専用のアカウントを登録しなければならないようだ。

AWS は US Amazon でアカウントを作るのに PA API のレポート画面へのログインでは Amazon Japan のアカウントを使うのは変だなと思っていたけど、 PA API 専用アカウントを設けることでその辺のねじれも解消されるだろう。

クライアントライブラリにはこれまで ecs という gem を使ってきたが、 PA API 5.0 対応はされてなくて、別の人が作った vacuum という gem に乗り換えた。

ecs という gem の名前に違和感をもつ人がいるかもしれない。いまでは Amazon で ECS といえば AWS の ECS ( Elastic Container Service ) のことを指すが、昔は Amazon 自身が PA API という名前ではなく Amazon ECS という名前でアフィリエイト用のシステムを提供していた。 Amazon は命名が色々紛らわしい。

PA API 5.0 は RESTful API ではなく GraphQL のような感じで、欲しいフィールド名を指定して API リクエストする感じになっている。レスポンスのサイズが小さくなって便利になった。

ちなみに移行ガイドは以下にあります。

DSC_4119.jpeg


  1. 10 年前にペパボの面接を受けに行ったときに「 AWS 使えますか?」と聞かれて「はい、使えます。アフィリエイトで小銭を稼いでいます」と答えてしまった。 

| @散財

ペーパードリッパーホルダー

概要

ドリップバッグのコーヒーはお湯に浸かって味が薄くなるが、ドリップバッグホルダーを導入してドリップをしやすくなりコーヒーの味が改善(濃く抽出される)。付属の受け皿で水切りができ、片付けも楽になった。


以前は会社で豆を挽いてコーヒーをいれて飲んでいたが、最近忙しくて豆から挽いてコーヒーいれて飲んでるような余裕がない。とはいえ全自動マシンのやつは飽きてしまったのでドリップバッグのやつを買って飲むようになった。まずはドトールのものを飲んでみてなかなか悪くないとは思ったが、どこまでお湯を注げばよいかがわかりづらい点や、お湯に完全に浸ってしまうことにより片付け時に水がポタポタと垂れてしまう点でいまいち体験が良くなかった。

そんななかコーヒードリップバッグホルダーというアイテムの存在を知った。

試しに買ってみるにはちょっと値段が高いなと思ったがリストカット感覚で注文してみた。テレビか何かで紹介されたばかりのようで Amazon には在庫がなく、届くまで二週間くらい待った。

使うときはこんな感じで使う。カップの上にドリップバッグホルダーをセットし、その上にドリップバッグをかける。

カップの中の様子を見ながらお湯を注げるのでどこまで注げば良いかわからないという問題や、ドリップバッグがお湯にどっぷり浸かってびちゃびちゃになるという問題が解決する。

おまけに受け皿も付いているので、まだ少し水がしたたる状態でカップから引き上げてもとりあえず置いておく場所を確保できる。とても便利。

さらにこれは期待していなかったことだが、ドリップバッグをお湯の中にドボンとつけないことで味もおいしくなる気がする。これまでドリップバッグではコーヒーの味が薄めになるのが不満だった。大抵のドリップバッグは豆の量が 7g 程度で少なめなので仕方がないのかなと諦めていたが、ドリップバッグホルダーを使うようになってから濃いめに抽出されるようになった。ドボンとお湯に浸からないおかげでお湯がコーヒー豆の中を通り、コーヒーの成分がちゃんと抽出されるのだろう。

図で説明するとこんな感じ。

ドリップバッグホルダーなし: お湯がすぐにフィルターの中から抜け出してしまい、十分にコーヒーの成分が抽出されない ドリップバッグホルダーあり: お湯が豆の中を通り抜けてからフィルターの外に出て行き、コーヒーの成分がよく抽出される

というわけでドリップバッグホルダー、めちゃおすすめです。

ドリップバッグは以下を使ってます。 100 パックで 2000 円くらいで安い!

| @技術/プログラミング

関連記事に画像を表示するようにして喜んでいたが、先月の AWS の請求額を見てビックリ。普段の 15 倍くらいの金額になっていた。デイリーの利用料金を見ると関連記事に画像を表示するようになった日から高くなっている。

CloudFront 転送量

このブログの画像は S3 に置いてあって CloudFront から配信している。これまでたくさん写真を掲載しても特にコストは高くなかった( Route 53 の費用など含めても $3 くらい、転送量だけだと $1.5 くらいだった)のが、転送量だけで $30 オーバーになっていた。ブログのサーバー代は Adsense 広告と Amazon アフィリエイトでまかなうつもりでやっているので、これでは完全に赤字になってしまう。

なぜ高くなったのかというと関連記事にサムネイル画像を表示することで、 imageproxy から CloudFront へのアクセスが発生するようになったからのようだった。こんな感じ。

image-data-transfer-infrastructure-1.png

imageproxy にもキャッシュの仕組みはあるが、 CloudFront が返す Cache Control ヘッダーの内容を理解せず決め打ちの時間でキャッシュを Expire させるので効率が悪い。

恐らく以下のように画像関連のインフラは AWS に寄せるのが一番効率的だと思う。Amazon の優秀なエンジニアが作ってる CDN が一番前段に出てブラウザーからのリクエストに答えるのがもっとも効率的に画像を配信できると思う。

image-data-transfer-infrastructure-2.png

ただ個人のブログレベルでここまでやるのは割に合わない感じがしたのでとりあえずは以下のような構成にした。

image-data-transfer-infrastructure-3.png

Nginx の proxy cache を使う。

キャッシュ時間は長めにとって 30d にしておいた。

あわせてキャッシュの HIT 率を計測するようにした。ログに $upstream_cache_status を書き出すようにして、 awk で定期的に集計するようにした。こんな感じ。

cat log/access.log \
  | grep 'cache_hit:' | grep -v 'cache_hit:-' | cut -f16 | sort | uniq -c \
  | awk '{
      if ($2 ~ /HIT/) {
        hit = $1
      };
      if ($2 ~ /EXPIRED/) {
        expire = $1
      };
      if ($2 ~ /MISS/) {
        miss = $1
      };
      sum += $1
    } END {
      hit_rate = hit/sum*100;
      expired_rate = expire/sum*100;
      miss_rate = miss/sum*100;
      print "HIT\t"hit_rate"%\nEXPIRE\t"expired_rate"%\nMISS\t"miss_rate"%"
    }'

こいつを Lokka の Dashboard に表示させる。

キャッシュヒット率

加えて、 Google の以下の記事を参考に、画像の遅延読み込みを行うようにした。

とりあえずはこれで様子を見たい。いまのところ、ちょびっとずつ転送量は下がってきているような感じがする。もうちょい下げたいところ。

しかし、画像の配信で毎月 $30 もかかるようであれば自前で画像をホストするのは諦めて Flickr に金払って PRO プランを継続した方が安いなと思い始めてしまった…。 Google Photos でも良いが、 Exif がわからなくなるのと埋め込み用の画像を取得する作業(公開用のアルバムを作ってそこに埋め込みたい写真を入れていく必要がある)が面倒くさいので移行に踏み切れない。

| @読書

DSC_6351

おもしろかった。 Twitter 、 CEO がコロコロ交代してて誰が中心人物なのかよく分からなかったがだいたいわかった。成立の過程が結構複雑で、 Podcast 配信会社だった Odeo を Noah Glass が創業し、 Blogger で一発あてたあとの Evan Williams が出資して会社を乗っ取り、 Evan Williams に憧れて入ってきたアルバイトの Jack Dorcey が Noah Glass とブレインストーミングして Twitter の原型を生み出し、 Odeo を飛び出して Twitter という会社を創業し Jack Dorcey が最初の CEO になる、という感じ。 2007 年から 2008 年頃にかけて自分が面白おかしく使っていた Twitter の中では群像劇が繰り広げられていたことがわかり興味深かった。

特に興味深かった箇所は以下で、自分も 2008 年頃、実家に住んでて周りにインターネットのことを話せる友だちはほとんどいなかったけど、 Twitter 越しにインターネットユーザーと交流することができて孤独を癒やされていた気がする。

 このステータスは、その場にいない人々を結びつけるのに役立つ。どんな音楽を聴いているか、いまどこにいるかということを、共有するだけではない。人々を結びつけ、孤独感を癒すことが重要なのだ。パソコンの画面を見つめているときに、どんな世代でも味わう感情を、消し去ることができる。ノア、ジャック、ビズ、エブは、そういう感情を味わいながら成長し、パソコンのモニターに安らぎを求めた。結婚生活と会社がだめになりつつあるとき、ノアはその感情を毎夜味わっている。孤独感を。

 エブがブロガーに熱中した原動力も、そういう感情だった。アパートメントに独りでじっと座り、孤独で、友だちもなく、キーボードを通じて世界とつながっていた。何年も前にビズが母親の家の地下室でブログをはじめた理由もおなじだ。ジャックもおなじ理由から、セントルイスにいるころにライブジャーナルのアカウントを取り、掲示板をうろついて結びつきを求めている人々とやりとりするために、コーヒーショップで何時間も粘った。ステータスという構想は、そういったことすべての解毒剤になり、孤独感を癒せるかもしれない、とノアは考えた。

ニック・ビルトン. ツイッター創業物語 金と権力、友情、そして裏切り (Japanese Edition) (Kindle Locations 1017-1026). Kindle Edition.

ただその後、 Evan Williams が CEO になって Twitter はステータス共有(投稿欄のプレースホルダーは "What are you doing?" )から情報発信メディア(投稿欄のプレースホルダーは "What's happening?" )への変革を図った。個人のステータスではなく、その人の周囲の状況を伝えて欲しいということだ。確かに 2010 年くらいから Twitter の様子が変わったように思う。東日本大震災のあとは日本の Twitter もニュース寄りになっていって、 2008 年頃のジャンプ放送局のような雰囲気はなくなってしまった。

Twitter はビジネスとしては成功したが、創業者たちはお互いの人間関係を悪化させ、大事な友人を失いながら莫大な富を手にした。最終章に出てくる、ビズ・ストーンが貧乏だった時代のエピソードがとても心温まる。この部分だけでも読んで良かったと思った。


Noah Glass 、 Twitter の最初期を支えた人物だと思うけど会社を追い出されて Twitter 社の歴史からもいなかったことにされ、ひたすら可哀想。おまけに Noah の Twitter アカウントは「不審なアカウントです」と表示されたりする。

| @技術/プログラミング

Archive ページ をリファクタリングした。

これまで gulp をビルドに利用していた(Archive ページを React Router 化)が、 webpack を使うように変えた。

React のコードも見直して、 DOM の状態に依存して表示・非表示を切り替えるコードがあったりして( 🐙 Archive ページにカテゴリごとの記事件数を表示する機能を追加 )ごちゃごちゃしてたので DOM を直接ごちゃごちゃ操作するのをやめて React で管理するように変えた。親コンポーネント、子コンポーネント、孫コンポーネント、子コンポーネントの兄弟コンポーネント間で状態を共有する必要があって、結構難儀した。

Archives React Component 1.png

実際の画面を見るとこんな感じ。

Archives React Component 2.png

App というコンポーネントがルートにあって、子に CategoryListCategoryList の子コンポーネント( App からすると孫)に Category コンポーネントがある。記事一覧自体は CategoryList と兄弟コンポーネントである Archive コンポーネントが担当している。

Archives React Component 3.png

こんな感じで特定の Category が選ばれたことを Category のクリックイベントをトリガーに CategoryList に伝達し、 CategoryList はさらにそれを App コンポーネントに伝える。その結果が App から Archive コンポーネントに伝えられ、表示内容が変更される。

この辺を参考にして実装した。コールバック関数を props として引き回し、状態を回収する感じ。

ただこういう込み入った状態の管理を React で行う場合は Redux などを利用するのが良いようだった。

前職のとき、 Redux とか Flux が出てきた頃に F/E のエンジニアの人たちが熱狂してたけど自分はいまいち理解できなくて、傍観するだけだったが、いまさらにして何となく Flux アーキテクチャの概要的なものを把握することができた気がする。ただ自分の場合は深みに入り込まず極力シンプルに作りたいと思っていたので Redux などには手を出さず、 Callback で愚直に状態を親コンポーネントに伝達していく方法をとった。

React 、やっぱり大分良いものだとという感じがした。 jQuery でクラスや CSS で show - hide を Toggle していた頃とは隔世の感がある。

| @Mac/iPhone

Castro

以前書いたことがある Castro🎧 Overcast と Castro - portal shit!)がすごく便利になっている。

以前の記事では、 Overcast にあるチャプター移動機能やオーディオエンハンスメント・無音カット機能が Castro にはないと述べていた。しかし一年ちょい前にリリースされた Castro 3 により、有料ではあるがこれらの機能が提供されることになった。

これがめっちゃ便利。 UI は前にも述べたとおりすぐれているし、さらに購読中の Podcast のショーノートを検索する機能も今年の 1 月についた。

これもスーパー便利で、「あの Podcast の誰々がゲストで出てる回を検索して聞きたい」というありがちな要望を満たすことができる。以下は Rebuild のエピソード一覧で "higepon" で検索し、 higepon さんが出てるエピソードだけを絞り込んでる図。

Rebuild.fm で higepon さんが出演してる回で絞り込んでる様子

めっちゃ便利で最高なので是非お試し下さい。

| @Mac/iPhone

Fire

Memolist.vim の保存先を Dropbox にする運用を長年続けてきたが、 iOS の Markdown エディターの iA Writer で編集時にファイルが無限複製されるという問題があることや、最近のポリシー変更で Dropbox を無料で使い続けるのは難しそうかつお金を払うにしてもプランが高め(最安でも ¥1,500 / 月で 2TB まで使えるプランしかない)で個人では使いづらそうなので iCloud Drive を代わりに使ってみることにした。 iCloud は今のところ無料で使ってるが 50GB 使えるプランでも月額 ¥130 なので個人で使いやすい。 iCloud Drive は Windows や Linux からは使えないが、 Linux デスクトップはもう何年も使ってないし、 Mac と iPhone にロックインされた生活に不満はないので無問題。

移行の手始めにまずは iCloud Drive にターミナルでアクセスしようとするが、 cd ~/iCloud\ Drive などではたどり着けない。以下の記事を読んで調べた。

パスは ~/Library/Mobile\ Documents/com~apple~CloudDocs で良いみたい。

~/Dropbox/memolist ディレクトリを ~/Library/Mobile\ Documents/com~apple~CloudDocs/Documents/ ディレクトリに移し、 .vimrc を以下のように書き換えた。

diff --git .vimrc .vimrc
index 6c4987e..56882b2 100644
--- .vimrc
+++ .vimrc
@@ -568,7 +568,7 @@

     " memolist.vim {{{

-      let g:memolist_path = "~/Dropbox/memolist"
+      let g:memolist_path = "~/Library/Mobile Documents/com~apple~CloudDocs/Documents/memolist"
       let g:memolist_unite = 1
       let g:memolist_unite_source = "file"
       let g:memolist_unite_option = "-auto-preview -start-insert"

これで Memolist.vim の Markdown ファイル保存先を iCloud Drive に移行できた。