狠狠撸

狠狠撸Share a Scribd company logo
??を支える技術
2016.04.08 増田貴士(@masutaka)
日?を支える技術
2016.04.08 増田貴士(@masutaka)
日报を支える技术
2016.04.08 増田貴士(@masutaka)
マスタカの日報
? 序盤はエンジニアでなく
ても分かる話を
? 中盤はプロダクトごとに
セクション分け
? 終盤は翌営業日にやるこ
とを全部列挙。日報駆動
開発のため
とあるスクリプトとの出会い
http://kitak.hatenablog.jp/
entry/2014/04/22/013849
出力を自分好みに変えて、
* [Bundle Update on 2016-03-24 - masutaka/awesome-github-
feed](https://github.com/masutaka/awesome-github-feed/pull/
38) by deppbot **merged!**
* [Fix performance - masutaka/github-nippou](https://
github.com/masutaka/github-nippou/pull/44) by masutaka
**merged!**
RubyGems.orgにリリースや!
? 2014年12月7日
? https://rubygems.org/gems/github-nippou/versions/0.0.1
? commitコメントに引用元書いて
? https://github.com/masutaka/github-nippou/commit/
4f408a6d
だましだまし使う日々
? 今日活動したIssueやPullRequestを取得できない時が
ある
? タイトルやステータスが古い時がある
? Issueのクローズやcommitへのコメントを検知できな
い
? なんか遅い
? やる気のない(リファクタリングしてない)コード
1年3か月放置…
先々週(2016-03-21)
なぜかやる気になった
※ 勉強会のことは意識していなかった
こんな感じ!
改善はほぼ完了
? 今日活動したIssueやPullRequestをもれなく取得
? 期間を指定することも可能になった
? タイトルやステータスも現在の値を取得
? Issueのクローズを検知。commitへのコメントは今
回見送り
? パフォーマンスは限界まで上げられた
? 満足行く程度までリファクタリングした
顺を追って话します。
Octokit
https://github.com/octokit/octokit.rb
GitHub Events API
List events performed by a user
https://developer.github.com/v3/activity/events/#list-events-
performed-by-a-user
If you are authenticated as the given user, you will see your private
events. Otherwise, you'll only see public events.
GET /users/:username/events
ここで使われていると思う
paginationあり
https://developer.github.com/v3/activity/events/
Events support pagination, however the per_page option is
unsupported.The ?xed page size is 30 items. Fetching up to ten
pages is supported, for a total of 300 events.
Only events created within the past 90 days will be included in
timelines. Events older than 90 days will not be included (even if the
total number of events in the timeline is less than 300).
curlでの取得例
$ curl -s -u <username>:<personal access token> https://
api.github.com/users/:username/events
[
{
"id": "3825680181",
"type": "PullRequestEvent",
"actor": {
"id": 170014,
"login": "masutaka",
"gravatar_id": "",
"url": "https://api.github.com/users/masutaka",
"avatar_url": "https://avatars.githubusercontent.com/u/170014?"
},
(snip)
pagination
$ curl -I <username>:<personal access token> https://
api.github.com/users/:username/events
(snip)
Link: <https://api.github.com/user/170014/events?page=2>;
rel="next", <https://api.github.com/user/170014/events?page=10>;
rel=“last"
(snip)
Octokit
https://github.com/octokit/octokit.rb
UserEvents取得方法
client = Octokit::Client.new(login: 'masutaka', access_token: 'xxx')
user_events = client.user_events(‘masutaka')
デフォルトでは最大で30個取得
鲍蝉别谤贰惫别苍迟蝉のハマりどころ
? client.user_eventsが返すイベントはデフォルト30個
? タイトルやステータスはイベント発生時のもの。
現在とは違う可能性あり
? 今回捕獲すべきイベントタイプ(※)は4つ
? IssuesEvent, IssueCommentEvent, PullRequestEvent,
PullRequestReviewCommentEvent
? IssueのふりをしたPullRequestがある
※ https://developer.github.com/v3/activity/events/types/
最初のスクリプト
1. UserEvents取得(30個だけ)
2. 必要なUserEvent以外捨てつつ、標準出力
に整形して表示
? 今日活動したIssueやPullRequestを取得できない時が
ある
? タイトルやステータスが古い時がある
? Issueのクローズやcommitへのコメントを検知できな
い
? なんか遅い
? やる気のない(リファクタリングしてない)コード
これらの原因
情报を漏れなく完璧に取得
1. UserEvents取得(30個)
2. 次のページ取得がまだ必要ならUserEventsを取
得し続ける?
3. 必要なUserEvent以外捨てる
4. 残ったUserEventsの現在のタイトルやステータ
スを取得しつつ?、標準出力に整形して表示
完璧になりました!
でも遅くなりました/(^o^)\
数秒だったのが、遅い時で20秒以上に…
パフォーマンス分析するぞ!
1. UserEvents取得(30個)… 約1.4秒
2. 次のページ取得がまだ必要ならUserEventsを取
得し続ける? … 約1.5秒 x 最大9回
3. 必要なUserEvent以外捨てる
4. 残ったUserEventsの現在のタイトルやステータ
スを取得しつつ?、標準出力に整形して表
示 … 約1.0秒 x 残ったUserEvent数
GitHub APIへのアクセスに時
間がかかっていた
パフォーマンス改善1
@client.user_events(@user)
!
@client.user_events(@user, per_page: 100)
fetch数を30から100に増やす
1. UserEvents取得(100個)… 約1.8秒
2. 1日100個に収まることがほとんどなので、
次のページ取得が必要な確率は低い
3. 必要なUserEvent以外捨てる
4. 残ったUserEventsの現在のタイトルやステー
タスを取得しつつ、標準出力に整形して表
示 … 約1.0秒 x UserEvent数
↑改善!
パフォーマンス改善2(修正前)
def list
lines = []
user_events.each do |user_event|
line << format_line(user_event)
end
puts sort(lines)
end
並列化してみよう
パフォーマンス改善2(修正後)
def list
lines = []
mutex = Mutex::new
# https://github.com/grosser/parallel
Parallel.each(user_events, in_threads: 5) do |user_event|
line = format_line(user_event)
mutex.synchronize { lines << line } # 排他制御
end
puts sort(lines)
end
パフォーマンス改善の結果
修正前: 17.531秒
↓
修正後: 7.660秒(デフォルト: 5並列)
修正後: 6.655秒(10並列)
※ 2016年3月30日で計測
1. UserEvents取得(100個)… 約1.8秒
2. 1日100個に収まることがほとんどなので、次
のページ取得が必要な確率は低い
3. 必要なUserEvent以外捨てる
4. 残ったUserEventsの現在のタイトルやステータ
スを5並列で取得しつつ?????、標準出
力に整形して表示 … 約1.0秒 x UserEvent数 ÷ 5
↓改善!
使い方
$ github-nippou help
Commands:
github-nippou help [COMMAND] # Describe available commands or one specific
command
github-nippou list # Displays today's GitHub events formatted for
Nippou
github-nippou version # Displays version
Options:
s, [--since-date=SINCE_DATE] # Retrieves GitHub user_events since the date
# Default: 20160406
u, [--until-date=UNTIL_DATE] # Retrieves GitHub user_events until the date
# Default: 20160406
デモ
リリース
まとめ
パフォーマンスチューニング
したいだけの人生だった。
ご静聴ありがとうございました。
? $ github-nippou | sed -e "s@- feedforce/@- @g"
>> ~/tmp/nippou.md
後悔
? github-nippou
? github_nippou
并列化といえば、
骋辞言语???!

More Related Content

日报を支える技术