Introduce DBConnection.Stage - #82
Conversation
2d45577 to
7e90431
Compare
|
I have updated this to use a documented and generic |
|
@fishcakez beautiful! ❤️ I don't see though how it can be used as a producer_consumer or consumer though. Is it somehow executing the query with the producer_consumer/consumer events? |
|
A start = fn(conn) ->
# prepare query/stream to use when handling events (init stage)
copy_query = Postgrex.prepare!(conn, "copy", "COPY table FROM STDIN", [])
Postgrex.stream(conn, copy_query, [])
end
## this is a consumer, so takes in events and returns `{[], state}`
handle = fn(conn, events, copy_stream) ->
{[], for event <- events, do: encode(event), into: copy_stream}
end
## close the query (undo start function)
stop = fn(conn, _reason, %DBConnection.Stream{query: copy_query}) ->
Postgrex.close!(conn, copy_query)
end
DBConnection.Stage.start_link(pool, :consumer, start, handle, stop)A start = fn(conn) ->
# prepare query to use handling events (init stage)
Postgrex.prepare!(conn, "insert", "INSERT INTO table (id, value) VALUES (DEFAULT, $1) RETURNING id", [])
end
## this is a producer_consumer, so takes in events and returns `{events, state}`
handle = fn(conn, values, insert_query) ->
ids = for value <- values do
%{rows: [id]} = Postgrex.execute!(conn, insert_query, [value])
id
end
{ids, insert_query}
end
## close the query (undo start function)
stop = fn(conn, _reason, insert_query) ->
Postgrex.close!(conn, insert_query)
end
DBConnection.Stage.start_link(pool, :producer_consumer, start, handle, stop)
|
|
@fishcakez perfect, thank you! |
| ### Options | ||
|
|
||
| * `:stream_mapper` - A function to flat map the results of the query, either | ||
| a 2-arity fun, `{module, function, args}` with `DBConnection.t` and the |
There was a problem hiding this comment.
Four spaces (counting from the doc marker) for paragraphs that belong to the bullet.
e5c01f5 to
845b46c
Compare
|
When having a "continuation" style transaction we want to be able to not raise when |
|
Does it mean we need to change Repo.transaction in Ecto or can we still
raise there?
If we can't raise still, would it be a breaking change since we only return
{:error, :rollback} if the user calls Repo.rollback? Although I guess
anything could call Repo.rollback and return {:error, :rollback} so I would
say that's ok?
--
*José Valimwww.plataformatec.com.br
<http://www.plataformatec.com.br/>Founder and Director of R&D*
|
We wouldn't be able to change it there because we can't tell why
While it is not the only way I think it is a breaking change because users may be rescuing the DBConnection.ConnectionError (current behaviour), and not handling We can resolve this by requiring a |
I think we actually need to go with requiring a continue function so we can force check in on exceptions, otherwise we may end up in situations where we close connections because the caller crashes or does not checkin. |
|
Closed in favour of #87 so this can be implemented in Ecto itself. |
Needs more tests but this is a first attempt at a streaming
GenStageproducer targetingFlowusage. Notice that there isflat_mapoption so we can preload inEctoand currently only supports a single stream.