マイ備忘録

あくまで個人の意見、メモです。

Algoliaのデバッグ

単なる作業メモ

携わってるシステムがAlgoliaを使って検索しているところがあって、そこでエラーとなるケースがあった。 デバッグする上でもAlgoliaのサーバとの通信内容を確認したかったので、Charlesを使って通信をプロキシすることに。

ローカルの開発環境はdockerなので、コンテナの中にCharlesのルート証明書をインストールして、コンテナ内からAlgoliaサーバへのcurlでのリクエストは通るようになった。 しかしAlgoliaのgemをインストールしたシステムはself signed certificateのエラーが出てプロキシできなかった。

仕方ないのでAlgoliaのgemのソースコードを見ていたところ、独自にルート証明書を持っていた。

github.com

これにCharlesのルート証明書を追加したらエラーがでなくなり、無事プロキシできた。

スクラムの相談してみた

スクラムやってての疑問を、著名なスクラムマスターの方に質問出来る機会がありました。 聞いた内容をメモに残しときます。

漠然と感じていること

スクラムってこんなんでいいんだっけ?

PJによってやり方はバラバラ。成果出ているなら今のやり方で継続してみよう

スクラムが凄くうまく回ってくるとどいうポジティブな作用がでてくるのだろうか?(チーム/プロダクト)

信頼関係ができ、それによるポジティブな作用が生まれてくる。例えば、

  • KPTのKEEPが相互感謝の嵐になる
  • 開発メンバーの意識が変わる。プロダクトの品質を自分ごととして考えられるようになる

スクラムイベントのファシリテートぐらいしかやってないけどいいんですかね?

ファシリーテートぐらいしかやってないよw

スクラムイベントに関連する物事のやり方

バックログアイテムの見積もり

全員でざっくりポイントを出して、外れ値の人の意見を聞く。でもう一回ポイントを出す。3回ぐらいやってばらつきがあるなら、多いポイントを採用する。 アイテムのスコープの確認になることが多い。

プランニングで決まったタスクのアサイ

自主性にまかせている。自分ごとにさせていくことが大事。

終わらなかったアイテムは、残作業を再見積もりするか?

しない。2スプリント分の平均をとればベロシティは均一になる。

ベロシティ的なものの振り返りってどうやるのが良い?

実はあまりやっていない。1スプリントの平均値はメンバー全員が認識しているので、その範囲に内でプランニングをし、100%やりきることが大事。 常に同じベロシティを出すのではなく、頑張ったスプリントのあとは多少緩めのプラニングをするなど、メリハリをつけていくことも重要。

KPTにカードがいつまでも残ってしまう問題

消すことが大事。例として、Keep, Problem, Tryを各2列用意して、残したいものを移動し、移動されなかったものは削除していた。 そしてTryの中から次のスプリントでやることを決め、それだを振り返るようにしていた。

KPT(というか振り返り)の結果を生産性の向上に繋げられているかがわからない

メンバーが抱える課題感を吐き出す場としても大切なので、継続していこう

スプリントレビューが実施できていない

スクラムイベントがどれか一つでも抜けていたらそれはスクラムではない。ただ、いきなりレビューするといって集まっても大変なので、

  • 常にインクリメント確認できる状態
  • インクリメントに対していつでもフィードバックを追加できるもの(スプレッドシートとかでもOK)

を用意しておき、スプリントレビューはそのフィードバックを中心に書くj人するのがよい

今後の改善として、まずはどこから始めるのが一般的なのだろうか

振り返りが大事と一般的にはいわれるが、プランニングでコミットした内容を達成する確率を上げていくことが大事。

大変参考になりました。

スクラムを始めてみての感想

転職して1ヶ月半ぐらい経ちました。 技術的にもチーム運営的にも新しいチャレンジをさせてもらっているので、頑張って結果を出して行きたいと思います。

さて、この1ヶ月半人生初のスクラムマスターをやっています。もともと「2週間のタイムボックスで開発をやってる」ぐらいの状況だったので、メンバーが増えてきたこのタイミングで少しスクラムっぽくやろうということになったので。比較的きちんとしたスクラムは自分も初めてやるので、やってみての感想や気づきをメモしておきます。

スクラムを始める前にやったこと

業務委託でサポートしてくれている方でスクラムの経験がある方にいろいろアドバイス頂き、以下のことをやりました。

