upinetree's memo

Web系技術の話題や日常について。

継続的デプロイの次の課題はなんだろう

Feature Toggle について考えていた流れで、デプロイシステムのことが気になってきた。 ちょっと前にどうやったらデプロイをもっと楽できるだろうかとか考えていたせいもあって、どうも気になると落ち着かない。 軽く思考を整理してブログという形で放流しておく*1

一言でいうと、たとえ理想的なデプロイシステムが得られたとしても、きっと別のところがボトルネックになるので一緒に解消していかないとだよなあみたいな話。

CI/CDがうまく回り始めたら

たとえば master にマージしたら自動でデプロイしてすぐに反映されるみたいな。いわゆる継続的デプロイ (not デリバリ) が達成できた状態。 なんかもう何も考えなくてもデプロイできちゃう。

こうなった状態で何が発生するかと考えると、僕のような人間としてはやはり master にマージするのが怖くなっちゃう気がする。 レビュアーがマージするとしたら、レビュアーは Approve するのが怖くなる。 レビュイーがマージするとしても、Approve もらったあとにマージするには一定の自信と覚悟がいる。

ほかには、機能のリリーススケジュールが決まっているときなんかは結局マージせずにその日を待つこともあるだろう。

一方で、デプロイとは別問題として feature branch を運用する上での課題にも考えを巡らす。

  • master の差分取り込みコスト
  • 他のブランチとの衝突
  • 予期せぬリグレッション
  • コードフリーズ

マージが遅れるとかマージできないってことはこれらの課題を相変わらず抱えたままということ。 デプロイが楽になっても、結局色々考えることあるんじゃないか。

じゃあどうする

トランクベース開発の推進

このあたりの話。

できる限り小さく変更を分けてこまめに master にマージすれば、怖さも最小限で済む。 マージが「機能の開発完了」単位でなく、小さな変更単位になっている状態を目指す。そうした文化づくりをしていく。

とはいえ一度に出したい機能もあるのが実際のところ。 そこでデプロイとリリースの分離が必要になってくる。

デプロイとリリースの分離

  • リリースのレバーをビジネス側が持つ
  • デプロイのレバーを開発側が持つ

こうできたら理想的だし、リリーススケジュール都合でデプロイを待つ必要もない。 (「XX側」といった構造が適切かどうかは検討の余地がある)

とはいえ、現実的にはデプロイ=リリースを意味することが多いので、分離する方法を探すことになる。

この分離のためには Feature Toggle がよく知られているかと思う*2。 特定の機能を無効にしたままリリースできるトグルを実装してしまう方法。

Feature toggle をちゃんとした仕組みとして、プロダクトや運用の性質にあわせていかに上手に設計するかがキーになるのだろうな。 仕組みがない状態で愚直にやり始めると if/else が散りばめられて、保守性の低下を招くことになりかねないし、そうでなくても普通に面倒。 トランクベース開発を可能にするくらいだとさらにその傾向が強くなりそうだ。

独立して適用できるか?

トランクベース開発や、デプロイとリリースの分離は、開発者個人からチーム全体へとコードの所有権を渡していって早期にフィードバックを得る方法のように思う。 そのフィードバックによって、コードを、ひいてはプロダクトを良くしていくことができるんだろう。

そうすると、冒頭の master マージのハードル解消とは独立したメリットがあるプラクティスとして考えることができる。 なのでそういう課題感がなくてもやってもいいんだけど、CI/CDがうまく回っている状態でなければこれらの実現は難しいように思う。 相互補完的な立ち位置にあるのではないだろうか。

とはいえ、できる範囲で部分的に適用していくのは大賛成。 あとはニーズとコストとの綱引きになるのかな。

*1:継続的デリバリ読めば書いてあるかもしれないけど、まだ読んでないのでこの思考自体無駄かもしれない

*2:というか僕はもともとはこれについて考えていたんだった。大脱線というか、逆さまに考えだしたというか

macOS で自作キーボードからジョブカン打刻

様子

用意するもの

jobcan_slack_electron

  • Electron 製自作ツール
  • ジョブカンを Slack 連携させると使えるようになるスラッシュコマンド (/jobcan_touch) を、 Slack API 経由で実行
  • レガシートークンが必要、かつコマンド実行のための command.chat APIは非公開なのでそのうち使えなくなるかもしれない…
    • ジョブカンが API を提供していないのでこうするのが一番楽そう
    • スクレイピングはつらい
  • オマケ機能で出勤、退勤時に好きな画像をランダムで表示してくれる

打刻用ショートカットを登録

macOS のショートカットキー設定ではアプリケーションを直接登録することができないので、 Automator でサービスを作ってからショートカットキーとして設定する。

  • jobcan_slack_electron をパスの通った場所に配置
  • Automator を起動

