まっしろけっけ

めもてきなやーつ

1on1 をやってる(やる)話

はじめに

minne では CTL と各エンジニアで 1on1 を月一でやってるんですが僕は少し前まで web 側の CTL をやっていたので web アプリケーションの開発を行うソフトウェアエンジニアの各位と 1on1 やっていたんですよ。

で下記のような事件があったんで web 側とかなくなってただの CTL として生き始めたのでモバイルエンジニアとの 1on1 もやり始めるぞい < イマココ

hisaichi5518.hatenablog.jp

1on1 の目的とか

だいたい下記のスライドに書いてあって新しく入社した人にも下記のスライドがやる目的です〜って共有している(ひさいちくん便利)

speakerdeck.com

これからの話

モバイルエンジニアの人々はひさいちくんと 1on1 をやっていたのでモバイルエンジニアの各位が将来に対してどんなビジョンを描いているか?とか細かいことは知らないのでとりあえず教えて貰いたいなと思って下記のような文章を用意した。


モバイルエンジニアの人々(mataku 以外)は shiro16 と 1on1 をするのは初になります。
1on1 によって皆さんがエンジニアとして成長するための手助けをしたいと考えているので、まずは皆さんがどのような目標を持っているのか?を教えて貰いたいと思います。

1on1 ではその目標に最短で辿り着くために今抱えている課題に対してどうアプローチすればいいか?という内省が出来るようにサポートできればと考えています。

【質問】(短期的/長期的どちらでも)エンジニアとしてどうなりたいか明確なビジョンがある場合はそのビジョンを明確ではない場合はざっくりとしたビジョンでもいいので書いてください

例1) shiro16 倒す
例2) シニアになる
例3) なんかよくわからんけどとりあえず凄くなる
その他...

モバイルエンジニア向けの文章になっているけど、web の人々も同じようなことをもう一度問う予定

なぜこのようなやり方をやろうと思ったか?

ペパボにはエンジニア職位制度というものがあり上位の職位には誰でも立候補が出来たりするんですが、ちょうどその時期でシニアエンジニアとして相応しいかどうか?は CTL みんなと面談して決めると言うことになっておりその面談を通して思うことがあってという感じ。

思うことというのは 1on1 をやっている中でエンジニアとして明確な目標を持って 1on1 に望む人はその目標に近づくためにどうすべきか?ということに悩んでいたりするんだけれど、僕が少しサポートをするだけでこんなに変わるのかと思うくらい振る舞いがとてもよくなったという経験があったのでビジョンを持ってそこを目指してもらおうと思った。

ぼんやりとしたビジョンしかないという人に関しては 1on1 を通してぼんやりとしたビジョンをより明確にするサポートをしていければと思っている

最後に

1on1 の話とは関係ないんだけど僕自身も上の職位を目指す上で現シニアプリンシパルの人々とは専門とする領域が違っていてその領域が好きだからもっとやっていきたいと思っているのだけれど、
その領域の違いの明確な言語化とその上でその違いを伸ばす努力をせんとな〜といい刺激を受けた期間だった。

GW にやったことをメモ

はじめに

だいたい大型連休は "どこか出かけるか〜?" となった後に "連休で混んでるときにわざわざ出かける意味とは...?" となって結局出かけないというとこに着地する。

で、何をやっているか?というと下記な感じになる。

  • ジム行く
  • 可愛い愛犬の散歩行く
  • 可愛い愛犬とゴロゴロする
  • 技術書読む
  • ゲームをする

だいたい技術書読んで飽きたらゲームして疲れたら技術書読んで〜をループして合間に他のことをする感じで生活していた

今回の GW にどんな技術書を呼んだか?をメモっておくだけの記事

読んだ技術書

プログラマのためのDocker教科書 第2版

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化

GW 前半に読んだのがコレ

完全に雰囲気で Docker を使っていたので、ちゃんと学んでみるか〜となって読んで見た。
読んでみたのだが雰囲気で使ってたことがほぼ当たってたのでfmfmと確認になったという結果になったが自分の使い方が間違ってなかったのだなぁとなってよかった。

最後に kubernetes のざっくりとした説明が載っていてそこはこのあと読んだ本のこともあり為になった。
Docker 良くわからんという人にはとてもオススメだと思う。

