Skip to content

Commit cbeb3ba

Browse files
committed
Add Flow.child_spec/1
1 parent cd76152 commit cbeb3ba

File tree

2 files changed

+74
-37
lines changed

2 files changed

+74
-37
lines changed

lib/flow.ex

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -307,25 +307,38 @@ defmodule Flow do
307307
308308
Flow allows computations to be started as a group of processes
309309
which may run indefinitely. This can be done by starting
310-
the flow as part of a supervision tree using `Flow.start_link/2`.
311-
312-
Since Elixir v1.5, the easiest way to add Flow to your supervision
313-
tree is by calling `use Flow` and then defining a `start_link/1`.
310+
the flow as part of a supervision tree using `{Flow, your_flow}`
311+
as your child specification:
312+
313+
children = [
314+
{Flow,
315+
Flow.from_stages(...)
316+
|> Flow.flat_map(&String.split(&1, " "))
317+
|> Flow.reduce(fn -> %{} end, fn word, acc ->
318+
Map.update(acc, word, 1, & &1 + 1)
319+
end)}
320+
]
321+
322+
It is also possible to move a Flow to its own module. This is done by
323+
calling `use Flow` and then defining a `start_link/1` function that
324+
calls `Flow.start_link/1` at the end:
314325
315326
defmodule MyFlow do
316327
use Flow
317328
318329
def start_link(_) do
319330
Flow.from_stages(...)
320-
|> ...
321-
|> ...
322-
|> ...
331+
|> Flow.flat_map(&String.split(&1, " "))
332+
|> Flow.reduce(fn -> %{} end, fn word, acc ->
333+
Map.update(acc, word, 1, & &1 + 1)
334+
end)
323335
|> Flow.start_link()
324336
end
325337
end
326338
327-
The `:shutdown` and `:restart` child spec configurations can be
328-
given to `use Flow`.
339+
By the default the `Flow` is permanent, which means it is always
340+
restarted. The `:shutdown` and `:restart` child spec configurations
341+
can be given to `use Flow`.
329342
330343
Flow also provides integration with `GenStage`, allowing you to
331344
specify child specifications of producers, producer consumers, and
@@ -494,6 +507,14 @@ defmodule Flow do
494507
end
495508
end
496509

510+
@doc false
511+
def child_spec(%Flow{} = arg) do
512+
%{
513+
id: __MODULE__,
514+
start: {__MODULE__, :start_link, [arg]}
515+
}
516+
end
517+
497518
## Building
498519