f:id:upinetree:20200301151649p:plain
Spotlight から探すと楽

  • 「ファイル」→「新規」→「クイックアクション」
  • 「アプリケーションを起動」アクションを追加して、起動アプリケーションに jobcan_slack_electron を選択

f:id:upinetree:20200301151755p:plain
設定が完了した様子

  • 保存(ここでは jobcan_touch という名前を設定)して終了
  • macOS の「システム環境設定」→「キーボード」→「ショートカット」→「サービス」に先程保存したクイックアクションのサービスが出現しているはずなので、好きなショートカットキーを設定する。このあとキーボードの専用キーに登録するショートカットになるので、誤爆しないよう複雑なものにすると良い

f:id:upinetree:20200301151849p:plain
jobcan_touch サービスをショートカットキーとして登録

  • 上記で設定したショートカットキーを自作キーボードから叩くために、QMKのキー設定を書く。以下は meishi の例で、誤爆防止のため One Shot Layer 機能を使っている
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  [0] = LAYOUT(
    XXXXXXX, XXXXXXX, XXXXXXX, OSL(1) \
  ),
  [1] = LAYOUT(
    HYPR(KC_BSLASH), XXXXXXX, XXXXXXX, XXXXXXX \
  ),
};
  • QMKの設定をファームウェアに焼いたら完成。設定したキーを入力すれば、ジョブカン打刻ができるようなった! 🎉

おまけ: Electron Fiddle でアプリを初めて作った感想

  • 最小限のElectronアプリをシュッと作れて良い体験だった
    • ただ、本当に最小限で、 main.js, render.js, index.html しか編集できない
    • require() を書くだけで自動的にモジュールがインストール、補完なども有効になる
    • 保存すれば普通の Electron プロジェクトなので、普通の開発フローに乗せられる
  • ボイラープレートの作成から、ビルド、実行、パッケージ化がワンタッチでできる
    • Gist への Save/Load もワンタッチ
  • Gist からリポジトリ化する際には、以下の対応を行った。らくちん
    • electron-builder の導入と設定
    • GitHub Actions でのビルド自動化

できる! mathn 脱却

この記事は STORES.jp Advent Calendar 2019 の 6 日目の記事です。

STORES.jp のバックエンド基盤チームでは、絶賛 Ruby のバージョンアップを進行中です。Ruby のバージョンアップはコード全体に影響を及ぼすため毎回一大イベントなのですが、本記事ではその中でも特に過酷だった事例を紹介します。それは「いつの間にか依存していた mathn を取り除かないと Ruby のバージョンを上げられない」というものでした。

mathn とは

Ruby 2.4 まで標準添付されていたライブラリで、数値ライブラリの挙動をグローバルに変更するものです。以下のように mathn の require の有無によってグローバルに計算結果が変わります。

1/2                #=> 0
2 * Rational(1,2)  #=> Rational(1,1)

require 'mathn'
1/2                #=> Rational(1,2)
2 * Rational(1,2)  #=> 1 (Fixnum)

Ruby 2.2 では Deprecated warning が表示されるようになり、Ruby 2.5 では外部ライブラリとして切り出されました。そのため完全なドキュメントは Ruby 2.1 のものが最後となっています。

https://docs.ruby-lang.org/ja/2.1.0/library/mathn.html

上記ドキュメントから引用すると、 mathn を require することにより以下の挙動が変化するようです。なかなかにダイナミックなモジュールですね。

  • 整数の除算が割り切れない場合、 Rational オブジェクトを返すようになります。
  • 複素数有理数の演算結果が実数や整数に収まる場合、 Float オブジェクトや Integer オブジェクトを返します。
  • Math モジュールの数学関数の定義域と終域を、実数のみから複素数へと拡大します。

いつの間にか mathn に依存していた

mathn は数値計算を行うようなスクリプトなど、使い所によっては便利なモジュールです。ただ、Ruby の標準の動作を上書きし、あらゆる計算結果に影響を及ぼすので、混乱を招く面があります。そのため、Web アプリケーションやライブラリで読み込むようなことはオススメできません。

しかし、思いもよらぬことは起こるものです。 stylish という gem が require 'mathn' していて、それが Rails アプリケーションから読み込まれていたのです。つまり、この Rails アプリケーションでは、気付かぬうちに計算の挙動がグローバルに上書きされてしまっていました。その事実に気づいたのは stylish が入ってから数年後で、その頃にはすでに mathn を前提とした計算がコードベースに深く浸透していたのでした。

基本的には誤差が無くなる方向に作用するものなので、混乱を招く以外に実害はありませんでした。また、広範囲に影響していることから、 mathn を取り除くコストとリスクを踏まえて対応を先送りしていました。しかし、Ruby 2.5 にアップデートするときに、この問題が顕在化したのです。