入門 Kubernetes

入門 Kubernetes

入門 Kubernetes

GW 後半に読んだのがコレ

最近話題の k8s についてマイクロサービスとの相性も良いとのことなのと社でも k8s 使って何かが行われようとしているっぽい雰囲気なので触っておこうという感じで読んだ。

minikube を使って環境作ってひたすら yaml を書き kubectl を駆使してアレコレした。
ちょうど今マイクロサービス化を進める上でめんどくさいなぁと感じていた部分の大半が k8s 使えばいい感じになるんじゃね?という感じに思えてきたので、早く導入したい!!1という気持ちになった。
書の中には若干不親切では?という箇所がいくつかあったのが気になったが k8s を理解するにはとても良いのでは?

エンジニアリング組織論への招待

入門 Kubernetes 読み終わった後に読み始めた。

なんかいいらしいとの噂を聞いていたので買っていたけど積んでたやつ

まだ読了してないので感想は特になしという感じ

最後に

今回は珍しく映画でも見に行くか〜と予約せずに渋谷に TOHO まで歩いたもののダルいなってなって昼飯だけ食べて帰ってくるという事件があった。

Rails Developers Meetup 2018: Day 2 で minne での CM 対応でのハイブリッドクラウド運用という話をした。 #railsdm

はじめに

Rails Developers Meetup 2018 こちらのイベントの登壇のお誘いが @kenchan があり話すということが決まったのが昨年の末とかだった記憶

話す内容を考えていたのだけれど、Elasticsearch 周りの話とかオンラインで全テーブルの DB の文字コードを変えた話とかその他色々考えたんだけど、被りそうなのと 30 分枠だと長すぎるか〜という感じだったのであまり聞いたことがなくちょうど年末くらいにやっていたハイブリッドクラウドを絡めた CM 対応の話をするか〜となった。

資料はこちら

speakerdeck.com

Rails のコード 3 行しかないので Rails Developers Meetup #とは となるような内容で、自分が主に担当した部分を多めに事例を紹介しました。
もう少し流れがスムーズになるように資料作れればよかったな〜というのと途中にちょっとしたトラブルがありアレだったという反省

AWS + Nyah 環境というのは社内でも珍しい構成でツラみとかもあるので気になる人はなんか聞いてください。

最後に

次喋る機会があるならちゃんと Rails の話をしたいね!

資料には含めなかったアレです。
pepabo.com

GraphQL の spec に関してアレコレ考えている

はじめに

最近 GraphQL を本格的に使い始めるぞいとなってんですよ。
経緯は下記参照

それでいくつか filed とか定義してデータ取れるようにしつつ rspec で test 書いててう〜むとなったので自分の考えをまとめて世の知見を知りたいとなったという経緯

前提

環境はこんな感じ

  • Rails なアプリケーション
  • graphql-ruby
  • graphql-batch
  • graphql-guard

その1 request spec は書く必要ないのでは?

実際に呼ばれるのは HogeSchema.execute なので request spec では GraphQL API に対して execute に渡される引数周りのチェックをすれば良いと考えた。
expect(HogeSchema).to receive(:execute).with(hoge, hoge, hoge) くらいを引数のパターン分あると良さそう。

何故ならば実際のクエリ書いてテストしていくとネストの深い巨大なクエリが出来上がって、
そのクエリの検証も辛いしレスポンスの json の検証もネストが深くなり辛いということになると考えたから。

実際に 4 種類ほどのデータ取れるようにしただけで辛いなって気持ちになったのでこの考えに至った。
ではどういうことをテストすれば安心を得られるだろうか?と考えた結果がその 2,3 になる

その2 GraphQL::ObjectType 毎に spec を書いていく

GraphQL で大事なのはそれぞれの GraphQL::ObjectType で定義された各スキーマ要素をチェックしていくと良さそう

どんな field が定義されているか?をチェックする。
PostType = GraphQL::ObjectType.define do
  name "Post"
  description "A blog post"
  field :id, !types.ID
  field :title, !types.String
  field :body, !types.String do
    guard ->(obj, args, ctx) { ... }
    resolve ->(obj, args, ctx) { ... }
  end
end

上記のような PostType があった場合は下記のようにチェックする。

