Skip to content

Commit ce227e0

Browse files
authored
Allow client to retry when specified (#337)
1 parent 6c3d35c commit ce227e0

File tree

5 files changed

+338
-102
lines changed

5 files changed

+338
-102
lines changed

integration_test/cases/execute_test.exs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,66 @@ defmodule ExecuteTest do
348348
] = A.record(agent)
349349
end
350350

351+
test "execute disconnect_and_retry succeeds" do
352+
err = RuntimeError.exception("oops")
353+
354+
stack = [
355+
{:ok, :state},
356+
{:disconnect_and_retry, err, :state},
357+
:ok,
358+
fn opts ->
359+
send(opts[:parent], :reconnected)
360+
{:ok, :new_state}
361+
end,
362+
{:ok, %Q{}, %R{}, :new_state}
363+
]
364+
365+
{:ok, agent} = A.start_link(stack)
366+
367+
opts = [agent: agent, parent: self()]
368+
{:ok, pool} = P.start_link(opts)
369+
assert P.execute(pool, %Q{}, [:param]) == {:ok, %Q{}, %R{}}
370+
371+
assert_receive :reconnected
372+
373+
assert [
374+
connect: [opts2],
375+
handle_execute: [%Q{}, [:param], _, :state],
376+
disconnect: [^err, :state],
377+
connect: [opts2],
378+
handle_execute: [%Q{}, [:param], _, :new_state]
379+
] = A.record(agent)
380+
end
381+
382+
test "execute disconnect_and_retry errors if there are no retries" do
383+
err = RuntimeError.exception("oops")
384+
385+
stack = [
386+
{:ok, :state},
387+
{:disconnect_and_retry, err, :new_state},
388+
:ok,
389+
fn opts ->
390+
send(opts[:parent], :reconnected)
391+
{:ok, :state}
392+
end
393+
]
394+
395+
{:ok, agent} = A.start_link(stack)
396+
397+
opts = [agent: agent, parent: self()]
398+
{:ok, pool} = P.start_link(opts)
399+
assert P.execute(pool, %Q{}, [:param], checkout_retries: 0) == {:error, err}
400+
401+
assert_receive :reconnected
402+
403+
assert [
404+
connect: [opts2],
405+
handle_execute: [%Q{}, [:param], _, :state],
406+
disconnect: [^err, :new_state],
407+
connect: [opts2]
408+
] = A.record(agent)
409+
end
410+
351411
test "execute bad return raises DBConnection.ConnectionError and stops" do
352412
stack = [
353413
fn opts ->

integration_test/cases/prepare_execute_test.exs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,39 @@ defmodule PrepareExecuteTest do
496496
] = A.record(agent)
497497
end
498498

499+
test "prepare_execute execute disconnect_and_retry succeeds" do
500+
err = RuntimeError.exception("oops")
501+
502+
stack = [
503+
{:ok, :state},
504+
{:disconnect_and_retry, err, :state},
505+
:ok,
506+
fn opts ->
507+
send(opts[:parent], :reconnected)
508+
{:ok, :new_state}
509+
end,
510+
{:ok, %Q{}, :newer_state},
511+
{:ok, %Q{state: :executed}, %R{}, :newest_state}
512+
]
513+
514+
{:ok, agent} = A.start_link(stack)
515+
516+
opts = [agent: agent, parent: self()]
517+
{:ok, pool} = P.start_link(opts)
518+
assert P.prepare_execute(pool, %Q{}, [:param]) == {:ok, %Q{state: :executed}, %R{}}
519+
520+
assert_receive :reconnected
521+
522+
assert [
523+
connect: [opts2],
524+
handle_prepare: [%Q{}, _, :state],
525+
disconnect: [^err, :state],
526+
connect: [opts2],
527+
handle_prepare: [%Q{}, _, :new_state],
528+
handle_execute: [%Q{}, [:param], _, :newer_state]
529+
] = A.record(agent)
530+
end
531+
499532
test "prepare_execute describe or encode raises and closes query" do
500533
stack = [
501534
{:ok, :state},

integration_test/cases/transaction_test.exs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,70 @@ defmodule TransactionTest do
435435
] = A.record(agent)
436436
end
437437

438+
test "transaction begin disconnect_and_retry succeeds" do
439+
err = RuntimeError.exception("oops")
440+
441+
stack = [
442+
{:ok, :state},
443+
{:disconnect_and_retry, err, :state},
444+
:ok,
445+
fn opts ->
446+
send(opts[:parent], :reconnected)
447+
{:ok, :new_state}
448+
end,
449+
{:ok, :began, :newer_state},
450+
{:ok, :committed, :newest_state}
451+
]
452+
453+
{:ok, agent} = A.start_link(stack)
454+
455+
opts = [agent: agent, parent: self()]
456+
{:ok, pool} = P.start_link(opts)
457+
assert P.transaction(pool, fn _ -> :ok end) == {:ok, :ok}
458+
assert_receive :reconnected
459+
460+
assert [
461+
connect: [_],
462+
handle_begin: [_, :state],
463+
disconnect: [_, :state],
464+
connect: [_],
465+
handle_begin: [_, :new_state],
466+
handle_commit: [_, :newer_state]
467+
] = A.record(agent)
468+
end
469+
470+
test "transaction begin disconnect_and_retry errors if there are no retries" do
471+
err = RuntimeError.exception("oops")
472+
473+
stack = [
474+
{:ok, :state},
475+
{:disconnect_and_retry, err, :new_state},
476+
:ok,
477+
fn opts ->
478+
send(opts[:parent], :reconnected)
479+
{:ok, :newest_state}
480+
end
481+
]
482+
483+
{:ok, agent} = A.start_link(stack)
484+
485+
opts = [agent: agent, parent: self()]
486+
{:ok, pool} = P.start_link(opts)
487+
488+
assert_raise RuntimeError, "oops", fn ->
489+
P.transaction(pool, fn _ -> flunk("transaction ran") end, checkout_retries: 0)
490+
end
491+
492+
assert_receive :reconnected
493+
494+
assert [
495+
connect: [_],
496+
handle_begin: [_, :state],
497+
disconnect: [_, :new_state],
498+
connect: [_]
499+
] = A.record(agent)
500+
end
501+
438502
test "transaction begin bad return raises and stops connection" do
439503
stack = [
440504
fn opts ->

0 commit comments

Comments
 (0)