Ruby 2.5 では、前述の通り mathn は外部ライブラリとして切り出されています。そのためアップデートにあたっては、ひとまず Gemfile に(外部ライブラリとして切り出された) mathn を記述して回避しようと考えていました。しかし実際に Ruby 2.5 に上げてみると、 mathn が原因で segfault するケースがあることがわかりました。

$ ruby -r mathn 'Time.at(1.1).to_s'
-e:1: [BUG] Segmentation fault at 0x0000080000000001
...

mathn はすでに deprecated なライブラリで、修正は期待できません。つまり、Ruby 2.5 にアップデートするためには mathn から脱却しなければならないということです。アップデートしないという選択肢はもちろんありませんよね。

入り込んだ mathn を取り除くためにやったこと

mathn 前提の計算はコードベースに無数に存在し、影響範囲は検討がつきません。それでも mathn を取り除かないと Ruby をアップデートできないので、なんとか工夫を考えました。

mathn による動作変更の理解を深める

まずは mathn が何をしているのかをよく知る必要があるので、コードリーディングをしました。 Ruby 部分はシンプルな実装なので難なく把握できました。

一方で C 拡張部分はなかなか複雑で、ドキュメントに書いてあった動作と照らし合わせながら、仕組みと影響範囲を理解することに努めました。 canonicalization 変数の作用を起点に見て回っていた記憶があります。たとえば ここ とか ここ とかから掘っていきました。

結果として以下のメソッドに影響がありそうだということがわかりました(網羅できてはいないが、あたりを付けるところまでをゴールとした)。

  • Xxx#to_r
  • Date#-
  • Date#ajd
  • Date#amjd
  • Date#marshal_load
  • Date#day_fraction
  • DateTime#-

影響調査範囲を絞り込む

mathn の影響箇所を人力で漏れなく洗い出すのは現実的ではありません。アプリケーションコードだけではなく、依存するライブラリ内部の計算結果にも影響するので、そこまで考慮するのはより一層難しくなります。

なので、ある程度網羅性を緩めた条件を設定することにしました。以下のように、アプリケーションの「出口」のみに焦点を当てるような仮定を設けました。

  • ライブラリ内部では通常は mathn がないことが前提になっているので、精度を求める場面では明示的に考慮するはず
  • Rational/Complex の自動丸めがなくなることは精度を低下させるような影響はないので、処理の途中の計算では問題ない
  • 出口であるリクエストやレスポンスの生成で顕在化した差異をやっつければよい。例えば、自動丸めされなくなり Rational が String に変換されて 3/1  のようになると困る

以上を前提とすると、次の方針が立てられます。

  • Rational を返すメソッド呼び出しを洗い出し、アプリケーションの出口に影響するかを判断する
  • メソッド呼び出しの検知は TracePoint の  returnc_return  イベントを掴む
  • Rational が Integer になって困るケースを検知するため、 mathn 削除前に TracePoint を仕込んで CI で検証する
  • Integer に丸められていたのが Rational になって困るケースを検知するため、 mathn 削除後に TracePoint を仕込んで CI で検証する

TracePoint で Rational の存在を検知し、影響を判断する

以下のようなモジュール(厳密には使用したものとは違います)を用意して、アプリケーションコード中の Rational が返ってくるメソッド呼び出しを検知しました。

module RationalDetection
  class << self
    def enable
      return if @trace_point
      trace_point = create_trace
      trace_point.enable
      @trace_point = trace_point
      @oneshot_detections ||= {}
    end

    def disable
      return unless @trace_point
      @trace_point.disable
      @trace_point = nil
    end

    def save_oneshot_detections(version: nil)
      dir = Rails.root.join('tmp/artifacts')
      filename = dir.join(["rational_callers_#{mathn_enabled? ? 'with' : 'without'}_mathn", version].join('_') + '.txt')
      FileUtils.mkdir_p(dir)
      File.open(filename, 'w') { |f| f.puts(@oneshot_detections.keys) }
    end

    private

    def called_from_app?(path)
      ['app', 'lib', 'config'].any? { |dir| path.match?(Rails.root.join(dir).to_s) }
    end

    def rational_instance?(object)
      Kernel.instance_method(:class).bind(object).call == Rational
    end

    def mathn_enabled?
      $LOADED_FEATURES.grep(/mathn\.rb/).present?
    end

    def create_trace
      TracePoint.new(:return, :c_return) do |tp|
        next unless rational_instance?(tp.return_value)

        caller_index = tp.event == :c_return ? 0 : 1
        caller_path = caller[caller_index].rpartition(/:/).first
        next unless called_from_app?(caller_path)

        @oneshot_detections[caller_path] ||= true
      end
    end
  end