499520
@doc """

test/flow_test.exs

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,22 @@ defmodule FlowTest do
9999
end
100100
end
101101

102+
test "child_spec/2" do
103+
parent = self()
104+
105+
start_supervised!(
106+
{Flow,
107+
Flow.from_enumerables([[1, 2, 3], [4, 5, 6]], stages: 2)
108+
|> Flow.filter(&(rem(&1, 2) == 0))
109+
|> Flow.map(&send(parent, &1))}
110+
)
111+
112+
assert_receive 2
113+
assert_receive 4
114+
assert_receive 6
115+
refute_received 1
116+
end
117+
102118
describe "errors" do
103119
test "on multiple reduce calls" do
104120
message = ~r"cannot call group_by/reduce/emit_and_reduce on a flow after another"
@@ -777,8 +793,8 @@ defmodule FlowTest do
777793
assert_receive {:consumed, [2]}
778794
assert_receive {:consumed, [4]}
779795
assert_receive {:consumed, [6]}
780-
assert_receive {:consumed, '\b'}
781-
assert_receive {:consumed, '\n'}
796+
assert_receive {:consumed, [8]}
797+
assert_receive {:consumed, [10]}
782798
end
783799

784800
test "into_stages/3 with :name", config do
@@ -805,19 +821,19 @@ defmodule FlowTest do
805821

806822
assert_receive {:producer_consumed, [2]}
807823
assert_receive {:producer_consumed, [6]}
808-
assert_receive {:producer_consumed, '\b'}
824+
assert_receive {:producer_consumed, [8]}
809825
assert_receive {:producer_consumed, [1]}
810826
assert_receive {:producer_consumed, [5]}
811-
assert_receive {:producer_consumed, '\a\t'}
827+
assert_receive {:producer_consumed, ~c"\a\t"}
812828
assert_receive {:producer_consumed, [3]}
813829
assert_receive {:producer_consumed, [4]}
814-
assert_receive {:producer_consumed, '\n'}
830+
assert_receive {:producer_consumed, [10]}
815831

816832
assert_receive {:producer_consumed, [2]}
817833
assert_receive {:producer_consumed, [6]}
818-
assert_receive {:producer_consumed, '\b'}
834+
assert_receive {:producer_consumed, [8]}
819835
assert_receive {:producer_consumed, [4]}
820-
assert_receive {:producer_consumed, '\n'}
836+
assert_receive {:producer_consumed, [10]}
821837
end
822838

823839
test "through_stages/3 + into_stages/3" do
@@ -833,25 +849,25 @@ defmodule FlowTest do
833849

834850
assert_receive {:producer_consumed, [2]}
835851
assert_receive {:producer_consumed, [6]}
836-
assert_receive {:producer_consumed, '\b'}
852+
assert_receive {:producer_consumed, [8]}
837853
assert_receive {:producer_consumed, [1]}
838854
assert_receive {:producer_consumed, [5]}
839-
assert_receive {:producer_consumed, '\a\t'}
855+
assert_receive {:producer_consumed, ~c"\a\t"}
840856
assert_receive {:producer_consumed, [3]}
841857
assert_receive {:producer_consumed, [4]}
842-
assert_receive {:producer_consumed, '\n'}
858+
assert_receive {:producer_consumed, [10]}
843859

844860
assert_receive {:producer_consumed, [2]}
845861
assert_receive {:producer_consumed, [6]}
846-
assert_receive {:producer_consumed, '\b'}
862+
assert_receive {:producer_consumed, [8]}
847863
assert_receive {:producer_consumed, [4]}
848-
assert_receive {:producer_consumed, '\n'}
864+
assert_receive {:producer_consumed, [10]}
849865

850866
assert_receive {:consumed, [2]}
851867
assert_receive {:consumed, [6]}
852-
assert_receive {:consumed, '\b'}
868+
assert_receive {:consumed, [8]}
853869
assert_receive {:consumed, [4]}
854-
assert_receive {:consumed, '\n'}
870+
assert_receive {:consumed, [10]}
855871
end
856872

857873
test "into_specs/3" do
@@ -863,8 +879,8 @@ defmodule FlowTest do
863879
assert_receive {:consumed, [2]}
864880
assert_receive {:consumed, [4]}
865881
assert_receive {:consumed, [6]}
866-
assert_receive {:consumed, '\b'}
867-
assert_receive {:consumed, '\n'}
882+
assert_receive {:consumed, [8]}
883+
assert_receive {:consumed, [10]}
868884
end
869885

870886
test "into_specs/3 with :name", config do
@@ -886,19 +902,19 @@ defmodule FlowTest do
886902

887903
assert_receive {:producer_consumed, [2]}
888904
assert_receive {:producer_consumed, [6]}
889-
assert_receive {:producer_consumed, '\b'}
905+
assert_receive {:producer_consumed, [8]}
890906
assert_receive {:producer_consumed, [1]}
891907
assert_receive {:producer_consumed, [5]}
892-
assert_receive {:producer_consumed, '\a\t'}
908+
assert_receive {:producer_consumed, ~c"\a\t"}
893909
assert_receive {:producer_consumed, [3]}
894910
assert_receive {:producer_consumed, [4]}
895-
assert_receive {:producer_consumed, '\n'}
911+
assert_receive {:producer_consumed, [10]}
896912

897913
assert_receive {:producer_consumed, [2]}
898914
assert_receive {:producer_consumed, [6]}
899-
assert_receive {:producer_consumed, '\b'}
915+
assert_receive {:producer_consumed, [8]}
900916
assert_receive {:producer_consumed, [4]}
901-
assert_receive {:producer_consumed, '\n'}
917+
assert_receive {:producer_consumed, [10]}
902918
end
903919

904920
test "through_specs/3 + into_specs/3" do
@@ -910,25 +926,25 @@ defmodule FlowTest do
910926

911927
assert_receive {:producer_consumed, [2]}
912928
assert_receive {:producer_consumed, [6]}
913-
assert_receive {:producer_consumed, '\b'}
929+
assert_receive {:producer_consumed, [8]}
914930
assert_receive {:producer_consumed, [1]}
915931
assert_receive {:producer_consumed, [5]}
916-
assert_receive {:producer_consumed, '\a\t'}
932+
assert_receive {:producer_consumed, ~c"\a\t"}
917933
assert_receive {:producer_consumed, [3]}
918934
assert_receive {:producer_consumed, [4]}
919-
assert_receive {:producer_consumed, '\n'}
935+
assert_receive {:producer_consumed, [10]}
920936

921937
assert_receive {:producer_consumed, [2]}
922938
assert_receive {:producer_consumed, [6]}
923-
assert_receive {:producer_consumed, '\b'}
939+
assert_receive {:producer_consumed, [8]}
924940
assert_receive {:producer_consumed, [4]}
925-
assert_receive {:producer_consumed, '\n'}
941+
assert_receive {:producer_consumed, [10]}
926942

927943
assert_receive {:consumed, [2]}
928944
assert_receive {:consumed, [6]}
929-
assert_receive {:consumed, '\b'}
945+
assert_receive {:consumed, [8]}
930946
assert_receive {:consumed, [4]}
931-
assert_receive {:consumed, '\n'}
947+
assert_receive {:consumed, [10]}
932948
end
933949
end
934950

0 commit comments

Comments
 (0)