僕が断念していたこの問題。

gakubuchi gemが落ちる - komagataのブログ

@tkawa さんのIssueきっかけに @_yasaichi さんが直してくださったそうです。

sprocketsなど追えてないのですが、ActionView::Base#asset_digest_pathに問題があったようです。

無事僕のcapistrano deployも落ちなくなったようです。ありがたい!

qiita-markdownを含んだGemfileをHerokuにpushするには - Qiita

こちら、HerokuのBuildpackの仕組みが環境変数ベースのものからちゃんとしたサブコマンドが用意されたのでそちらを使わないと動きません。

Buildpacks | Heroku Dev Center

素の状態だとqiita-markdownが依存してるcharlock_holmesruggedがインストールできません。

rugged

cmakeが必要なのでcmakeを入れてくれるbuildpackを入れます。

$ heroku buildpacks:add --index 1 https://github.com/rcaught/heroku-buildpack-cmake

charlock_holmes

libicuが必要なため、Aptfileに書いたライブラリをapt-getでインストールしてくれるbuildpackを使います。

$ vi Aptfile 
libicu52
libicu-dev
$ heroku buildpacks:add --index 1 https://github.com/heroku/heroku-buildpack-apt
$ heroku buildpacks
1. https://github.com/heroku/heroku-buildpack-apt
2. https://github.com/rcaught/heroku-buildpack-cmake
3. heroku/ruby

aptが使えるならいろいろやりやすそうです。

Thread作りすぎにならないように10個ずつ送る。

threads = []
1000.times do
  threads << Thread.new { post_request(url, data) }

  if threads.size >= 10
    threads.each(&:join)
    threads.clear
  end
end

404などのページをassets pipelineを使って作れるgakubuchi gemを使っています。

capistranoでデプロイする時、これのassets:precompileで落ちてデプロイできてないことがよくある。(落ちないこともある)

もう一度デプロイすると動くので騙し騙し使っている。デバッグしないとなあ・・・。