end
  • called_from_app? メソッドの呼び出しでは、ライブラリの内部での mathn の影響を前述の仮定のもとで無視しています
  • 一度だけ呼ばれていることを確認できれば良いので、 @oneshot_detections のハッシュでフラグ管理しています。そして CI の Artifact としてテスト終了後に書き出します
  • 戻り値が Rational かどうかの判定のために is_a? を使わずにわざわざ rational_instance? という怪しげなメソッドを定義しています。これは、BasicObject を継承していて method_missing が定義されているクラスは、 is_a? を呼び出した際に method_missing が呼ばれてしまい、その実装により誤検知もしくは例外を発生してしまうケースがあったためです。また、 defined? による判定も true になってしまうようでした( Ruby 2.7-preview1 で確認したときは false になっていたので、どこかで修正されたのかな)

このモジュールを RSpec の実行時に呼び出すようにして、

config.around(:example) do |example|
  RationalDetection.enable
  example.run
  RationalDetection.disable
end

config.after(:suite) do
  RationalDetection.save_oneshot_detections(version: Time.current.to_i.to_s)
end

CircleCI で mathn あり、なしの両方の条件で実行し、結果を Artifact として得ました。そして一つ一つ出口への影響有無を判断し、必要な修正を行いました。

TracePoint で検知できない範囲への対応

検知可能なのはテストで通る範囲のみとなるので、それ以外の部分についても影響がないことをできる限り確認したいところです。かといって TracePoint を本番で運用するのはパフォーマンスやリスク面で難しいものがあります。

そのため、事前の mathn のコードリーディングや TracePoint で検知した結果得られたパターンで再度 grep して横展開しました。

TracePoint 以外の選択肢?

  • AST だと評価結果が得られないので Rational を返すタイミングがわからない
  • ISeq は AST をコンパイルした命令列なので、やはりこれも評価結果を得られるわけじゃない

というわけで、戻り値を検出するという目的のためには TracePoint で実際の評価結果を知る必要がありそうでした(後学のため、他の方法があれば教えてもらえると助かります)。

まとめ

そんなこんなで mathn の脱却に成功し、 Ruby 2.5 へのアップデートも無事に完了したのでした! 🎊

あまり同じ事例に遭遇することはないとは思いますが、この事例から得られる教訓としてはこのあたりでしょうか。

  • gem を入れるときは、require したらどうなるかをしっかり確認する
    • 他の例として、過去の Whois gem がある。この gem は Rails の core_ext 部分をごっそりコピーしてきて自分で持っていたので、 Rails を新しくしても古いままのコードで動くことになっていた
    • https://github.com/weppos/whois/pull/317
    • (メンテナンスされていれば)バージョンを上げることで致命的な問題は解消することが多いので、そういった意味でも新しいバージョンに追従しておくのは大事
  • ライブラリを作るときはその影響範囲をできるだけ閉じておく。副作用がある場合、ドキュメントにわかりやすく記載する
  • テストをしっかり書いてあると救われる(なかったらと考えるとゾッとする 😂 )

新婚旅行でフロリダのディズニーワールドに行ってきた

2019/9/11 ~ 9/18 の6泊8日で、アメリカのフロリダ州ウォルト・ディズニー・ワールドWDW)に行ってきた。

アメリカ、初WDWだったこともあり、記憶が新鮮なうちに感じたこと思ったことをまとめておく。

…と書き始めた頃は思っていたが、ダラダラしていたらすでに1ヶ月近く経過してしまった 🙈

まだまだ書けることはあると思うが、一旦ここまでにして、思い出したら都度追記していこうと思う。

旅程

移動は羽田発トロント経由オーランド着(帰りはその逆)。カナダを経由するのでETAの申請をしたのが多少面倒だった(システム障害のせいか、何度申請しても最初からやり直しになってつらかった)。

深夜に移動したり、空港での待ち時間が多いスケジュールだった。転職というイベントもあって準備時間の節約のためにHISに依頼したが、正直この判断は間違いだった(後述する)。

とまあ色々大変だった面はあれど、旅行自体はめっちゃ楽しかった。現地の人に毎年来てと言われたが、お金と時間さえ許せば本当に毎年行きたいと思えるほどだった。

アメリカ(フロリダ)について感じたこと

