遅いと思ったからといってすぐspawnするのはダメ
昨日は遅いと思ったらとりあえずspawnとか言っていたのが、そうもいかなくなりましたという話。
昨日書いたやつがこれ。Rails Tutorialに沿って書いている。
## priv/repo/seeds.exs alias PhMicroblog.{User, Repo} defmodule Helper do def insert_user!(name, email, password) do params = %{ name: name, email: email, password: password, password_confirmation: password } %User{} |> User.changeset(params) |> Repo.insert! end end Faker.start Helper.insert_user!("Example User", "example@railstutorial.org", "foobar") Enum.each 1..99, fn i -> spawn fn -> Helper.insert_user!(Faker.Name.name, "example-#{i}@railstutorial.org", "password") end end
これはユーザを100人つくるseedでしたが、この後Micropost
というものが出現し、それを300個ほど作りましょうという話になりました。Elixirに書き直すとこんな感じ。適当なcontent
をつくってはユーザ6人にMicropost
をつくる。それを50回。
Helper.insert_user!("Example User", "example@railstutorial.org", "foobar") Enum.each 1..99, fn i -> spawn fn -> Helper.insert_user!(Faker.Name.name, "example-#{i}@railstutorial.org", "password") end end users = from(u in User, order_by: :inserted_at, limit: 6) |> Repo.all Enum.each 1..50, fn _i -> content = Faker.Lorem.sentence(5) Enum.each users, fn user -> user |> build_assoc(:microposts) |> Micropost.changeset(%{content: content}) |> Repo.insert! end end
だがしかしこれだと、
users = from(u in User, order_by: :inserted_at, limit: 6) |> Repo.all
に到達するときはspawn
し終わった直後なので、ユーザが作られているのかわからないのです。手元では、users
は最初につくったExample Userさんだけになってしまいました。で、どうしたかというと、Task
ですよ。
Helper.insert_user!("Example User", "example@railstutorial.org", "foobar", true) 1..99 |> Enum.map(&Task.async(Helper, :insert_user!, [Faker.Name.name, "example-#{&1}@railstutorial.org", "password"])) |> Enum.map(&Task.await/1) users = from(u in User, order_by: :inserted_at, limit: 6) |> Repo.all |> IO.inspect (for _ <- 1..50, user <- users, do: user) |> Enum.map(fn user -> Task.async fn -> user |> build_assoc(:microposts) |> Micropost.changeset(%{content: Faker.Lorem.sentence(5)}) |> Repo.insert! end end) |> Enum.map(&Task.await/1)
ユーザを100人並列でつくって、作り終わってから6人持ってきて、50個ずつmicropostを作っています。ここまで来ると、6人作り終わった時点でmicropostを作り始めたくなりますがそれはまたあとで。
あと、ユーザが持つ50個の内容が全員一緒というのもどうなんだいということと、こっちの方が書きやすかったので、全員バラバラな内容のmicropostを作るようにしちゃいました。