describe PostType do
  subject { described_class.fields.keys }
  it { is_expected.to eq(["id", "title", "body"])
end

この他にも field 毎の型定義も想定した通りになっているかチェックしておきたい。
Ruby とかやってると型とかそんなに気にしないかもしれないけれど静的型付け言語がこの API を使うとなった場合はいい加減な型定義は出来ないのでちゃんとしておきたいという気持ち。

しかし一個一個書いていくのもダルいなと感じ他ので db のカラムのデータ型がそのまま field になっている場合が多いと考えるとある程度自動でチェックする仕組みは用意できそうなのでは?と考えたのでちょっとゴニョゴニョしようかなと考えている
db 以外の field はちゃんと個別チェックする。

graphql-guard の設定が正しいかをチェックする

これは README に書いてあるのだけれど下記のように呼び出せるので返り値を適切にチェックすると良さそう。

describe PostType do
  it do
    body = PostType.field_with_guard('body')
    expect(body.guard(obj, args, ctx)).to be_truthy
  end
resolve もチェックする

これも上記と同じようにチェックできる

describe PostType do
  it do
    expect(PostType.fields["body_url"].resolve(obj, args, ctx)).to eq("...")
  end

しかしこの方法だと resolve 内で graphql-batch の loader を使ってる場合にエラーが出るんでどうしたら...というのが悩み

その3 実際のクエリ書いてチェックする必要ってある?

その1 とも被る内容なのですが、その2 の spec をしっかり書いていれば schema の定義はしっかりと出来ているわけでその状態でデータ上手く取れない〜となった場合はクエリが悪いのだろうということになると考えられるからです。

それでも心配なら全スキーマを取ってくるクエリ書いてエラーでないねっていう程度はいいかもしれん(けど、factory bot でデータを用意するのすらだるい)

でも個別(field 毎)のエラーのチェックはクエリ投げないとダメなんかな〜という感じだが現状エラーが出るようなパターンを書いてないのでなんとも言えない

最後に

まだ本格的に使い始めて3,4日程度なのと通常の query のみで mutation に関しては全くという感じなので上に書いた考えは変わってくるかもしれない。

ペパボ社内で他に GraphQL を使っているサービスがあったので、どういう方針なんって聞きにいくついでに今の考えまとめようと思って雑に gist 書き出したらこういう考えに至った。
でそれを共有したらこんなこと考えてたんですよ〜とやまちゃんがナイスなブログを書いてくれて優秀な若者便利!!1となった

blog.kymmt.com

続:社内のテックミーティングでマイクロサービスの基本的なことについて喋った

はじめに

下記の記事で基本的なことを非エンジニアにもわかりやすく喋った。
で、次は下記の資料の課題をどうやって技術的に解決していくの?という部分を説明しなければいけなかったのでサラッと資料で説明したという経緯

shiro-16.hatenablog.com
× モノシリック
◯ モノリシック

資料

speakerdeck.com

具体的にこれ使うというのは記述してるけどその説明は口頭で説明したり、参考のページを紹介したりなどした。
あとは実際に導入するときに pull request にアレコレ書くのでそんな感じにした。

最後に

喋ったのは一週間くらい前なのだけれど slideshare に uploade できないマンと化してしまって...となっていたのでアップが遅れた。
もう speakerdeck にしよと思い立ったのでピッとアップしたという感じ

社内のテックミーティングでマイクロサービスの基本的なことについて喋った

はじめに

定期的に(?)開催されている minne のテックミーティングでマイクロサービ化を進める上で基本的なことをエンジニア以外の人にも知っておいて欲しかったので喋った。

資料

www.slideshare.net


基本的なことをエンジニア以外の人にも知っておいて欲しかったという前提があるので技術的に具体的にこういう風に〜というのは話さず概要をわかりやすく説明したつもり。

最後に

LT 5 分!という感じだったけど絶対終わらないんでという前置きをして 15 分喋った。
今回喋った内容はマイクロサービスアーキテクチャに載っている内容がほとんどです。

rspec-mail_matcher という gem を作った

経緯

仕事で開発している minne というサービスの Rails の version を 5.1.3 から 5.1.4 にあげようと雑に bundle update rails して見たら CI が通らんぞってなっていろいろ調べて行った結果。

CI が通らなくなった箇所

mailer の spec が落ちるようになっていた。具体的な内容はこんな感じ

it '本文に url が含まれること' do
  url = %r{http://example.com/?test1=1\&test2=2}
  expect(mail).to have_body_text(/#{url}/)
end

CI の結果を見ると本文に含まれる URL が http://example.com/test1=1test2=2 と & が消えた状態になってしまっていた(& が消えてることに気づかずにあってるやん!なんで!と二時間ほどハマったのは内緒)

原因の調査その 1

have_body_text という matcher は email-spec という gem で実装されている。

で email-spec を読むと #default_part_body という method から取得した文字列をメールの本文として扱っているので #default_part_body の結果が期待するものかとりあえず調べる。

it '本文に url が含まれること' do
  url = %r{http://example.com/?test1=1\&test2=2}
  binding.pry
  expect(mail).to have_body_text(/#{url}/)
end

spec を実行して止まったところで mail.default_part_body とやると確かに & が消えた状態になっている。


なるほどでは mail.html_part.body では?ということで実行して見ると & は & となっていて消えてはいない。なるほど〜 ここ の HTMLEntities の処理がおかしいっぽいぞというのがわかった

原因の調査その 2

その 1 で htmlentities がアレっぽいというのがわかったので処理を追っていくと ここ の処理で HTML 関連の文字列置き換えをしているぞというのがわかる。

prepare(source).gsub(@entity_regexp){
  binding.pry
  if $1 && codepoint = @map[$1]
    codepoint.chr(Encoding::UTF_8)
  elsif $2
    $2.to_i(10).chr(Encoding::UTF_8)
  elsif $3
    $3.to_i(16).chr(Encoding::UTF_8)
  else
    $&
  end
}

上記のように pry を追記して spec を実行して止まったところでそれぞれの違いを見て見た。

# 5.1.3
pry> prepare(source)
=> "......"
# 5.1.4
pry> prepare(source)
=> "......"

prepare(source) は差分なし

# 5.1.3
pry> $1
=> "amp"
#5.1.4
pry> $1
=> nil

なるほど〜、ということは String#gsub が ActiveSupport あたりで override されてるのか?という考えにたどり着く。
上記の pry 時に caller を実行すると activesupport/lib/active_support/core_ext/string/output_safety.rb が 5.1.4 だと追加されていることがわかる。
確証を得たいので下記で確認。

# 5.1.3
pry> prepare(source).class
=> String
pry> prepare(source).class.ancestors
=> [ActiveSupport::ToJsonWithActiveSupportEncoder,
 String,


#5.1.4
pry> prepare(source).class
=> String
pry> prepare(source).class.ancestors
=> [ActiveSupport::SafeBuffer,
 ActiveSupport::ToJsonWithActiveSupportEncoder,
 String,.....

なるほどね。ということで ActiveSupport::SafeBuffe が追加されたことで htmlentities の処理がうまく動かなくなってしまったことが原因だということが判明。

解決方法を考える

email-spec or htmlentities に PR 投げるか〜というのを最初考えてリポジトリ見たら 3 years ago とかの文字が並んでてなるほど...という感じになった。
それなら自分で作るか〜という気持ちになって今回作ったのでした。

email-spec との差

minne の spec を書き換えるのはダルいと思ったので基本的に matcher の method 名は email-spec に合わせる方向で設計したのだけれど、email-spec の default_part_body に関しては納得いかなくて html_part, text_part の順で取得されるのでこの仕様を知らないと have_body_text で text mail の本文をチェックしているはずなのに html mail の本文チェックしてて同じ記述があるから CI 通った(逆も然り)ということが起きそうなのがダメっぽいな〜という感じになった。

そこで have_body_text で text mail の body を have_body_html で html mail の body をチェックする matcher を定義して実装した。
しかし、現状の v0.1.2 だと 3,4 時間で雑に作ったので multipart? が false の際は雑に #body を使ってしまっているので次の version ではそこら辺の metcher を用意するか have_body_ でそれぞれチェックするかの処理を実装する予定

github.com

最後に

5.1.3 と 5.1.4 のソースの差分 ActiveSupport っぽいなというのはわかっていたけれど、どこがどう問題になっているのか調べて見るか〜と言った感じ。
だらだらと調査内容から書いたのはこのブログを PR に貼り付けて説明いらずにするためです。