スクラムでやることや簡単なルールを決める

  • バックログは今も使用しているZenHubを継続して使う
  • スプリントの期間
    • タイムボックは今まで通り2週間
    • 最初の月曜にプランニング、最後の金曜日にレトロスペクティブを行うということにした
    • レトロスペクティブからプランニングまでに時間があるが、その期間は次のスプリントに含めることに(レトロスペクティブとプランニングを同じ日にやるのはきついかなと...)
  • どのスクラムイベントをいつやるか
    • プランニング
    • デイリー
    • レトロスペクティブ
    • レビュー
      • 現段階ではやらないことに
  • スクラムイベントではどんなことをやるか(後述)
  • 1ポイントの基準
    • 今まで消化したタスクの中で、数行程度の修正だったものを"1"ということにして、チーム全体のコンセンサスを取った

そもそものスクラム開発の説明

  • 自分のスクラムに対する認識を整理するためにも簡単なドキュメントを作って、メンバーに共有しました github.com

所感

  • レトロスペクティブから次のプランニングまでの間は半日〜1日分ぐらいの稼働時間がある。アサインされているタスクが終わった人は、この期間のやることが無くなってしまう。まあ勉強とかすればいいのだが、この辺りは今後変えていくことになるかも。
  • レビューはそれぞれのissueのリリース前確認時にやってるから一旦なしになったが、UI/UX等の改善を考えると、全員でシステムを確認するレビューの時間をとってもよいかもしれない
  • ZenHubめっちゃ便利
  • スクラムの説明資料にアジャイルソフトウェア開発宣言のことも書いたけど、意外と知らない人が多く、説明してよかったと思った

スクラムを始めてみて

スプリントの途中から始めたので、デイリーの改善からやりました。

デイリーでやっていること

  • バックログの更新共有
    • Issueのパイプライン(New, ToDo, InProgress, Test, Review, Done, Closeを用意している)更新は個人で行うようにしているので、それの共有。昨日やったこと、今日やることの代わり。
  • 新規Issueの確認
    • 新しいIssueが登録されていれば全員でその内容を確認し、見積もりを行う
    • 優先度の高い場合もあるので、必要であればスプリント計画の見直しを行う
  • その他共有、相談等

所感

  • 開発チーム以外も含めてデイリーをやっていたけど、開発チームだけの時間を設けることでコミュニケーションは増えた。スコープを小さくすることは大事。
  • みんなバックログの更新をやってくれて嬉しかった。前職は全部一人でやってたし。
  • 見積もりはまだまだ課題がある。最終的なポイントの決定ロジックは明確なルールがなく、自分のさじ加減(平均を採用したり、上を採用したり、などなど)
  • その他共有はまだ業務連絡みたいなものが多いけど、技術的なトピックスとかをみんなが話すような雰囲気になっていけばいいなと思う

プランニングでやっていること

途中だったスプリントが終わって(レトロスペクティブも次のスプリントからということにしていた)、初めてのプランニングになりました。 ざっくり以下のアジェンダで進めることにしています。

0. 前回のスプリントで消化しなかったIssueを今回のスプリント(マイルストーン)に移しておく
1. プロダクト状況共有
2. new issueの見積もり
3. 今回のスプリントでやるIssueを決めて、マイルストーンを設定していく
4. マイルストーンに登録された未アサインタスクに関してアサインを決める
5. 微調整(多い少ない等、自己申告してもらう)

0. 前回のスプリントで消化しなかったIssueを今回のスプリント(マイルストーン)に移しておく

これは事前準備として、プランニングの前にやっていること。ZenHub上の作業です。 結構消化できてないIssueが残ってたりするんですよね。

1. プロダクト状況の共有

プロダクトオーナー的な立場の人も参加してくれているので、ビジネスの話は必ず共有してもらいたい。のでこの時間を取ってます。 ビジネス側でウォッチしているKPIや、検討中のビジネス展開などを共有してくれるので、非常に有意義だと思ってます。 たった2週間でも、結構状況は変わるんですね。

2. new issueの見積もり

デイリーでNewIssueはチェックしてるとはいえ、プランニングの前に新しいものが出てくるもの。なのでそれのポイントを出します。 初回はIssueの整理をしておらず、見積もりがされていない昔から残っていたIssueが大量にあったので、それの見積もりだけでプランニングの時間が終わってしまった。 2回目移行はプロダクトオーナーがIssueの整理をやってくれて、デイリーでのNewIssueチェックもワークしてきたのでこの問題な無くなったけど、大変だった。。

3. 今回のスプリントでやるIssueを決めて、マイルストーンを設定していく

大体80〜90ポイントぐらいを基準にしてますが、現状もっと増えてしまっている。 すぐにリリースできないようなタスクが多くて、Reviewなり、リリース待ちの状態で残っててそれがそのまま持ち越されてしまう、ってところが原因なのかなと。。 改善の余地あり。

