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

Establish links in the order from the spec #558

Merged
merged 2 commits into from
May 24, 2023
Merged
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
6 changes: 3 additions & 3 deletions lib/membrane/core/parent/child_life_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ defmodule Membrane.Core.Parent.ChildLifeController do
| :linking_externally
| :ready,
children_names: MapSet.t(Child.name()),
links_ids: MapSet.t(Link.id()),
links_ids: [Link.id()],
awaiting_responses: MapSet.t({Link.id(), Membrane.Pad.direction()}),
dependent_specs: MapSet.t(spec_ref())
}
Expand Down Expand Up @@ -158,7 +158,7 @@ defmodule Membrane.Core.Parent.ChildLifeController do
put_in(state, [:pending_specs, spec_ref], %{
status: :initializing,
children_names: MapSet.new(all_children_names),
links_ids: MapSet.new(links, & &1.id),
links_ids: Enum.map(links, & &1.id),
dependent_specs: dependent_specs,
awaiting_responses: MapSet.new()
})
Expand Down Expand Up @@ -634,7 +634,7 @@ defmodule Membrane.Core.Parent.ChildLifeController do

links_ids =
spec_data.links_ids
|> MapSet.difference(removed_links_ids)
|> Enum.reject(&MapSet.member?(removed_links_ids, &1))

awaiting_responses =
spec_data.awaiting_responses
Expand Down
46 changes: 46 additions & 0 deletions test/membrane/integration/linking_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,52 @@ defmodule Membrane.Integration.LinkingTest do
end
end

test "links should be estabilished in the order they are created in the spec" do
defmodule PadsOrderBin do
use Membrane.Bin

def_input_pad :input, availability: :on_request, accepted_format: _any

@impl true
def handle_init(_ctx, _opts), do: {[], %{}}

@impl true
def handle_pad_added(Pad.ref(:input, pad_id), _ctx, state) do
state = Map.update(state, :pads_order, [pad_id], &(&1 ++ [pad_id]))
{[], state}
end

@impl true
def handle_parent_notification(:get_pads_order, _ctx, state) do
answer = {:pads_order, Map.get(state, :pads_order, [])}
{[notify_parent: answer], state}
end
end

for _i <- 1..10 do
pads_ids = Enum.shuffle(1..32)

children = [
child(:element, Element),
child(:bin, PadsOrderBin)
]

links =
Enum.map(pads_ids, fn pad_id ->
get_child(:element)
|> via_in(Pad.ref(:input, pad_id))
|> get_child(:bin)
end)

pipeline = Testing.Pipeline.start_link_supervised!(spec: children ++ links)

Testing.Pipeline.execute_actions(pipeline, notify_child: {:bin, :get_pads_order})
assert_pipeline_notified(pipeline, :bin, {:pads_order, ^pads_ids})

Testing.Pipeline.terminate(pipeline)
end
end

defp assert_link_removed(pipeline, id) do
assert_pipeline_notified(pipeline, :source, {:handle_pad_removed, Pad.ref(:output, ^id)})
assert_pipeline_notified(pipeline, :sink, {:handle_pad_removed, Pad.ref(:input, ^id)})
Expand Down