- 開発
週刊Railsウォッチ(20181112)Ruby 2.6.0-preview3リリース、非同期スレッドのテストはつらい、MySQL 8のGROUP BYほか
こんにちは、hachi8833です。そろそろ身が持たないのでウォッチのボリューム削減を図っています。
- 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
- 「つっつきボイス」はRailsウォッチ公開前ドラフトを社内有志でつっついたときの会話です👄
- 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください
⚓Rails: 先週の改修(Rails公式ニュースより)
⚓.freeze
をごっそり削除
Rails 6ではRuby 2.4.1以降がサポート対象になるので、従来のマジックコメントをRubocopのStyle/FrozenStringLiteralComment
に一元化するそうです。
# .rubocop.yml#L133
+Style/RedundantFreeze:
+ Enabled: true
+ Exclude:
つっつきボイス:「RailsでサポートされるRubyもいよいよ2.4.1以降か〜: この処置は納得、つかrubocop -a
で自動的に.freeze
を消せたと思うから作業はラク😋」
rubocop -a
でスキッと消えました。
⚓マルチDB系改良: 接続切り替え用基本API
つっつきボイス:「これはこの間のつっつきでもチェックした気がしてきた」「connects_to
とか既視感ありますね👁: プルリクの番号は違いますが」「前回はサンプルコードがなかったからその辺もカバーしたんでしょうね」
プルリクを雑に訳してみました。
1) モデルで複数データベースに接続できる
connects_to
メソッドを追加:
class AnimalsModel < ApplicationRecord
self.abstract_class = true
connects_to database: { writing: :animals_primary, reading: :animals_replica }
end
class Dog < AnimalsModel
# 書き込み用のanimals_primary、読み出し用のanimals_replicaという2つのDBに接続される
end
2)
connected_to
ブロックメソッドを追加: 接続のロール切り替えや、モデルで接続していなかったDBへの接続に用いる。そのブロック内でデータベースに接続できると、slow_replica
など普段は接続したくないが、コンソールや特定のコードブロックで接続したい場合に便利。
ActiveRecord::Base.connected_to(role: :reading) do
Dog.first # AnimalsBaseに接続されたreplicaでdogをfind
Book.first # readingで接続していないためエラーをraise
end
ActiveRecord::Base.connected_to(database: :slow_replica) do
SlowReplicaModel.first # DB設定にslow_replica設定があれば探索し、なければエラーをraise
end
⚓MySQL 8.0.13のデフォルト式などに対応
MySQL 8.0.13については「SQL」にもエントリを置きました。
つっつきボイス:「MySQL、マイナーバージョンアップにしてはいろいろ追加されてるみたいですね」「MySQLは結構いろいろアップデートされますよ🤓」「何がアップデートされたのかな👀」
「ほうほう、まずdefault function/expressionはCREATE TABLE t2 (a BINARY(16) DEFAULT uuid_to_bin(uuid()));
みたいにデフォルト値に式や関数を置けるようになったと: むしろ今までできなかったのが驚き😳」「へぇ〜!」「ぽすぐれでは普通にできる😋」
「functional indexは今までもMySQLでできた気がするけど、お、"not a column"ということは、カラムを作らなくてもfunctional indexできるようになったってことか!🤓: つまり今まではカラムを作らないとできなかったと」「そうでしたか!」「MySQLもついにという感じ🥳」「kamipoさんが速攻このプルリクを出したということは待ち望んでいたのかもしれないですね」「これはそれなりのRDBMSが備えている機能ですね」
⚓Railsガイドにデバッグ用詳細ログ出力方法を追加
つっつきボイス:「今までRailsガイドに記載されてなかったのかー: Railsのログ周りを見ればわかるんだろうけど」「ActiveRecord::Base.verbose_query_logs = true
でアクティベートできるみたい」「お、マルチプルデータベース対応の一環っぽい」「そっか、マルチになったら欲しいヤツですね」
これも雑に訳してみました。
ログのデータベースクエリでは、1つのメソッドが呼ばれたときに複数のデータベースクエリがトリガされる理由がすぐにわからないことがある。
rails console
セッションでActiveRecord::Base.verbose_query_logs = true
を実行して詳細クエリログをオンにしてメソッドを再度実行すると、どの1行の呼び出しですべての個別のデータベース呼び出しが生成されるかがよくわかるようになる。
irb(main):003:0> Article.pamplemousse
Article Load (0.2ms) SELECT "articles".* FROM "articles"
↳ app/models/article.rb:5
Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = ? [["article_id", 1]]
↳ app/models/article.rb:6
Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = ? [["article_id", 2]]
↳ app/models/article.rb:6
Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = ? [["article_id", 3]]
↳ app/models/article.rb:6
=> #<Comment id: 2, author: "1", body: "Well, actually...", article_id: 1, created_at: "2018-10-19 00:56:10", updated_at: "2018-10-19 00:56:10">
あるデータベース呼び出しを行うメソッドがある特定のソースファイル名と行番号が、データベースステートメントごとに
↳
で示されている。N+1クエリ(1つのデータベースクエリが多数の追加クエリを生成する)によるパフォーマンス低下の原因特定や修正に有用。
⚓ドキュメント: I18nのdeep_interpolation:
オプション
訳文ハッシュをバルクで式展開したい場合、
deep_interpolation: true
を渡す必要がある。以下の辞書があるとする。
en:
welcome:
title: "Welcome!"
content: "Welcome to the %{app_name}"
これを指定しないと、ネストした式展開が無視される。
I18n.t 'welcome', app_name: 'book store'
# => {:title=>"Welcome!", :content=>"Welcome to the %{app_name}"}
I18n.t 'welcome', deep_interpolation: true, app_name: 'book store'
# => {:title=>"Welcome!", :content=>"Welcome to the book store"}
つっつきボイス:「これもドキュメント追加ですね」「deep_interpolation
...こんなのあったのかー: yamlで式展開する話は前のウォッチでも扱った気がする」
後で探すと、Railsアプリの基本的なセキュリティの注意の項で話題にしていました。
- yamlの式展開はそのままでは出力されない(
html_safe
で無理やり出すのはよくない) - yamlのキー名末尾に
_html
を付けると自動でエスケープしてくれる(Railsガイド↓にもある推奨の方法) _html
によるエスケープはビューヘルパーのt
(translate
)メソッドでのみ利用可能
参考: 4.4 安全なHTML変換 -- Rails国際化 (I18n) API | Rails ガイド
⚓ActiveStorage::Downloader
のオートロードの問題を修正
# activesupport/lib/active_support/dependencies.rb#L257
def load_dependency(file)
if Dependencies.load? && Dependencies.constant_watch_stack.watching?
- Dependencies.new_constants_in(Object) { yield }
+ descs = Dependencies.constant_watch_stack.watching.flatten.uniq
+ Dependencies.new_constants_in(*descs) { yield }
+ else
yield
end
rescue Exception => exception # errors from loading file
exception.blame_file! file if exception.respond_to? :blame_file!
raise
end
つっつきボイス:「もしかすると先週のウォッチでちらっと取り上げたActive Storageが特定の状況でNoMethodErrorになった問題と関係あるのかな?」「番号は違っていますけどちょっと似た雰囲気ですね🤔」
⚓その他
以前のウォッチで既におおよそ取り上げていますが。
- PR: Make Webpacker the default JavaScript compiler for Rails 6 by dhh · Pull Request #33079 · rails/rails
- リポジトリ: rails/actiontext
- PR: Add allocations to template renderer subscription by eileencodes · Pull Request #34136 · rails/rails
⚓Rails
⚓Rubocopによる自動修正の注意点(Ruby Weeklyより)
つっつきボイス:「たまたまRubocopの話題が続きました」「Rubocopにこういうオプションがあるのね↓」「安全でないcopがあるという話を追ってるようです」
# 同記事より
# 安全なcopだけを実行
$ rubocop --safe
# 安全なオートコレクトだけを実行
$ rubocop --safe-auto-correct
# 安全なcopだけを実行してから安全なオートコレクトだけを実行
$ rubocop --safe --safe-auto-correct
「ちょうど記事にもこの設定にSafe: false
とかSafeAutoCorrect: false
↓がある: 詳しくは記事に書いてあると思うけど、確かに書き換え系のcopだとオートコレクト後に意味が変わってしまう可能性がある場合も考えられるので、その辺を見てくれる設定なのかもしれない」
# まったく安全でないcop
Style/CollectionMethods:
Description: 'Preferred collection methods.'
StyleGuide: '#map-find-select-reduce-size'
Enabled: false
VersionAdded: 0.9
VersionChanged: 0.27
Safe: false
# 信頼できるwarningを出すcopだが、オートコレクトは安全ではない
Style/SpecialGlobalVars:
Description: 'Avoid Perl-style global variables.'
StyleGuide: '#no-cryptic-perlisms'
Enabled: true
VersionAdded: 0.13
VersionChanged: 0.36
SafeAutoCorrect: false
「安全なcopは何も考えずにオートコレクトできるけど、安全でないcopもあるよってことなんでしょうね: Rubocopのドキュメントをざざっと見てみるとConfigurable attributesにSafeMode
あるヤツがいくつか見つかった↓」「後で見てみようっと」「ちゃんとメンテされているならこういうオプションを活用できますね😋」
ActiveRecordとの互換性: ActiveRecordには
detect
メソッドは実装されておらず、find
には独自の意味があるため、ActiveRecordのメソッドにこのcopを適用するのは安全でないと考えるべき。
同サイトより大意
- リポジトリ: rubocop-hq/rubocop
⚓RocketJob: Ruby/Rails向けバッチジョブ管理(Ruby Weeklyより)
つっつきボイス:「ジョブ管理のGUIが使えるgemのようです」「まだ★は少ないかなー?」「新しいからかもですね」「おー、こんな感じのUI↓」
「そういえばSidekiqのマウンタブルエンジンの管理コンソールって、使い勝手の面でもうひと頑張りして欲しいなって思うときあるんですよね...RocketJobは後発の分イケてそうかな🤔」「このgem単体で立ち上げられそう」「でしょうね: たぶん共通のジョブAPIを叩いてるだけだと思うので」
- サイト: Sidekiq
⚓Phusion Passengerのドキュメントサイトが公開(Ruby Weeklyより)
つっつきボイス:「トップページの動画が気合入ってます」「Passengerはいろいろ頑張ってますね」
⚓autoload_reloader: Shopifyによるオートロードの別実装(Ruby Weeklyより)
- リポジトリ: Shopify/autoload_reloader
# 同リポジトリより
require 'autoload_reloader'
File.write "foo.rb", "Foo = 1"
# ファイルシステムをスキャンしてオートロードをセットアップ
AutoloadReloader::Paths.push(Dir.pwd)
# オートロードされた定数を使って開始
Foo # => 1
File.write "foo.rb", "Foo = 2"
# 定数をアンロードしてパスを再度スキャン
AutoloadReloader.reload
Foo # => 2
# パスにあるオートロード可能な定数をすべて読み込む
AutoloadReloader.eager_load
つっつきボイス:「オートロードリローダーってloadが2回も出てくる😆」「なるほど、const_missing
を使わずにやれるのね: これはこれで挙動が変わりそうではあるけどconst_missing
よりは、ね🤓」
「読み込み順で言うことを聞かせたいときとかに使うんでしょうか?🤔」「というよりreload
できるのがいいんでしょうね: const_missing
で読み込まれると、きれいにリロードしようと思ったら普通はプロセスを立ち上げ直すしかないんですが、プロセスを落とさずに再スキャンしてリロードできるというのがうれしいポイントなんだと思う🧐」「あーなるほど!」「Railsもそうやってプロセスを止めずにリロードできるんでしょうね: カジュアルに再読み込みしたいRailsアプリなんかにはいいのかも」
リポジトリのREADME#How it worksによると、Railsでは利用できないとガイドに書かれているModule#autoload
を使ってやれるようにしたそうです。
参考: autoload
-- class Module - Documentation for Ruby 2.5.0
⚓その他Rails
つっつきボイス:「割と普通の記事っぽいです」「GraphQLにしたときのパフォーマンスも気になるけど、主導権がユーザー側に来るのがちょっと怖い気はするなー」
- 元記事: Scaling the Monolith(Awesome Rubyより)
-
リポジトリ: thiagopradi/octopus -- Octopus gemはRails 6リリース後にメンテナンスモードに入るそうです。
つっつきボイス:「今日昼の社内勉強会でちょうどOctopusの話が出たので見てみたらREADMEにそう書いてました」「昔はシャーディングといえばOctopusだったんですが、最近Octopusの話題を聞かなくなってきているからメンテモードになったのもわかる気がする」
参考: レプリケーションとシャーディング、MySQLでレプリケーションの張り方 - WebエンジニアのLoL日記
⚓Ruby
⚓Ruby 2.6.0-preview3リリース(Ruby公式ニュースより)
Ruby 2.6.0-preview3 Released https://t.co/Lo9gn5SyUg
— Ruby Language (@rubylangorg) November 6, 2018
- プレスリリース: Ruby 2.6.0-preview3 Released
ひとまず記念写真。
つっつきボイス:「早っ、もう2.6.0が近いのかー」「詳しくは上の公式ページにひととおり載っていました」「JITがまた一段と速くなっていそう🚀」
k0kubunさんがpreview3のパフォーマンスについてメモしていることをRubyWeeklyで知りました。
# 同Gistより
Comparison:
Optcarrot Lan_Master.nes
2.6.0-preview3+JIT: 86.6 fps
2.6.0-preview2+JIT: 73.9 fps - 1.17x slower
2.6.0-preview1+JIT: 59.2 fps - 1.46x slower
2.6.0-preview3: 54.6 fps - 1.59x slower
2.6.0-preview2: 53.3 fps - 1.62x slower
2.6.0-preview1: 53.0 fps - 1.63x slower
2.5.3: 48.5 fps - 1.78x slower
2.0.0: 34.6 fps - 2.50x slower
⚓Bundler 2.0のその後
- 元記事: Bundler: An Update on Bundler 2.0
- リポジトリ: bundler/bundler
つっつきボイス:「あーBundler 2.0ってその後どうなってるのかな?🤔」「現在のBundler 2.0はリポジトリにstableがあるようですが、まだ正式ではないっぽいですね」「そりゃBundler 2.0にはbreaking changesが入るからそう簡単には2.0には移行できないでしょうね」「あ、そうか」
「記事をよく見ると今日新しいBundler 2.0.0をリリースするとある: breaking changesは以下だけにとどめるみたいです」
- Bundler 1.17から2.0の全breaking changes:
- Ruby 1.8.7〜2.2のサポート終了
- RubyGems 1.3.6〜2.5のサポート終了
- エラーがSTDOUTではなくSTDERRに出力される
「今の段階でgem install bundler
で2.0が入ったら下手するとDockerfileとかも含めて軒並み動かなくなるかもしれないし👹」「くわっ😵」「BundlerってあらゆるRubyアプリで使われるから、Bundlerがもしいきなり消えたりしたらすげー困る😰」
なお、記事執筆時点ではgem install bundler
でインストールされるのは1.17.1です。2.0-stableブランチの最新コミットも2.0.0.pre.1となっています。
参考: Bundler 2.0.0.devを使ってみる - koicの日記
⚓Rubyの「サーキットブレーカー」とは(Hacklinesより)
- 元記事: Circuit Breakers
CircuitBreakerはMartin Fowler先生のパターンだそうです↓。
参考: CircuitBreaker
つっつきボイス:「日本語の手頃な記事↓があったので見てみよう: clientとsupplierの間にCircuitBreakerオブジェクトを配置して障害モニタリングすると: ↑おーこの図が欲しかった😍」
NetflixのHystrixにも使われるCircuit Breaker patternを調べてみた – ~ my tech diary ~
「CircuitBreakerがエラーハンドリングをやってくれることでエラーを握りつぶされなくなるのがメリット🧐: CircuitBreakerが死ぬと全体が死ぬことになりますが」「元記事にはcircuitboxというgemが紹介されてました↓」「見た感じ、双方向にプロキシする、とても薄い層っぽい」「シンプルだけど有効そう」「エラーハンドリングやログフォーマットを統一するのによさそうですね😋」
- リポジトリ: yammer/circuitbox
# 同リポジトリより
class ExampleServiceClient
def circuit
Circuitbox.circuit(:yammer, exceptions: [Zephyr::FailedRequest])
end
def http_get
circuit.run do
Zephyr.new("http://example.com").get(200, 1000, "/api/messages")
end
end
end
「こういうのをインフラでハンドリングするなら、たとえばFluentdあたりで取ってそこからイベントを出すみたいな方法も考えられますが、メッセージ中のエラーなんかはアプリ側でハンドリングしたいことがあるから、こういうCircuitBreakerパターンになるでしょうね🤓」
⚓Michael Hartlインタビュー(Hacklinesより)
- Podcast: 017 - Michael Hartl, Author of the Ruby on Rails Tutorial | The Ruby Testing Podcast(47:48)
つっつきボイス:「Michael HartlはおなじみRailsチュートリアルの原著者ですね」
「このPodcastなんですけど、その名も『Ruby Testing Podcast』というそれ専門みたいです」「へぇ〜!」「まだ聞いてませんが、Michale HartlさんはRailsチュートリアルの版を一新したときにRSpecを捨ててminitestに切り替えてたから、そのあたりの話をしてるんじゃないかなと思って」「push-upに続けて何故シュワルツネッガーの話まで😆」
Ruby Testing Podcastのバックナンバーを見ると2018年5月から凄い勢いで出してますね。
後で調べたらpush-upは「腕立て伏せ」でした。
⚓Rubyの非同期スレッドをテストするには(Awesome Rubyより)
つっつきボイス:「非同期スレッドのテストは、ダルいぞつらいぞ〜😭」「そもそも完全にテストできるのかというのもあるし、時間もかかるし」「どのタイミングでどの処理を実行するとすべてのrace conditionを網羅できるか、というのをやり始めると一瞬で指数関数的に組み合わせが増大するので📈」「あー😅」「なのでマルチスレッドのテストはもうそれだけでつらい🤯」「そしてそれをテストで実装しようとするとなおつらい🤯」「再現性が、ね😅」
「しかも単純にsleepかけてもダメ」「そもそもsleepかけた瞬間にテストが激遅になるし🐢」「人間がこのタイミングとこのタイミングみたいな感じでsleepをかけておりゃぁ!と調べるのはまだやれなくもないんですが」「それでも『完全に同時』みたいなタイミングの制御は難しいし😩」
「そう思うと、RailsのActionCableあたりで『何でこんな書き方になるの?』みたいなテストを見かけたりするのはたぶんそれ」「もう本質的に難しいんですね...😨」「そうなんですよー」「結局、下のレイヤの特定の実行タイミングにかかわるようなテストって書きようがないので」
「そして非同期処理にはエントリポイントというものがないから!😤」「そうっ😤: エントリポイントがあればそこで待ち構えられるけど、ないからブレークポイントで止めてえいやっと調べるしかない」「本当にそうするしかないんですよ👽」
「そしてそこまでやっても、網羅できてる保証はないという😭」「人力で止めてやってると客観性も再現性もないし」「やっぱり非同期スレッドのテストはどう転んでもつらい😇」
「ここでこういうタイミングでこれを実行するとバグが発生する、みたいなのはまだやれる」「そうそう😆: このぐらいの負荷で30分ぐらい回すとだいたい何件のエラーが起きるとか😆」「0.000何パーセントの割合でコケるみたいなの」
「そういうポイントをたまたま見つけられるとうれしい気持ちになる😊」「でもそれで本当に修正されたかどうかはわからないという🙃」「そういうときは論理を駆使して絞り込むとか」「確固たる原因を突き止めるのが半端なく大変」
⚓その他Ruby
そういえば一年前に松江で受けたインタビューが公開されてることにさっき気づきました https://t.co/ojI0OA5rJQ
— Ryuta Kamizono (@kamipo) November 1, 2018
原稿が印刷所へ送られていったそうです!脱稿した〜〜〜やった〜〜〜!!!(・∀・) https://t.co/psf1SR4MmP
— igaiga (@igaiga555) November 7, 2018
https://twitter.com/it_tech_news/status/1060356503645827072
つっつきボイス:「igaigaさんの本はこれまでいろいろやってきたリソースの蓄積をうまくまとめてそう」「かんたんRubyというタイトルからの連想ですが、趣味で簡単なコードを書くのと仕事でちゃんとしたコードを書くときの差が大きいんですよね結局☺️」「結局そう」「動きさえすればいいコードを教えるならいろんな方法で本を書けそうだけど、クォリティを問題にし始めると途端に書き方をきちっと合わせなければならなくなるので😆」「よく入門書なんかではattr_accessor
で書けばいいよ❤️って教えてるけど、現場に来ると『違うでしょっ😤』って言われちゃったりするんで、そういう本を書くのは難しい...」
⚓Ruby trunkより
⚓RefinementがForwardableで使えない->想定どおり
require "forwardable"
module URIExtensions
refine URI::Generic do
def authority
port_string = port == default_port ? nil : ":#{port}"
"#{host}#{port_string}"
end
def origin
"#{scheme}://#{authority}"
end
end
end
using URIExtensions
class Container
extend Forwardable
def_delegator :@uri, :origin
def_delegator :@uri, :authority
def initialize(uri)
@uri = uri
end
end
u = URI("https://google.com")
container = Container.new(u)
puts container.origin
puts container.authority
つっつきボイス:「お、Forwardableですよ」「デリゲートするためのモジュール」「RefinementしたらForwardableが届かなくなったと思ったら『Refinementはレキシカル(静的)にメソッドを上書きするので想定どおり』という回答でした」「仕様どおり😆」「using
でRefinementした後extend Forwardable
のdef_delegator
は効かなくなると」「よぐわがんね😅」「こういうコードって普段書かないな〜」
参考: module Forwardable
(Ruby 2.5.0)
参考: 静的スコープ - Wikipedia
「Refinementってproductionコードで使ったことあります?」「developmentですら1回も書いたことないです🤓」「でしょうね〜: あるとすればモンキーパッチを当てるときとか」「業務のコードでモンキーパッチを当てないといけなくなったとしたら、仕様を『それは利用できません』の方に倒す方が確実な気がする😆」「でもたまに当てないといけなくなるんですよね😆」「幸いにして今までそういう事態になったことはない☺️」「かなり昔に、RFCに準拠していないサーバーに接続するために、RailsのRFCに準拠している部分にモンキーパッチを当てたことならあります🐵」「😆」「😆」
「パッチ当てるときにRefinementを使うかどうかという選択肢はありますね」「他でも使われている可能性があるものだったらRefinementを使う方が安全でしょうね🧐」
後で動かしてみたら確かにエラーになりました。
puts container.origin
#=> NoMethodError: undefined method `origin' for #<URI::HTTPS https://google.com>
from /Users/hachi8833/.rbenv/versions/2.5.3/lib/ruby/2.5.0/forwardable.rb:229:in `origin'
⚓クラウド/コンテナ/インフラ/Linux/Serverless
⚓VMWareがHeptioを買収
つっつきボイス:「VMWareもくばねてに手を伸ばしたんだなと思って」「よく知らないけど前からやってるんじゃないかな?🤔」
その後以下の記事も出ました。
⚓その他クラウド
つっつきボイス:「もしかしてカレンダー予約かな〜と思ったらそっちではない方向でした」「お、GoogleのはAWS Batchとは違って本当にスケジューラなんですね😋」
参考: AWS Batch – 簡単に使えて効率的なバッチコンピューティング機能 – AWS
「こういうスケジューラ、AWSで欲しいんですよね」「ないんですか?」「AWSには所定の時刻にバッチを実行するシンプルなサービスは単品ではなかったと思う」「へぇ〜😳」「AWS BatchはSNS↓トリガーで動かすことはできますが、そのSNSを別の何かでスケジューリングするとかになるんじゃないかな🤔」「やりようはあると思うけど、cron程度のものはあってもいいよねみたいな」
参考: Amazon Simple Notification Service(プッシュ方式のメッセージ送信) | AWS
AWS Instance SchedulerはEC2/RDSインスタンス向けのスケジューラなので別物ですね。
参考: AWS Instance Scheduler の紹介
「ふと思ったんですが、クラウド運営側からするとcron的な単体サービスってあまり置きたくないものなんでしょうか?」「ふむむ、置きたくないとまではいかなくても、インフラとして設置しようとすると時刻同期の問題とかがあるから面倒というのはあるかもしれないですね」「おー」「バッチの実行時刻をきっちり同期して保証するのって地味にダルいので😟」
「たとえばですが、インスタンスが落ちているときにcronの時刻が来てしまったらどうするか、なんてことを考えたりすると、インスタンスの終了に要する期間のスケジュールも見越した上でやらないとサービスとして不完全になってしまうので」「ははぁ」「コンテナとかAWS Lambdaみたいに作り捨てるようなものならcronでサービスしやすいと思いますが、特定のEC2インスタンスでcronジョブを実行するみたいなのは、エラー通知とかもしっかり設計しないといけなさそう」
「いわゆるtrustedなサービスや、呼ばれてから動き出すようなサービスぐらいならcronでも問題なくスケジューリングできそうですが、untrustedなサービスが動いていなかったときの挙動をサポートするのは地味にダルい」「ふむふむ」「ちゃんとやるとなったら、ジョブをキューに入れて、SNSとSQLSQSを間に挟んで...と結局大げさになってしまう」「なるほど!😃」
「まあAWSもそのうちこういうスケジューリングサービスやるんじゃないかなという気はしています: 最近のAWSは既存のサービスをCloud Formationのテンプレートで組み合わせたものに名前を付けて新しいサービスにしてたりしますし😆、スケジューリングサービスは既存の組み合わせで実現できるので」「😆」
参考: AWS CloudFormation (設定管理とオーケストレーション) | AWS
「Googleのスケジューラは、単体で使うよりもたとえばGoogleカレンダーあたりと組み合わせるといいかもしれないっすね: App Engineで使えるってあるし」「それはありかも」「ちょろっと何かやるにはよさそう: retryループとか発生しそうだけど🤣」「🤣」
参考: App Engine - 任意の言語でスケーラブルなウェブ バックエンドやモバイル バックエンドを構築 | Google Cloud
⚓SQL
⚓MySQL 8.0.13リリース
以下の資料↓もよさそうです。
先日開催した「MySQL8.0バージョンアップ対策セミナー 」の資料を公開しました!
MySQL 8.0のInnoDBの変更点、バージョンアップ準備に役立つアップグレードチェッカー、5.7と8.0のパラメーターの差異から変更点を解説した資料が参照できますので是非ご活用下さい!https://t.co/MLtrZea2LI #mysql_jp— Yoshiaki Yamasaki (@yyamasaki1) November 7, 2018
つっつきボイス:「さっきの先週の改修でも取り上げましたが一応」「Upgrade Checker↓なんてものもあるのか」
参考: MySQL Shell 8.0.4: Introducing “Upgrade checker” utility | MySQL Server Blog
「GROUP BYのソートがなくなるんでしたっけ」「マジで?!😱」「Twitterだかはてブだかで、日本のMySQL強者の誰かがそういうことを言ってたのを見た覚えがあります: GROUP BYにORDER BYかけないヤツはまさかいないよな、MySQL 8からは順序保証されないよ、みたいな感じで」「あ〜それ見たことある気がする」
探しましたがうまく見つけられませんでした🙇。
「MySQLは昔からそういうところある😆」「そういうところって😆」「SQLの仕様ではGROUP BYの順序は保証されないんですが、MySQLはたまたま順序が保証されてたという😆」「じゃそれを当てにしてるコードは...😰」「MySQLのオーダリング系は結構そういうのがあったりするし」「そのGROUP BYがこのたびちゃんとするようになったと」「正しい」「よくわかってないですが😅」
「たしかにクラスタリングとかやり始めると暗黙のオーダリングはどうしてもパフォーマンスが落ちてしまう」「RailsのActiveRecordのgroup
だけ叩いたときの挙動がどう変わるのかが気になるところです☺️」「どうだろう?🤔シンタックスが間違ってたわけじゃないから、単に今までどおり順序保証のないGROUP BYするんじゃないかな: ぽすぐれでも通らないと困るし」「そうですね〜」
参考: group
-- ActiveRecord::QueryMethods
「それにしてもMySQLの今までの暗黙の順序保証って、どういう順序を保証してたんでしょうね😅」「😆」「もしMySQLのストレージエンジンに依存するような順序保証だとしたら、今までの暗黙の順序保証もそもそも当てにすべきじゃなかったろうし😆」「MySQLの順序保証がなくなった後、ぽすぐれみたいに割とクエリの結果が違うようになったら苦情出そうで、それはそれで困る😭: ぽすぐれはUPDATEとかDELETEとかかけると割と順序が変わるので」「やっぱりORDER BY付けろと」「ORDER BYしないといけないときはORDER BYすべき🧐」
参考: MySQLの「InnoDB」と「MyISAM」についての易しめな違い - (2015年までの)odaillyjp blog
⚓JavaScript
⚓bootstrap.native: Bootstrap 4でjQueryを使いたくない人に
- サイト: Native JavaScript for Bootstrap
- リポジトリ: thednp/bootstrap.native -- ★1000超え
つっつきボイス:「今日の社内勉強会で言及されてたので」「そうそう、これね☺️」「この手のものではこれがメジャーっぽいですね」「こういうののVue.js版を作ってる人もいたと思う」「へぇ〜😳」「jQueryじゃないBootstrap JSを作っている人々」
これ↓のようです。★6000超えです。
- サイト: Bootstrap Vue
- リポジトリ: bootstrap-vue/bootstrap-vue
「追従するの大変そう...😅」「今度オレオレRailsアプリでbootstrap.native試してみます😍」「BootstrapのJSってそんなにヤバいことはしてないと思う: まあモーダルのアニメーションなんかは地味に面倒ですが☺️」「モーダルアニメーションをjQueryとまったく同じにしてブラウザ互換を確保するとか、たしかに面倒くさそう😇」
⚓Node.jsのSocket.IOとは
- サイト: Socket.IO
- リポジトリ: socketio/socket.io
★44000超え!
参考: Node.jsからSocket.IOを使うための事前知識 - Qiita
つっつきボイス:「socket.ioはJavaScript界隈では普及してるようですが、自分が単純に知らなかったので😅」「Nodeでソケット開くときに使うヤツですよね😎」「WebSocket用かと思ったら、WebSocketに限らないみたい」「まあNodeでWebSocketやろうとすると、このsocket.ioがめちゃめちゃ使われてるのは確かかも😋」
参考: ソケットプログラミング
「socket.ioの使い方↓を見ると、メッセージ指向っぽい気もするけど、いわゆるNodeサーバーっぽい書き方っすね」「おー」「普通のソケットサーバーというか、任意ソケットっぽい」「socket.ioのREADMEにも『socket.ioはWebSocketの実装じゃないよ』って書いてあるし」「ホントだ」「JSというかNodeでこんなの書けるんだ〜」「socket.ioはかなり前からあるはずで、Node.jsでサーバー作るときによく使われる、OS系にアクセスするためのライブラリのひとつですね☺️」「本当の生ソケットを開きたいときとか」「Node.jsでプロキシ書くときとかも使うでしょうね」
// 同リポジトリより
const server = require('http').createServer();
const io = require('socket.io')(server);
io.on('connection', client => {
client.on('event', data => { /* … */ });
client.on('disconnect', () => { /* … */ });
});
server.listen(3000);
「全部Node.jsで書けちゃうとは、すげ〜💪」「結構前からそうですけどね☺️」「例のIsomorphicなんてのはもろにNode.jsから始まったヤツだし」「そうそう」「JS最強説👹」
Isomorphic JavaScriptは最近「Universal JavaScript」と呼ばれてることを知りました↓。
参考: Universal / Isomorphic JavaScript について - Qiita
- サイト: Node.js
「そういえばIsomorphicが話題になってた頃に、JSの強いヤツを集めた略語があった気がするけど何でしたっけ...🤔LAMP↓みたいな感じで」「Nodeと、Expressと、んーと」「MEANか↓!」「それだっ」「Firebaseが出る前でしたね☺️」
参考: MEAN(MongoDB, Express, AngularJS, Node.js)スタックが優れている理由 - Mozilla Open Web Day in Tokyoを終えて - albatrosary's blog
参考: LAMP (ソフトウェアバンドル) - Wikipedia
「まあ確かに全部JSにすればそれぞれをJSONでつなげられるみたいなメリットはありますよね」「JSONにスキーマがあれば🤣」
⚓CSS/HTML/フロントエンド/テスト
⚓UIデザインをオブジェクト指向的に考える
はてブでバズっていたので。
つっつきボイス:「ここでいうオブジェクトって何を指すんだろう?🤔」「名詞→動詞構文に、実装モデル・表現モデル・メンタルモデルか」「いわゆるヒューマンインターフェースアナライズみたいな分野ではこういうふうに考えますね」
参考: UX/UI – U-Site
「表面・骨格・構造・要件・戦略か」「抽象度高い」「特に海外のUIデザイナーやUXデザイナーは以前からこんな感じで進めているし、日本でもやってる人たちはいる」「案件でもこういう背後の要件とか戦略とか伝えてもらったらうれしいなっ😆」「『ユーザーインターフェイスは実装モデルではなくユーザーの脳内モデルに基づいて作れ』正解〜🎯」
「こういうUI/UX分野は昔からAppleが強いですね: Xcodeのインターフェイスビルダー↓なんかまさにそうですし」「あーたしかに」「Appleはツールも一緒に作ってきたのが凄い😍」
参考: Interface Builder - Wikipedia
「その意味ではデザインツールのSketch↓なんかもそうで、上の記事みたいなUI/UXの基礎や階層をきちんと心得ておかないと単なる使いにくいPhotoshopみたいになってしまう😆」「😆」「Sketchに限らず、コンポーネント化されたWebデザインをやろうと思ったらこのあたりは避けて通れないでしょうね😎」「そうでないと、こういうツールを使ってても、あるコンポーネントを変更しても他のにさっぱり反映されない、みたいなことになりかねない😆」「😆」
「いわゆるフロントエンドエンジニアにもこういう知識が求められますね」「フロントも大変だ😅」「コーダーならともかくですが☺️」
⚓言語よろずの間
⚓Facebookの「Reason」とは
- サイト: Reason · Reason lets you write simple, fast and quality type safe code while leveraging both the JavaScript & OCaml ecosystems.
- ドキュメント: What & Why · Reason
- リポジトリ: facebook/reason
- サイト: BuckleScript · Write safer and simpler code in OCaml & Reason, compile to JavaScript.
- リポジトリ: bucklescript/bucklescript
Reasonは新言語ではなく、OCamlをJavaScript風に書けるよう制約して、BuckleScriptでJavaScriptにコンパイルするのだそうです。よく見たらFacebookのリポジトリでした。
つっつきボイス:「ReasonはGobyの@st0012さんから教わりました: OCamlなんだけどJavaScriptっぽく書けるみたいな感じです」「おほ😊、1行目のtype
のあたりは関数型っぽくて、let
から先はJSっぽいけど関数型っぽい部分もある」「へぇ〜😳ガードっぽく書いたり」「いろいろ考えるなー」
type schoolPerson = Teacher | Director | Student(string);
let greeting = person =>
switch (person) {
| Teacher => "Hey Professor!"
| Director => "Hello Director."
| Student("Richard") => "Still here Ricky?"
| Student(anyOtherName) => "Hey, " ++ anyOtherName ++ "."
};
「そういえばMatzの『言語のしくみ』でHaskellよりOCamlが好きって書かれてました」「OCamlは結構息の長い言語で、金融系や保険系の商品設計あたりではかなり使われてたと思う」「おーそっちですか」
参考: OCaml - Wikipedia
参考: OCaml.jp
「ファンドの商品設計とかは関数型的に記述しないと複雑になりすぎてしまうからでしょうね」「手続き型だとつらそう...😭」「商品そのものがものすごく複雑だから人間がバグを発見するのは無理だし、障害発生の影響も大きすぎるし」「確かに扱ってるのがお金だし」「なのでそういう分野では構造上バグが出にくい関数型系の言語がよく使われてて、記憶ベースですが日本のとある大手銀行の商品開発や戦略系の部門でOCamlが使われてたって聞いたことあるし、Haskell使ってる金融系もあった気がする💵」「へぇ〜😳」
参考: Haskell、Scala、ML、Scheme:あなたが次に学ぶ関数型言語 | POSTD
「そういえばOCamlってプログラミング言語としては珍しくフランス🇫🇷産なんですね」「フランスそっち方面ではあまり聞かないかも」「雰囲気的にはですが、諜報・天文・暗号解読とかだとイギリス🇬🇧あたりが強い印象」「あとイスラエル🇮🇱ですかね」「ドイツ🇩🇪とか」
⚓その他
⚓Linuxノートどうよ
Macは持ってますけど、メインマシンはThinkpadにUbuntuですね
— Yukihiro Matsumoto (@yukihiro_matz) November 7, 2018
つっつきボイス:「最近Linuxのトラックパッドドライバがだいぶよくなったらしいのでこの辺ちょっと気になってます😆」「☺️」
⚓最近の深層強化学習
深層強化学習アルゴリズムまとめ - Qiita https://t.co/dpUxDTxtH4 こういう最近までの手法をざっくりまとめてくれるのは素晴らしい!
— Yuta Kashino (@yutakashino) November 5, 2018
つっつきボイス:「やべーこれ😆わからん」「ドキュンあるし」「DQNありますねー☺️」「こういう記事を一度はざざーっと読んで用語を押さえておくと、次に調べるときの脳内インデックスとして役立ちますね📖」「ですね☺️」
方策関数ってPolicy Functionなんですね。
ロボットは東大に入れるか。Todai Robot Projectでデータが公開されたことも話題になってます。
「これも結構前からやってますね」「研究期間終わらないうちにクローズしてた気がする」「そうだったかも」「結局東大入れたんだろか🎓」「研究費を引っ張るのにはいい題材😆」
⚓番外
⚓今一番凄いのってどれだろう
“「Spiking Neural Network Architecture (SpiNNaker)」と称する独自プロセッサを100万基搭載。同プロセッサは、1基あたり1億個のトランジスタを備え、秒間2億回の処理が可能となっている。… https://t.co/jlNcDM21cy
— Hideyuki Tanaka (@tanakh) November 7, 2018
つっつきボイス:「今ってどのスパコンが一番凄いのかだんだんよくわからなくなってきて😅」「今だとピーク性能よりも電力効率あたりの比重が上がってたりしますね」
シン・ゴジラの設定のうちクラウド周りだけは早晩古くなりそうだったのを思い出しました。
⚓図解シリーズ
スパコンがどうやってできるか知らない人が多いみたいなんで図解してみました。 pic.twitter.com/oIxKw3JF20
— ロボ太 (@kaityo256) July 4, 2017
何だかかわゆかったので😍。
今回は以上です。
おたより発掘
「igaigaさんの本はこれまでいろいろやってきたリソースの蓄積をうまくまとめてそう」 いつも読んでる週刊Railsウォッチでtweet取り上げてもらえて嬉しい! / “週刊Railsウォッチ(20181112)Ruby 2.6…” https://t.co/3tpvYYUsFm
— igaiga (@igaiga555) November 14, 2018
プロダクションコードでもガシガシ Refimenets 使ってるマンです / 週刊Railsウォッチ(20181112)Ruby 2.6.0-preview3リリース、非同期スレッドのテストはつらい、MySQL 8のGROUP BYほか - https://t.co/DzLlFLZsSR
— バンビちゃん@実際パリピになれないオタク (@pink_bangbi) November 14, 2018
バックナンバー(2018年度後半)
週刊Railsウォッチ(20181105)DBマイグレーション9つのコツとハマった話、Railsのモデルとディレクトリの設計ほか
- 20181029 特集『肥大化したActiveRecordリファクタリング7つの方法』今ならどうなる?Redis 5のストリーム機能他
- 20181022 Railsの名前空間地獄とrequire_dependency、PostgreSQL 11がリリース、clean-rails.orgほか
- 20181015 Rails初心者と一発でバレる書き方、次のVue.js構想、RubyのOpenStruct、Twilioほか
- 20181001 Railsアップグレード記事と各種支援ツール、CLI向けRubyワンライナー集、Rubyアプリをワンバイナリ化ほか
- 20180925 Rails大規模支払サービス開発のノウハウ、RailsのMySQLがutf8mb4に移行、Rpush gemほか
- 20180918 ビューテンプレート探索が高速化、mini_scheduler gem、レガシコントローラのリファクタリングほか
- 20180910 公開つっつき会#2、RSpecは何を参考にするか、イベントソーシング、marginalia gem、負荷テストツールvegetaほか
- 20180903 次世代アップローダーgem「Shrine」、RSpecをどこまでDRYに書くか、Rubyのmainオブジェクトの秘密、GitLabのCookie利用許諾機能はエライほか
- 20180827 Ruby Prize 2018募集開始、Interactor gemとReader Object、書籍『Real World HTTP』、Basecampのヒルチャート機能ほか
- 20180820 Railsで構築されたサイト40選、Deviseはつらいよ、ARのスコープとクラスメソッドの使い分けほか
- 20180813 Rails 5.2.1リリース、sanitize_sql_arrayは5.2からpublicだった、Dev.toがRailsアプリのソースを公開ほか
- 20180806 Rails 5.2.1.rc1リリース、Railsガイド日本語版が5.1に対応、Regexp#match?ほか
- 20180723 Railsdm Day 3 Extremeを後追い、PSDにはZeplin.io、好みの分かれるJSX、負荷テストツール比較ほか
- 20180709 Rails Developers Meetup Day 3 Extreme今週末開催、RailsのSTI/キャッシュ/添付ファイル/Redis/PDF出力、ECMAScript 2018、プロフェッショナルIPv6ほか
- 20180702 Ruby 2.2メンテ正式終了、Ransackがつらくなるとき、書籍『Domain-Driven Rails』、GitHubの高可用MySQLほか
- 20180622 Railsの需要未だ巨大、Unicode 11.0リリース、WebDriverがW3Cで勧告、Flutter.io、2封筒問題ほか
- 20180615 TTY gemとHTTPClient gemは優秀、Rubyの謎フリップフロップ、ちょいゆるRubyスタイルガイドほか
- 20180608 特集「RubyKaigi 2018後の祭り」、
Enumerable#index_with
は優秀、コントローラから@
を消し去るほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。