4. マイルストーンに登録された未アサインタスクに関してアサインを決める

仕掛り中のもの以外は基本的にはアサインがないため、アサインしていく

5. 微調整(多い少ない等、自己申告してもらう)

アサインした結果、偏りがある場合微調整を行う。 個人が何ポイント持っているか、までは個人攻撃になる恐れがあるので、極力自己申告してもらうようにする。(個人単位では見ないほうがよいとアドバイス頂きました。確かに。)

所感

  • ものすごく課題に感じているのが、事前準備で消化しなかったIssueをそのまま次に移していること。Issueの設定がわかったのかもしれないけど、依存関係とかがすごく多くてまとめでじゃないとリリースできないものが結構おおい。全部着手しているので、それをまとめてマイルストーンを変更すると、すごいポイントがすでにやることとして加算されてしまう(実際は8割ぐらい完成していたりするのに)。何とかしたいけど、どうするのが正解なのだろうか。こういった状況にならないように適切なIssueに分割なりするのがプランニングなんだろうけど...
  • タスクアサイン時のルールと言うか意識というか、現状は個人の成長を意識したアサインにはなっていない。できそうな人をアサインしている状況なので、当然アサインされるタスクの量に偏りが出るだろうし、モチベーションにも影響するかもしれない(いつも簡単なタスクばかり回される...みたいな意見がでそう)。ここも改善ポイントだなと。

レトロスペクティブでやっていること

振り返りのやり方はいろいろあるけど、日本でよく使われているKPTをベースとすることに。 ざっくり以下のアジェンダで進めることにしています。

1. 今回のレトロスペクティブの目標共有
2. 振り返るためのデータを集め
    - Keep出し
    - ZenHub上のデータ共有
    - Problem出し
3. 改善のためのアイディア出し
    - ZenHubのデータも参考にし、Keep/ProblemからTryを出す
4. 出たアイディアから何をやるか決める
5. レトロスペクティブの振り返り

進めることにしているといっても、まだ1回しかやってませんが...。 コロナの影響で在宅勤務になったため、今はペンディングしている状況。ただ、流石に振り返りがないのは良くないとチーム内からも意見がでてきたので(いや、嬉しい限りです)、今のスプリントではやります。

1. 今回のレトロスペクティブの目標共有

振り返る上で何も思いつかない人もいるので、今回のスプリント内でのトピックスについての振り返りを考えてみませんか?というアナウンスをする。 もちろんトピックス以外でも全然OK。初回のときは以下のような例を上げた。

- 1スプリントで消化できるポイントの目安
- ポイント消化を向上させることができるような取り組み
- ZenHubの運用方法

2. 振り返るためのデータを集める

ポジティブなことを最初に行ってもらうために、Keepから考えてもらうようにしている。 そしてZenHub上での計測値と合わせて、Problemを出す。

3. 改善のためのアイディア出し

Keep/Problemに対するTry出し。ZenHubのデータを踏まえてTryを出せるようになればいいのだが、まだ難しそう。

4. 出たアイディアから何をやるか決める

改善策として上がったTryのうち、何をやるかきめる。 Issueとして取り組まなければならなそうなものは、1〜2個ぐらいに絞って次回のスプリントで出来るようプロダクトオーナーと交渉する。 それ以外のものはチームのルール的なものに入れる(増えすぎるとよくないけど...)。

5. レトロスペクティブの振り返り

今回のレトロスペクティブの総評と、フィードバックをもらうようにしてます。

所感

  • アジェンダには書いてないけど、なぜ振り返りをやるのかの共有は最初にやったほうがよい。腑に落ちない人もいるかもしれないし。
  • 1人1人に発言してもらうので、時間がすぐにオーバーする。なのでタイムキープが凄く大切。
  • 改善案はいいことしかないから、その中からどれを選ぶかきちんと決めること
  • 次からリモートになるから、うまくやれるかな。

全体を通しての感想

  • 全てにおいて、事前準備は大切です。アジェンダは事前に作って印刷し、それを見ながらファシリテートしてました。これがなかったら辛かった。
  • 目下の課題はプランニングの改善
    • 80〜90ポイントぐらいのタスク量でスプリント開始したい。
    • 個人の成長も考えた上でのアサインもやっていきたい。そのためにはメンバーそれぞれが何をやりたいのかを把握しないといけないけど。
  • スクラムとかファシリテートとかの本は流し読みしかしてないので、自分自身ももっとうまく回せるように努力しなければ

といった感じです。これからも頑張っていきます。

Webアプリで処理中に外部実行したコマンドは接続を切るとどうなるか