あくまでフロリダ、ディズニーという母集団に対する個人的な印象。感じたことをつれづれと書き残しておく。

  • バリアフリー先進国
    • 設備はもちろんのこと、実際にそれが頻繁に利用されている。車椅子の方が多く外出していて、自然に受け入れられている
  • 大人は見た目イカツイので一見怖いけど、なんだかんだ親切にしてくれる
    • 関わった人みんな良い人だった
    • 肥満の人が思った以上に多い。男性は肥満かマッチョかといった印象…
    • 子供が天使
  • 食事が口に合わなかった
    • 基本的に塩気が強く旨味が少ない
    • デザートで参ったのはクリーム。ジャリジャリして砂糖感が強く、科学的な風味がする
    • 高いレストランでは普通に美味しかったが、外国人向けに調整されているのかも?
  • 水が合わなかった
    • 鉱物の影響か、独特の臭さがある
    • 手荒れがひどくて痛くなり、常に保湿クリーム塗ってた
    • シャワーで髪もギシギシ
  • 日差しが強い
    • サングラスを常につけていた
    • 日焼け止めのANESSAがめちゃくちゃ効いてほぼダメージなし。すごい
  • 雨がよく降る
    • いわゆるスコールで、すぐ止む
    • 現地の人は慣れているのか雨を全く気にしない。すごい
  • コミュニケーションの違い
    • 「How are you (doing)」 ってほぼ最初に聞かれるに慣れずに毎回怯む。とりあえずキョドりつつ good とか答えてたけど、ネイティブはどういう返しをするんだろ
    • とにかく褒める。肯定する。子供は自立させて何でもやらせる。周囲も含めて寛容さがあるのかもしれない
    • ちょっとしたことでも声をよくかけてコミュニケーションする。個人的な経験上、日本ではお互い黙って勝手にピリピリする場面がよくあるなあと思っているが、一言言えば済むことも多いので見習おうと思った
    • (蛇足)それぞれの文化圏ではそれぞれの集合体が生き残るために築いたコンテキストがあり、良いところも悪いところもある。なるだけ良いと思ったところを取り入れていきたい。長年生きてきた上でのアンラーニングは難しいが、定期的に他の文化圏に行くことで自分のコンテキストを認識する機会を作るのは良いことだなと思った
  • エアコン冷やしすぎ。上着がないとつらい場面もあった
  • レストランでのカードでの支払い手順が面倒(チップのせい)
    • あらかじめ調べておくとスムーズ
  • シャワーのお湯の出し方は服を脱ぐ前に確認すべし。初見ではまじでわからん仕組みのものがあるので、裸で試行錯誤するのはつらすぎる。なお、高いホテルだと分かりやすい仕組みのシャワーが付いてた

ディズニーワールド

  • 規模がおかしい
    • 東京ディズニーランドが5つくらいある感じ。ホテルやその他施設を含めれば、ひとつの都市(むしろウォルト王国)と言っても良いくらい
    • ホテルの数も多く、それぞれめちゃ広い。クオリティは課金次第だが、外装や庭、プールなどのこだわりは廉価帯のホテルでもかなり高い
    • 毎日そこかしこで花火が上がっている。消費量やばそう
    • ほぼ物販だけのパーク?がある (Springs)。だいたいここで揃う。グッズの種類に驚愕。グッズはマイナーなキャラのものもあるのでマイナーキャラ好きの妻もニッコリ。服も揃っていて、なかでもTシャツの種類がすごい
  • とにかくUXがよい
    • リアル、ウェブ、アプリの連携がスムーズ。ウェブで計画・予約し、アプリを見て行動し、リアルで楽しみ、結果がアプリにフィードバックされる。アプリ取得必須
    • マジックバンド考えたひと天才
      • パークへの入場、ファストパスの使用、決済、ホテルへのチェックイン、ルームキー、フォトパスの本人確認などがマジックバンド1つあればできる
      • 1段上のセキュリティが求められる場面では、ちゃんと指紋と合わせて二要素認証される
      • カスタマイズ(課金)要素もあり、自分の好きなデザイン、使用感にできる
      • 好きなデザインにしたければ、事前にウェブで指定しておく。日替わりでデザインが変わるのでガチャっぽい
    • フォトパスすばらしい
      • パーク内外にカメラマンがいて、写真を撮ってくれるシステム。思っていた以上の数のフォトパススポットがあって、行く先々で撮ってもらった。枚数でいえば200枚ほど
      • マジックバンドで本人確認して、撮ってもらった写真はアカウントに紐付けられたクラウドストレージにアップされる。そしてアプリですぐ確認できる(タイムラグが発生する場合もあるが)
      • 特定のポーズに対応した効果やアニメーションが付与される場合もあってたのしい
      • 課金要素ではあるが、必須。事前に予約すると安くなる
    • ホテルは自動チェックアウト。時間になるとマジックバンド購入分のレシートがメールで届く
    • セルフのドリンクサーバー用で、一度買ったら何度でもリフィル可能なマグがあって便利。RFIDで購入済みかチェックしているようだった。RFIDが反応しなくなることがあって、レジの人に相談したら登録し直してくれて復活した
  • 園内の様子
    • 入場の際の荷物検査が厳重で隅々まで見られる。検査員はだいたいイカツイけど、気さくに話しかけてきてくれる
    • 家族連れが多い。3代で来ていたりする。日本人はハネムーンの人をよく見かけた
    • アバターのアトラクションめちゃ楽しかった。あとアナ雪のレリゴーを合唱するショーはテンション爆あげの方たちの歓声がたのしかった
    • ことあるごとに歓声が上がる。テンション上がり切るとショーの前にウェーブが起こったりする(たのしい)
    • スターウォーズエリアの作り込みがすごいので、ファンはぜひ。ショーも頻繁で、ベイダー卿が子供たちにフォースの使い方を教えてたりする
    • ハロウィンイベント(要課金)の日本にはない盛り上がり。DJがアゲアゲの曲流してる中みんな酒飲みながらキャラクターと一緒に踊ってたりする
    • イベントに応じたバッジがもらえる。はじめて行くとか、誕生日とか、ハネムーンとか、お祝い事があるなら、キャストに言うと良い
  • キャスト(従業員)の多様性が印象的だった
    • 老若男女、多人種なのはもちろん、車椅子で働いている方もいた
    • 日本からの大学生インターンを多数受け入れている模様。半年くらい滞在するんですよ~と話を聞いて羨ましいねと話していた。大変そうではあるが、英語でのコミュニケーションの練習にもなってよさそう
  • バス、モノレール、船、(+新しくできるSkyline)と、移動手段が豊富
  • 滞在期間中のホテルの移動には luggedge transportation が便利(チップ発生)
  • グランドフロリディアン(ホテル)にはマジックキングダムの花火を見るための開けたスペースがあった。スピーカーも設置されてて、花火のショーの音楽も聴けた。富裕層のための特等席という感じだった…
  • お土産に向いた個包装でたくさん入ってるお菓子があまりない。そして日本人の口には合わなそう…結局お菓子は経由地のカナダで買った

