จะทดสอบธุรกรรมฐานข้อมูล async ที่ Elixir.Task ใช้งานได้อย่างไร

ฉันกำลังพยายามแทรกบันทึกในฐานข้อมูลแบบอะซิงโครนัสโดยใช้ Elixir.Task ในตัวควบคุม Phoenix การทดสอบที่ครอบคลุมวิธีการควบคุมนั้น บันทึกข้อยกเว้นว่ามีข้อผิดพลาดในการเชื่อมต่อ DB (DBConnection.OwnershipError)

ฉันพยายามตั้งค่าการทดสอบคอนโทรลเลอร์เป็นแบบอะซิงก์ ดังนั้นโหมด Ecto.Adapters.SQL.Sandbox จะถูกแชร์

ลิงก์ไปยังการใช้งานคอนโทรลเลอร์: ลิงก์

ลิงก์ไปยังการทดสอบตัวควบคุม: ลิงก์

บันทึก:

05:28:21.325 [error] Task #PID<0.438.0> started from #PID<0.436.0> terminating
** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.438.0>.

When using ownership, you must manage connections in one
of the four ways:

* By explicitly checking out a connection
* By explicitly allowing a spawned process
* By running the pool in shared mode
* By using :caller option with allowed process

The first two options require every new process to explicitly
check a connection out or be allowed by calling checkout or
allow respectively.

The third option requires a {:shared, pid} mode to be set.
If using shared mode in tests, make sure your tests are not
async.

The fourth option requires [caller: pid] to be used when
checking out a connection from the pool. The caller process
should already be allowed on a connection.

If you are reading this error, it means you have not done one
of the steps above or that the owner process has crashed.

See Ecto.Adapters.SQL.Sandbox docs for more information.
    (ecto_sql) lib/ecto/adapters/sql.ex:618: Ecto.Adapters.SQL.raise_sql_call_error/1
    (ecto) lib/ecto/repo/schema.ex:649: Ecto.Repo.Schema.apply/4
    (ecto) lib/ecto/repo/schema.ex:262: anonymous fn/15 in Ecto.Repo.Schema.do_insert/4
    (elixir) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
    (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Function: #Function<4.97600206/0 in UrlShortenerWeb.LinkController.redirect_url/2>
    Args: []
05:28:21.380 [error] Task #PID<0.435.0> started from #PID<0.433.0> terminating
** (stop) exited in: DBConnection.Holder.checkout(#PID<0.434.0>, [log: #Function<11.104730475/1 in Ecto.Adapters.SQL.with_log/3>, cache_statement: "ecto_insert_visits", timeout: 15000, pool_size: 10, pool: DBConnection.Ownership])
    ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
    (db_connection) lib/db_connection/holder.ex:71: DBConnection.Holder.checkout/2
    (db_connection) lib/db_connection.ex:1030: DBConnection.checkout/3
    (db_connection) lib/db_connection.ex:1340: DBConnection.run/6
    (db_connection) lib/db_connection.ex:540: DBConnection.parsed_prepare_execute/5
    (db_connection) lib/db_connection.ex:533: DBConnection.prepare_execute/4
    (postgrex) lib/postgrex.ex:196: Postgrex.query/4
    (ecto_sql) lib/ecto/adapters/sql.ex:658: Ecto.Adapters.SQL.struct/10
    (ecto) lib/ecto/repo/schema.ex:649: Ecto.Repo.Schema.apply/4
    (ecto) lib/ecto/repo/schema.ex:262: anonymous fn/15 in Ecto.Repo.Schema.do_insert/4
    (elixir) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
    (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Function: #Function<4.97600206/0 in UrlShortenerWeb.LinkController.redirect_url/2>
    Args: []
05:28:21.380 [error] Task #PID<0.441.0> started from #PID<0.439.0> terminating
** (stop) exited in: DBConnection.Holder.checkout(#PID<0.440.0>, [log: #Function<11.104730475/1 in Ecto.Adapters.SQL.with_log/3>, cache_statement: "ecto_insert_visits", timeout: 15000, pool_size: 10, pool: DBConnection.Ownership])
    ** (EXIT) shutdown: "owner #PID<0.439.0> exited"
    (db_connection) lib/db_connection/holder.ex:71: DBConnection.Holder.checkout/2
    (db_connection) lib/db_connection.ex:1030: DBConnection.checkout/3
    (db_connection) lib/db_connection.ex:1340: DBConnection.run/6
    (db_connection) lib/db_connection.ex:540: DBConnection.parsed_prepare_execute/5
    (db_connection) lib/db_connection.ex:533: DBConnection.prepare_execute/4
    (postgrex) lib/postgrex.ex:196: Postgrex.query/4
    (ecto_sql) lib/ecto/adapters/sql.ex:658: Ecto.Adapters.SQL.struct/10
    (ecto) lib/ecto/repo/schema.ex:649: Ecto.Repo.Schema.apply/4
    (ecto) lib/ecto/repo/schema.ex:262: anonymous fn/15 in Ecto.Repo.Schema.do_insert/4
    (elixir) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
    (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Function: #Function<4.97600206/0 in UrlShortenerWeb.LinkController.redirect_url/2>
    Args: []

person Hassan Gharehhasan Loo    schedule 12.07.2019    source แหล่งที่มา


คำตอบ (1)


ฉันจะเพิ่มคำอธิบายเกี่ยวกับความแตกต่างในคำตอบเดิม
person apelsinka223    schedule 12.07.2019
comment
การตั้งค่าแท็ก Aync เป็นเท็จไม่ได้แก้ปัญหา ฉันไม่อยากใช้โหมดแมนนวลเพราะบทความนี้ไม่แนะนำเช่นกัน - person Hassan Gharehhasan Loo; 15.07.2019
comment
เกิดข้อผิดพลาดกับแท็กเหมือนกันใช่ไหม - person apelsinka223; 15.07.2019
comment
ใช่แล้ว มันก็เหมือนกัน - person Hassan Gharehhasan Loo; 17.07.2019
comment
บางทีงานอาจมีเวลาไม่เพียงพอที่จะดำเนินการตามคำขอ ให้ลองเพิ่ม Process.sleep(1000) ในการทดสอบ วิธีที่ดีที่สุดคือการส่งข้อความจากงานและ assert_receive ในการทดสอบเพื่อให้แน่ใจว่างานนั้นเสร็จสิ้น แต่การนอนหลับก็โอเคเช่นกัน - person apelsinka223; 17.07.2019
comment
โดยทั่วไป ฉันไม่คิดว่าจะเพิ่มการนอนหลับในการทดสอบเป็นความคิดที่ดี ซึ่งจะทำให้การทดสอบใช้เวลานานและคาดเดาไม่ได้ - person Hassan Gharehhasan Loo; 29.07.2019
comment
สิ่งที่ฉันทำในกรณีนี้คือแยกงาน ฉีดมันตาม ENV และจำลองมันใน test env เพื่อไม่ให้แทรกลงในฐานข้อมูล - person Hassan Gharehhasan Loo; 29.07.2019