Skip to content

Commit

Permalink
Deprecate Plug.Conn's Collectable protocol implementation (elixir-plu…
Browse files Browse the repository at this point in the history
  • Loading branch information
joaquimadraz authored and josevalim committed Mar 4, 2018
1 parent c17ecd2 commit 963b1f3
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
38 changes: 38 additions & 0 deletions lib/plug/conn.ex
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,23 @@ defmodule Plug.Conn do
It expects a connection with state `:chunked` as set by
`send_chunked/2`. It returns `{:ok, conn}` in case of success,
otherwise `{:error, reason}`.
To stream data use `Enum.reduce_while/3` instead of `Enum.into/2`.
`Enum.reduce_while/3` allows aborting the execution if `chunk/2` fails to
deliver the chunk of data.
## Example
~w(each chunk as a word)
|> Enum.reduce_while(conn, fn (chunk, conn) ->
case Plug.Conn.chunk(conn, chunk) do
{:ok, conn} ->
{:cont, conn}
{:error, :closed} ->
{:halt, conn}
end
end)
"""
@spec chunk(t, body) :: {:ok, t} | {:error, term} | no_return
def chunk(%Conn{adapter: {adapter, payload}, state: :chunked} = conn, chunk) do
Expand Down Expand Up @@ -1356,6 +1373,27 @@ end

defimpl Collectable, for: Plug.Conn do
def into(conn) do
IO.puts(:stderr, """
warning: using Enum.into/2 for conn is deprecated, use Enum.reduce_while/3 instead:
To stream data use `Enum.reduce_while/3` instead of `Enum.into/2`.
`Enum.reduce_while/3` allows aborting the execution if `chunk/2` fails to
deliver the chunk of data.
Example
~w(each chunk as a word)
|> Enum.reduce_while(conn, fn (chunk, conn) ->
case Plug.Conn.chunk(conn, chunk) do
{:ok, conn} ->
{:cont, conn}
{:error, :closed} ->
{:halt, conn}
end
end)
""")

fun = fn
conn, {:cont, x} ->
{:ok, conn} = Plug.Conn.chunk(conn, x)
Expand Down
9 changes: 7 additions & 2 deletions test/plug/conn_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ defmodule Plug.ConnTest do
alias Plug.Conn
alias Plug.ProcessStore

import ExUnit.CaptureIO

test "test adapter builds on connection" do
conn =
Plug.Adapters.Test.Conn.conn(%Plug.Conn{private: %{hello: :world}}, :post, "/hello", nil)
Expand Down Expand Up @@ -360,8 +362,11 @@ defmodule Plug.ConnTest do

test "send_chunked/3 with collectable" do
conn = send_chunked(conn(:get, "/foo"), 200)
conn = Enum.into(~w(hello world), conn)
assert conn.resp_body == "helloworld"

capture_io(:stderr, fn ->
conn = Enum.into(~w(hello world), conn)
assert conn.resp_body == "helloworld"
end)
end

test "send_chunked/3 sends self a message" do
Expand Down

0 comments on commit 963b1f3

Please sign in to comment.