振り返り

持っていって良かったもの

  • GoPro持って行ってとてもよかった。旅の雰囲気とか、夫婦で実況する感じで残せた。購入も検討している。レンティオでレンタルしたが、注文から返却までストレスフリーだった。すばらしや
    • GoProの長いマウントはパーク内への持ち込み時に注意された(畳んでいるならいいけど展開すると没収されるよ、みたいな話)ので、短い棒で行くのが良い
    • オリジナルの動画は結構サイズ大きいので、S3 Glacier Deep Archive で保管することにした。参照しなければ 1 GB あたり月額 0.00099 USD で済む。50 GB なら月 5 円くらい
  • 休息時間という湿布が良くきいた。普通の湿布だと妻は肌に合わないのだが、これは問題なし。持ってく量が少なすぎたので今度遠出するときは増やしていきたい
  • 蒸気でホットアイマスクという製品がよかった。袋開けるだけなので機内でも使えてホッとできる。というか目を駆使する仕事なので普段から使えるわ
  • のどぬ~るぬれマスク。機内は乾燥するので、これつけておくと快適に寝られる
  • ユンケル黄帝顆粒。毎日一日中歩きまわるので、体力回復が課題。顆粒はかさばらなくてよい。持ってく数が少なかったので今度は増やしてみたい
  • 小さな包装の除菌ティッシュ。なんだかんだ使うシーンが多い
  • 酔止め。アトラクションは苦手だけど、せっかくなので乗りたいという人におすすめ(妻がそうだった)
  • 虫除け。ディズニーワールドは自然が豊富で水場が多いので、必須といえる
  • サングラス。快適に行動するために必須。せっかくなのでグッズを買っても良い
  • 日焼け止めのANESSA。マジで効く
  • ビタミンCのサプリメント。シャワーで髪がギシギシになる対策として、サーファーの美容師に妻が教えてもらったらしい。直接カプセルをあけて塗り込む。根拠はよくわからないけど、髪の調子は結構よかったようだ
  • レインポンチョ。スコール対策。行動時に荷物になるデメリットはあるので、濡れる覚悟ができていれば不要(でも風邪をひいたら悔やみきれないので、今回は万全の体制で臨んだ)。夏なら半袖短パンで水着を下に着ていれば良さそうではある。それでもエアコンの冷え対策は必要か
  • 防水かばん。同上の理由。ノーティアムのこれが動きやすくて良かった
  • 洗剤。ホテル内にコインランドリーがあり、そこで使える(洗剤も買えるが、馴染みのものを買っていくと良い)。なお、コインランドリーはマジックバンドが使えず、クレカ決済になるので注意

やっておいてよかったこと