Tasks: TOP => deploy:assets:precompile
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing as root@app1.kowabana.jp: rake exit status: 1
rake stdout: I, [2016-09-16T10:01:36.563918 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/blocks-25f0ada07701275b817165481ea227bf448e4b33b160e18e4e4e5ff988e4ec06.css
I, [2016-09-16T10:01:36.565468 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/blocks-25f0ada07701275b817165481ea227bf448e4b33b160e18e4e4e5ff988e4ec06.css.gz
I, [2016-09-16T10:01:48.018613 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/application-ed4db3deeeed188beda19cdd3571fffe28eac2adfd49a4c948d14dee05076639.js
I, [2016-09-16T10:01:48.019534 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/application-ed4db3deeeed188beda19cdd3571fffe28eac2adfd49a4c948d14dee05076639.js.gz
I, [2016-09-16T10:01:56.640992 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/application-36e5ebe3ef6a536d04cf635d1343bbfb50cd9c2de9b70bec0d72b0469565bf1c.css
I, [2016-09-16T10:01:56.641414 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/application-36e5ebe3ef6a536d04cf635d1343bbfb50cd9c2de9b70bec0d72b0469565bf1c.css.gz
I, [2016-09-16T10:01:56.804354 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/404-f5b8eac98ade00d0f719281af5b7b9103e7403700bda2ea175fefb8fff1ccfc5.html
I, [2016-09-16T10:01:56.805071 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/404-f5b8eac98ade00d0f719281af5b7b9103e7403700bda2ea175fefb8fff1ccfc5.html.gz
I, [2016-09-16T10:01:56.848952 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/406-67bca5a0e35c21ad811db2b88cca0ea5537cf59d85269977c274cb94dee913aa.html
I, [2016-09-16T10:01:56.849368 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/406-67bca5a0e35c21ad811db2b88cca0ea5537cf59d85269977c274cb94dee913aa.html.gz
I, [2016-09-16T10:01:56.905607 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/422-ef00dd8611c3e3d04be35eb07806ac98bad01d2e91f1777e01f7bbc340849e49.html
I, [2016-09-16T10:01:56.906426 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/422-ef00dd8611c3e3d04be35eb07806ac98bad01d2e91f1777e01f7bbc340849e49.html.gz
I, [2016-09-16T10:01:56.962076 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/500-cf3665c336cdd9870de6ce60459b74d0d4280ac369f48ef590922fbac639673e.html
I, [2016-09-16T10:01:56.962528 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/500-cf3665c336cdd9870de6ce60459b74d0d4280ac369f48ef590922fbac639673e.html.gz
rake aborted!
Errno::ENOENT: No such file or directory @ rb_sysopen - /srv/kowabana.jp/releases/20160916010102/public/assets/406-1a8f57ba17cdbf23ab495f461eea0f1e844b30e0789aab4c933385017f437c27.html
/srv/kowabana.jp/shared/bundle/ruby/2.3.0/gems/gakubuchi-1.2.2/lib/gakubuchi/fileutils.rb:8:in `copy_p'
/srv/kowabana.jp/shared/bundle/ruby/2.3.0/gems/gakubuchi-1.2.2/lib/gakubuchi/task.rb:15:in `block in execute!'
/srv/kowabana.jp/shared/bundle/ruby/2.3.0/gems/gakubuchi-1.2.2/lib/gakubuchi/task.rb:10:in `each'
/srv/kowabana.jp/shared/bundle/ruby/2.3.0/gems/gakubuchi-1.2.2/lib/gakubuchi/task.rb:10:in `execute!'
/srv/kowabana.jp/shared/bundle/ruby/2.3.0/gems/gakubuchi-1.2.2/lib/tasks/after_precompile.rake:3:in `block in <top (required)>'
/srv/kowabana.jp/shared/bundle/ruby/2.3.0/gems/rake-11.2.2/exe/rake:27:in `<top (required)>'
/usr/local/rbenv/versions/2.3.1/bin/bundle:23:in `load'
/usr/local/rbenv/versions/2.3.1/bin/bundle:23:in `<main>'
Tasks: TOP => assets:precompile
(See full trace by running task with --trace)
rake stderr: Nothing written


** DEPLOY FAILED
** Refer to log/capistrano.log for details. Here are the last 20 lines:


 DEBUG [3390349e]   I, [2016-09-16T10:01:56.905607 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/422-ef00dd8611c3e3d04be35eb07806ac98bad01d2e91f1777e01f7bbc340849e49.html

 DEBUG [3390349e]   

 DEBUG [3390349e]   I, [2016-09-16T10:01:56.906426 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/422-ef00dd8611c3e3d04be35eb07806ac98bad01d2e91f1777e01f7bbc340849e49.html.gz

 DEBUG [3390349e]   

 DEBUG [3390349e]   I, [2016-09-16T10:01:56.962076 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/500-cf3665c336cdd9870de6ce60459b74d0d4280ac369f48ef590922fbac639673e.html

 DEBUG [3390349e]   

 DEBUG [3390349e]   I, [2016-09-16T10:01:56.962528 #30643]  INFO -- : Writing /srv/kowabana.jp/releases/20160916010102/public/assets/500-cf3665c336cdd9870de6ce60459b74d0d4280ac369f48ef590922fbac639673e.html.gz

 DEBUG [3390349e]   

 DEBUG [3390349e]   rake aborted!

Errno::ENOENT: No such file or directory @ rb_sysopen - /srv/kowabana.jp/releases/20160916010102/public/assets/406-1a8f57ba17cdbf23ab495f461eea0f1e844b30e0789aab4c933385017f437c27.html

/srv/kowabana.jp/shared/bundle/ruby/2.3.0/gems/gakubuchi-1.2.2/lib/gakubuchi/fileutils.rb:8:in `copy_p'

/srv/kowabana.jp/shared/bundle/ruby/2.3.0/gems/gakubuchi-1.2.2/lib/gakubuchi/task.rb:15:in `block in execute!'

/srv/kowabana.jp/shared/bundle/ruby/2.3.0/gems/gakubuchi-1.2.2/lib/gakubuchi/task.rb:10:in `each'

/srv/kowabana.jp/shared/bundle/ruby/2.3.0/gems/gakubuchi-1.2.2/lib/gakubuchi/task.rb:10:in `execute!'

/srv/kowabana.jp/shared/bundle/ruby/2.3.0/gems/gakubuchi-1.2.2/lib/tasks/after_precompile.rake:3:in `block in <top (required)>'

/srv/kowabana.jp/shared/bundle/ruby/2.3.0/gems/rake-11.2.2/exe/rake:27:in `<top (required)>'

/usr/local/rbenv/versions/2.3.1/bin/bundle:23:in `load'

/usr/local/rbenv/versions/2.3.1/bin/bundle:23:in `<main>'

Tasks: TOP => assets:precompile

(See full trace by running task with --trace)

とりあえず日本の祝日のデータのyamlのみを含んだ holiday-jp/holiday_jp リポジトリを作りました。

https://github.com/holiday-jp/holiday_jp

従来のgemのreposは holiday-jp/holiday_jp-ruby になります。

holiday-jp/holiday_jp-ruby: Japanese holiday.

holiday_jp-rubyとかholiday_jp-phpとか作ってgit submoduleでyamlのrepoを取り込む感じで。

RubyKaigi中は過去に手をかけられてなかった自分のgemをメンテする絶好のタイミング。

pull requestいただいたmergeしてるけどrubygemsにpushしてないgemがよくあるのでこの機会にリリース。

holiday_jp | RubyGems.org | your community gem host

organizationに移る前に、色々PRを貰ってたのでリリースしました。祝日に山の日が増えてます。

RubyKaigi 1日目、各発表は他所のレポートをみていただくとして、Official Partyはやはり大事ですね。

@k1LoWさんとお話させていただく。

holiday_jpをwootheeみたいにorganization作って、言語非依存のyml(各言語用ライブラリではgit submoduleで読み込む)だけにしてはどうかという話。

それがいいですね。今夜やります。

やりました。

holiday-jp

@morygonzalezさんとお話。

  • Lokkaを今までのしがらみすてて作りなおそう。
  • 2人しかいないのにLokkaKaigiやって沢山人いる風にみせよう。
  • 福岡ダンボール問題。
  • リモートワーク手放しで賞賛するな問題。

ステッカー貰いました。

ss

@toyoshiさんとお話。

  • misocaのチーム構成やマネジメントの話。
  • 企業と連携の仕方。
  • 名古屋は紹介が重い話。(ちょっと親しいぐらいでは紹介しない問題)

僕らも今企業向けのサービスを作っているところなので非常に参考になる話をお聞きしました。

インターン、元インターンの方々とご挨拶。毎年のことですがリモートでやっててはじめましての人も多い。

しょうもない俺達と長く話さず沢山の知らない人にどんどん声をかけようという話。

今回は京都なので5人でAirbnbで一軒家を借りて前乗りしました。

おばあちゃんの家のようなカントリーサイドのティピカルジャパニーズハウスです。

https://gyazo.com/91aad256abf30d78b504f0582e131567

https://gyazo.com/2d1070b02ab578ab03891a0681c0816c

https://gyazo.com/d9ee44f8714982655d2edabfefb7764e

明日に遅れないようにAppleの発表は見ずに寝ることにします。

長いことrailsばっかりやってると他人のコードを「Railsのレール(流儀)にどれだけ乗れてるか、どれだけ流行りの書き方してるか」だけで判断しがち。

見慣れない書き方だったり、他の言語っぽい書き方だったりするとボロカスに評価しているのを見かける。

Railsに浸かり過ぎて、Railsっぽくないもの=悪。レールから外れている=ゴミ。そういった判断は楽だしRailsプロジェクトにおいては大抵あってる(Railsを理解するのを面倒臭がっているゴミコード)んだけど、対象のコードが持つ価値(どんなことをどういう方法で解決してるのか)を判断する力が衰える気がする。

Railsのレールや最近の流行りの書き方とは違うけど、一貫性のあるコードだったり、不具合が出づらく変更に強いコードってのはある。

特にRails経験は浅いけど他の言語・フレームワークに習熟してる人のコードにそういうものが多い。

手癖でやってるとそういう筋肉が落ちる。自戒を込めて。

railsでコメント数をどう実装するかで悩んでいます。

https://gyazo.com/c7ac20038c53ad302091f718fd948d15

ニコ動だとこんな感じ。

https://gyazo.com/a124a4bbf487715768730ec4aea9d810

怖話でもこんな感じでコメント数/再生数などを保存しています。

一定以上の数になると素朴な処理では速度的に無理が来ます。

怖話での実装方法

怖話でのカウント数の実装の歴史。

  1. 何もせずDBに1レコードずつ保存時代。
  2. 一覧ページなどが重いのでrailsのcounter cahcheを使う。
  3. コメントや閲覧はpolymorphic関連なのでcounter cacheが対応してない。conditional_counter_cacheを使う。
  4. 削除に時間がかかり過ぎる。 ← イマココ

一覧の表示はconditional_counter_cacheで大丈夫なのですが、削除時の処理がかかりすぎてタイムアップする問題がでてきました。

削除時の問題

ここではわかりやすく閲覧数ではなくコメント数で説明します。

コメント数が1万件ある話を削除すると下記のような処理が走ります。

  1. storyを削除する。
  2. dependent: :destroyで依存するコメント1が自動的に削除される。
  3. コメントが削除されたのでstoryのcomments_countが-1でUPDATEされる。
  4. dependent: :destroyで依存するコメント2が自動的に削除される。
  5. コメントが削除されたのでstoryのcomments_countが-1でUPDATEされる。
  6. 以下1万回繰り返し

1件につき100msだとしても1000sかかるので無理がある。

これまでの考え

  • memcacheやredisを使うのは手間なので無理が来るまで避けたい。(開発環境の構築の手間が増える)
  • ランキングで集計するので時間の情報は欲しい。
  • 一番楽な方法で実装しよう。

今の考え

  • RDBは無理がある。memcacheやredis、他のストレージもやむなし。
  • rails的に一般的な実装はなんだろう?
  • ありがちな問題なので一般的な対処方法を構築したい。

皆さんこういうのどう実装されてますか?こんな風にやってるよという方がいらっしゃったら @komagata などにメッセージいただけるとありがたいです。 :bow:

更新:railsでコメント数の実装の悩み〜解決編〜 - komagataのブログ