Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Demonstrate unexpected timeout behaviour when sources are slow #35

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/dataloader.ex
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ defmodule Dataloader do
if pending_batches?(dataloader) do
fun = fn {name, source} -> {name, Source.run(source)} end

# This function behaves unexpectedly when the source times out; it drops
# the source! For example, if we have a single source and it times out,
# `pmap` silently accepts the failure and returns `[]`... which then
# turns our `sources` into an empty map here!
#
sources =
dataloader.sources
|> pmap(
Expand Down
12 changes: 12 additions & 0 deletions test/dataloader_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,16 @@ defmodule DataloaderTest do

assert log =~ "boom"
end

test "fails silently and returns an empty map of sources if things timeout" do
source = %Dataloader.TestSource{}

dataloader =
Dataloader.new(timeout: 1) # Note the short timeout
|> Dataloader.add_source(:test, source)

new_dataloader = Dataloader.run(dataloader)

assert dataloader == new_dataloader
end
end
19 changes: 19 additions & 0 deletions test/support/test_source.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule Dataloader.TestSource do
defstruct [opts: [], batches: [], results: %{}]

defimpl Dataloader.Source do

def load(source, _batch_key, _item_key), do: source

def fetch(_source, _batch_key, _item_key), do: :error

def pending_batches?(_source), do: true

def put(source, _batch_key, _item_key, _item), do: source

def run(source) do
Process.sleep(5) # Just needs to be larger than our Dataloader timeout
source
end
end
end