だいたい妻がやってくれたものだが

  • ファストパス取得
    • 結構前からできるので、早めの行動がよい。人気のものは割とすぐに埋まってしまう
  • レストラン予約(キャラクターダイニングとか)
    • これも人気のものはすぐに埋まる
  • 以上のスケジュール表、やりたいこと・行きたい場所リスト作成
    • 妻が旅のしおりを作ってくれて、スケジュールやお土産リスト、持ち物などの確認がしやすかった。事前にワクワクする効果もあり
  • フォトパスの事前予約(安くなる)
  • ガイドブックの熟読と行動順の整理
  • マジックバンドガチャ
    • 悩んだ挙げ句最終的には単色にしてしまった
    • 選ぶのはたのしかった

HISを利用して後悔したこと

  • 6泊8日なので丸6日は行動できます、という説明のプランだった
  • 妻は海外旅行初めてだし、時差とかきついので余裕のある旅程にしてとリクエストした
  • しかし出発1ヶ月前に確定した旅程は遅く出発し、早く帰るというもの。睡眠時間を考慮すると4.5日しか行動できない。ホテルやチケットも6日分のものになっているのにその価値を消費しきれなかった
  • どうやら、契約したプランの可変時間帯のギリギリを提示されたらしい。なのでプラン自体は契約通り。とはいえその説明はなかったし、事前に余裕を持って行動したいと伝えているのに他のプランを提示しないというのは、旅行代理店に期待する価値を大きく満たせていないと感じた
  • 有料での延長も価格交渉も受け付けられないとの支店長判断にがっかり
  • それ以外にも担当者が催促するまで連絡よこさないとか、請求書に誤りがあるとか、名前を何度も間違うとか、色々おかしかった
  • 逆にこれらのやりとりで時間を取られてしまった。WDWに行くというくらいの目的なら複雑な旅程でもないし、大金を払って無駄な時間を費やすくらいなら、最初から全部自分でやればよかった
  • 一方で現地スタッフの存在は心強かった。はじめて行く地ということもあり、色々ガイドしてくれたのがよかった。ただ、他の旅行代理店でもそういうサービスはあるし、直接依頼するということもできるので、それが決定的な価値になるというわけではない
  • 総じて、もう利用することはないな、という結論になった

その他

  • WDW目的なら現金はもっと少なくていい。だいたいマジックバンドでなんとかなる。WDWの外でもクレジットカードだけで大丈夫。チップでまれに現金が必要になる
  • 体力不足、体力の過信、体調管理。疲労によりショーを断念することになった(翌日にリベンジできてよかったが)
  • 英会話の準備不足…全然話せなくなってる。色んなとこで雑談チャンス発生してたのに全然対応できなくて悔しかった。妻は英会話苦手なのに果敢に挑戦しててえらかった。チキンな私には真似できない

まとめ

もともと私自身そこまでディズニーのファンではないのだけど、今でも2日に1回フロリダが恋しくなるくらいに楽しかったのでみんなもっと行くといいと思うよ(長時間の飛行機のつらさと、お金と休暇がなかなか捻出できないという現実が立ちはだかる…)。

あと、密かに目標にしていた「ケンカしない」というのを達成できたので、新婚旅行としては大成功だった。

事前の入念な調査と準備、持ち物の整理をしてくれた妻に感謝である(妻の荷物の多さを小馬鹿にしていたが、結果として助けられたのである。すまんかった)。

転職しました(5年ぶり2回め)

Diff

- 万葉
+ STORES.jp

なんで

  • ずっと受託開発をやってきて、そこそこお客さんに価値を提供できるようになってきた
  • 一方で自分のキャリア上に運用経験がないことがずっと心に引っかかっていて、自分(たち)の製品・サービスに主体的に関わってみたいと思った
  • また、サービスに愛着を持ってなんやかんや試行錯誤したりといったこともしてみたかった
  • というか、そういった経験もなしに受託開発を続けても、心理的・技術的に提供できる価値に限界があると考えた
  • 受託開発ではこのあたりに踏み込むのが難しくて、組織とか権限とか情報とかにおいてたくさんの制約がある。そういう構造があるのは当然というか妥当で、その中でWin-Winになる範囲で踏み込む努力もしたが、自分にはどうしても器用にできず難しかった
  • そんなこんなでゆるゆる1年前くらいから転職を意識していた
  • STORES.jp はエージェントさんに紹介してもらって、細く長くコンタクトをとっていくうちにたのしそうだなーという感覚を持っていった
  • 明るく前向きにやっていくぞという雰囲気で、かといってキラキラでもなく。エンジニアも向上心があって、かといってムキムキマッチョでもなく。といったところが結構合うなと思った
  • みんな STORES.jp というサービスが好きで、自分もサービスに愛着を持っていけるかなという感じがした(そして実際そういう魅力のあるサービスである)
  • 条件面に関しても交渉の中でかなり配慮していただいてありがたい限り