若いメンバーに説明しないといけなかったので、メモしとく。

テスト用のコード

実行されるWebアプリの処理は下記(環境変わってrailsいじるようになった)。 systemでsleepコマンドを実行する。 systemはlinuxのsystemコマンドを実行する(rubyのドキュメントにsystemコマンドのリンクあったし...)。

pubs.opengroup.org

test_controller.rb

class TestController < ApplicationController
  def index
    system(`sleep 100`)
    render status: 200, json: @controller.to_json 
  end
end

確認手順

  1. ブラウザでサーバ(http://localhost:3000/test/index)にアクセスする
  2. ブラウザを閉じる
  3. ps -ef, pstree -pでプロセスを確認

ちなみに、dockerで環境作ってます。

結果

$ ps -ef

UID        PID  PPID  C STIME TTY          TIME CMD
user         1     0  0 22:08 ?        00:00:01 puma 3.12.2 (tcp://0.0.0.0:3000)
user        79     1  0 22:13 ?        00:00:00 sleep 1000

$ pstree -p

ruby(1)-+-sleep(79)
        |-{ruby}(51)
        |-{ruby}(52)
        |-{ruby}(53)
        |-{ruby}(54)
        |-{ruby}(55)
        |-{ruby}(56)
        |-{ruby}(57)
        |-{ruby}(58)
        |-{ruby}(59)
        |-{ruby}(60)
        |-{ruby}(61)
        |-{ruby}(62)
        |-{ruby}(63)
        |-{ruby}(64)
        `-{ruby}(78)

ということで、接続切ってもプロセスは動いている。

なんで

systemコマンドはforkして子プロセスを生成し、生成された子プロセスがexecを使ってshでコマンドを実行する。

execl(<shell path>, "sh", "-c", command, (char *)0);

つまり、rubyがsystemコマンドで子プロセス(sh)を生成し、さらにshが子プロセス(sleep)を生成して実行する。 shは子プロセスを生成したらすぐに終了するので、sleepの親プロセスは、親の親であるrubyになる、という感じ。

HTTPについて

社内の勉強会用にざっくり書いた

github.com

HTTPについてまとめてみるかなと思ったのはmozaic.fmの影響です。 jxckさんには(一方的に)本当にお世話になってます。 毎回楽しみにしております。

また、@shibu_jpさんのReal World HTTP ミニ版(O'Reilly Japan)も大変参考させてもらいました。 www.oreilly.co.jp

フル版も買います。

Androidアプリつくった

アプリ開発の流れを経験しておきたいのと、(個人的に)便利だろうなと思うものを考えたので作りました。

play.google.com

あまり作業時間を確保できなかったのもありますが、まあ時間かかりました。 アプリ開発は大変だということがよく分かりました。

このアプリは早速使っていきます。

pythonでfitting

簡単な回帰モデルを作らないと行けなくなりそうなので、事前確認。 pythonはド素人なもので。

環境構築

こういうテスト環境はdockerでやりたいので、以下を参考にさせて頂きました。

Alpine Linuxにnumpy, scipy, scikit-learn, pandasを入れた - Qiita

Dockerfile

FROM alpine:latest

RUN apk --update-cache \
    add musl \
    linux-headers \
    gcc \
    g++ \
    make \
    gfortran \
    openblas-dev \
    python3 \
    python3-dev \
    freetype-dev \
    libjpeg-turbo-dev \
    libpng-dev

RUN pip3 install --upgrade pip
RUN pip3 install numpy \
    scipy  \
    scikit-learn \
    matplotlib \
    pandas

RUN mkdir /app

build command

docker build ./ -t python-test

script準備&実行

docker run -it --name python-test-container python-test
docker cp ./test.py python-test-container:/app/test.py
docker start python-test-container
docker exec python-test-container python3 /app/test.py
docker cp python-test-container:/app/plot.png plot.png

データ的に反比例の関数になるはずなので、scipy.optimizeのcurve_fitを使う。python、すごく便利ですね。

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

def fitfunc(x, a):
    return a/x

x = np.array([それっぽい適当なデータ])
y = np.array([それっぽい適当なデータ])

param, cov = curve_fit(fitfunc, x, y)
list_y_fit = []
for num in x:
    list_y_fit.append(param[0] / num)

array_y_fit = np.array(list_y_fit)
plt.plot(x, y, marker="o", linestyle="None")
plt.plot(x, array_y_fit, marker="")
plt.savefig('/app/plot.png')
print("a = " + str(param[0]))
plt.show()

結果はこんな感じ。

f:id:takata3:20190425224841p:plain