おきもち

やっていくぞーという感じです。

万葉には大変お世話になって、感謝の気持ちが尽きない。 万葉のおかげでWebアプリケーションエンジニアとして一人前になれたし、リーダー業務だったり執筆だったりと、いろいろな経験の機会をいただけた。あと妻にも出会った。 なので、申し訳なさとか、さびしさもある。 しかしここは次のステップに進むと自分で選択したのでがんばろう。

実はSTORES.jpにはちょっと前から不定期にアルバイトで入っていて、正社員としては今日からとなる。 マインドの切り替えとか、情報量の多さへの慣れとかまだまだで、ちょっと疲労もたまりがちなのだけど(風邪引いたり)、まずは体調優先で着実にスタートしていきたい。

直近の心配は、万葉の7時間勤務に慣れきっていて勤務時間ショートしないかなというところ…。

これからも相変わらず Ruby, Rails をメインでやっていくし、各種カンファレンスにも顔を出すのでよろしくおねがいします。 あと、恵比寿に通っているので、近辺の方はゆるっとランチとか飲みとかいきましょー。

例のリスト

http://amzn.asia/0Ly1XAG

Ergo42 Towel を作った

遊舎工房さんの実店舗でキットを購入。meishiを除けば最初の自作キーボードだったので、作りやすそうで、コンパクトだけどある程度キー数があるスプリットキーボードという点で選定。

構成

  • キースイッチ
    • Gateron Silent Brown * 56
  • キーキャップ
    • MDA Big Bang セット

ログ

f:id:upinetree:20190505103522j:plain

ダイオードのはんだ付けが完了したところ。付属のアクリル脚の幅が曲げるのにちょうどよかったので、簡易的なリードベンダーとして利用してみた…が、雑に行ったせいで仕上がりはそんなにきれいではない。

f:id:upinetree:20190506121821j:plain

キースイッチのはんだ付けが終わったところ。ケースの組み立て前にそれぞれのスイッチをテスタで導通確認し、ファームウェア書き込んで動作確認。

f:id:upinetree:20190506235112j:plain

ケースを取り付けてキーキャップを乗せたところ。これで完成!

と思いきや、ここからが長かった。

キーマップ

せっかくなので親指を酷使できる配列にしたいとか、キー数が少ない中で効率的な記号配置をしたいとか、でも慣れるのに時間のかかる配置は避けたいとか、キーマップにはいろいろと悩んだ。

ファームウェアを書き込んで実際に触ってみると、普段のユースケースではつらい場合があることもわかったり、なるほどこれがキーマップ沼かと実感。慣らしつつ少しずつ育てていくのがまたひとつの楽しみなのだろう。

とりあえず今のところは以下の配置にしてみている(すでに上記の写真とは違う)。

f:id:upinetree:20190512221730p:plain

感想

  • 親指を酷使する配列は指の移動が減って小指が快適
  • 慣れるまでが大変そう。格子配列もまだTypoしまくるし、すべてのキーが同じ大きさなので指先の感覚が今までと違う
  • MDAキーキャップだと高さ(とくに最下段)が合わなくてガタガタになる。DSAとかを買い増しかしら…
  • Pro Micro の microUSB 端子がもげやすいと聞いて用意したZrseのマグネット式ケーブルが便利だった。端子部分を余分に用意しておくとファームウェア書き換えのときに差し替えがらくちん
  • 持ち運び用のいい感じの入れ物がほしい

meishi キットで自作キーボードに入門した

自作キーボードが作りたくて遊舎工房さんに行った。 yushakobo.jp

Ergo42 Towelmeishi キット を購入。 買うときにいろいろと教えてくれたり、こちらのふわっとした相談に乗ってくれたりしてありがたかった 🙏

meishi キットは練習用に買ってみた。 ハンダ付けとか10年くらいやってないし、いきなり作り始めるのも危険そうだったので…。

小さなキットでもキーボードに必要な最低限の要素が詰め込まれていて、入門用として最適だった。 案の定つまづくこともあって、作っといてよかったなーと思った。

f:id:upinetree:20190413233859j:plain
完成したmeishi

キースイッチは、左から

色々試せて楽しい。

Pro Micro の MicroUSB 端子はもげやすいという噂を聞いたので、マグネット式のケーブルも買った。

キーマッピングは今のところ何が便利か思い浮かばず、とりあえず Slate で割り当てていたウィンドウ切り替えに対応させてみた。

便利…か?

https://docs.qmk.fm/#/keycodes あたりを見て、 qmk_firmwarekeyboards/meishi/keymaps/default/keymap.c を変更してファームウェアをビルド&書き込み。 お手軽。

さあ次は Ergo 42 Towel を作っていくぞー。