Releases: membraneframework/membrane_core
v0.11.3
v1.0.0-rc0
Here comes the first release candidate for Membrane Core 1.0! 🎉 This release contains the final API polishing before making it stable and brings a couple of new features. The migration guide, which will help you seamlessly upgrade from 0.11, is available here. We also started the process of migrating all the plugins. Now, let's have a look at the most important changes brought by this release:
Children groups & anonymous children
Let's consider an example when there are a couple of streams and you need to spawn some elements to process each of them, and then put them all into a common sink:
def handle_info({:new_stream, stream_id}, _ctx, state) do
spec =
child({:source, stream_id}, MySource)
|> child({:parser, stream_id}, MyParser)
|> child({:depayloader, stream_id}, MyDepayloader)
|> get_child(:sink)
{[spec: spec], state}
end
Now it's more concise with children groups:
def handle_info({:new_stream, stream_id}, _ctx, state) do
spec =
child(:source, MySource)
|> child(:parser, MyParser)
|> child(:depayloader, MyDepayloader)
|> get_child(:sink)
spec = {spec, group: {:stream, stream_id}}
{[spec: spec], state}
end
And even more concise with anonymous children - from now on, you only have to name a child when you refer to it:
def handle_info({:new_stream, stream_id}, _ctx, state) do
spec = {
child(MySource) |> child(MyParser) |> child(MyDepayloader) |> get_child(:sink),
group: {:stream, stream_id}
}
{[spec: spec], state}
end
Moreover, you can remove the whole group by its name when the stream is no longer available:
def handle_info({:stream_finished, stream_id}, _ctx, state) do
{[remove_children: {:stream, stream_id}], state}
end
Check the docs for details.
Deferring component setup
Sometimes setting up a component requires a lot of work, possibly done asynchronously. Now, you can prevent a component setup from finishing before such asynchronous work is done, without blocking in handle_setup
. It's as simple as marking it as incomplete:
def handle_setup(_ctx, state) do
request_some_async_work(...)
{[setup: :incomplete], state}
end
When the work is finished, just let Membrane know it can proceed:
def handle_info(:done_setup, _ctx, state) do
{[setup: :complete], state}
end
This mechanism works for all components, including pipelines. Therefore, pipelines now automatically switch to playing after they are set up, which is usually desired. If you don't want this to happen, just complete the setup whenever everything is ready. Here are the docs.
Demand units on outputs
From now on, you can specify demand units on both inputs and outputs. If the demand unit on the output doesn't match the one on the linked input, Membrane will take care of recalculating it for you. Thanks to that, all Membrane elements are now compatible and can be linked together, regardless of the demands unit they support! This applies to auto demands as well. Therefore, there's no need to provide demand units in bins anymore.
API improvements
handle_process
andhandle_write
are replaced withhandle_buffer
for better consistency:mode
and:demand_mode
options in pad definition are replaced with:flow_control
, which may be:push
,:auto
or:manual
and defaults to:auto
whenever available (currently in filters, soon in sinks as well)- Callback contexts are now maps instead of structs and they're documented in a single module per component, so it's more straightforward to figure out what they contain
All changes
Breaking changes
- Replace the
playback
action with deferring setup by @FelonEkonom in #496 - Rename handle_write and handle_process to handle_buffer by @FelonEkonom in #506
- Refactor callback contexts by @FelonEkonom in #504
- Unify mode and demand_mode options of pads by @varsill in #508
- Demand units conversion by @varsill in #498
- Rename
Membrane.RemoteControlled.Pipeline
toMembrane.RCPipeline
by @mat-hek in #505 - Update Membrane.Time API by @FelonEkonom in #494
- remove _t suffix from types by @mat-hek in #509
Non-breaking changes
- Children groups and anonymous children by @varsill in #461
- Implement
:remove_link
action by @FelonEkonom in #487 - Add
Membrane.ResourceGuard.cleanup/1
by @FelonEkonom in #477 - Add
Membrane.Testing.Pipeline.get_child_pid/2
@FelonEkonom in #497 - Bump Ratio to 3.0 by @varsill in #438
Bug fixes
- Stop all timers when a component enters zombie mode by @FelonEkonom in #485
- Fix a deadlock when the pipeline spawns a spec entailing two dependent specs in a bin by @mat-hek in #484
- Fix pad docs generation by @mat-hek in #490
- fix subprocess supervisor crash when a child fails in handle_init by @mat-hek in #488
- Docs formatting fixes in children_spec.ex by @bblaszkow06 in #492
- Unlink only existing children on crash group down by @FelonEkonom in #499
- Add
timer_interval_t
toElement.Action.t
by @balins in #502 - Fix RC during unlinking by @FelonEkonom in #500
Full Changelog: v0.11.0...v1.0.0-rc0
v0.11.2
What's Changed
Full Changelog: v0.11.1...v0.11.2
v0.11.1
What's Changed
- add playback related changes to the release guide by @mat-hek in #472
- Put in guide info about updating tuples returned from callbacks by @FelonEkonom in #475
- Implement running all cleanup functions in ResourceGuard by @FelonEkonom in #477
- Updating guide - parent/children communication and childrenspecs by @varsill in #474
- Fix typo by @daniel-jodlos in #481
- Bump Ratio to 3.0 by @varsill in #438
- Stop all timers, when componenet enters zombie mode by @FelonEkonom in #485
- [MC-106] Fix a deadlock when pipeline spawns a spec entailing two dependent specs in a bin by @mat-hek in #484
- Fix pad docs generation by @mat-hek in #490
- fix subprocess supervisor crash when a child fails in handle_init by @mat-hek in #488
Full Changelog: v0.11.0...v0.11.1
v0.11.0
Membrane Core v0.11.0 is now available!
This release includes mostly API improvements. For some of them, breaking changes were necessary. To facilitate migration, we prepared the updating guide that should help adjust your code to the changes.
Breaking changes
Actions
The following actions have changed:
Membrane.Element.Action.caps_t
->Membrane.Element.Action.stream_format_t
(#468)Membrane.Bin.Action.notify_t
->Membrane.Bin.Action.notify_parent_t
(#415)Membrane.Element.Action.notify_t
->Membrane.Element.Action.notify_parent_t
(#415)Membrane.Pipeline.Action.forward_t
->Membrane.Pipeline.Action.notify_child_t
(#415)Membrane.Bin.Action.forward_t
->Membrane.Bin.Action.notify_child_t
(#415)
Callbacks
From now on, the callbacks should return an {actions, state}
tuple. Returning errors is no longer supported - if a component can't recover from an error, it should raise (#471)
Furthermore, the following callbacks have changed:
handle_stopped_to_prepared/2
->handle_setup/2
in all components (#432)Membrane.Element.Base.handle_caps/4
->Membrane.Element.Base.handle_stream_format/4
(#432)handle_element_start_of_stream/3
->handle_element_start_of_stream/4
andhandle_element_end_of_stream/3
->handle_element_end_of_stream/4
in pipelines and bins (#417)handle_init/1
->handle_init/2
in all components (#432)handle_other/3
->handle_info/3
in all components (#415)handle_notification/4
->handle_child_notification/4
in pipelines and bins (#415)
The following callbacks have been removed:
Instead, Membrane.ResourceGuard
, Membrane.UtilitySupervisor
or handle_terminate_request/2
should be used.
What is more, messages sent with the :notify_parent
action (former :notify
action), are handled in a separate handle_parent_notification/3
callback instead of being handled in handle_other/3
, along with messages sent from any other processes. (#415)
Pads definitions
In v0.11
:caps
option passed to def_input_pad/2
or def_output_pad/2
has been deleted. Instead of it, we have added a new option - :accepted_format
. The main principle of these two options is the same - validation of value passed to :caps
or :stream_format
action. While :caps
required a module name or specific tuple format as argument, :accepted_format
requires following types of terms:
-
Elixir pattern - eg.
accepted_format: %My.Custom.Format{field: value} when value in [:some, :enumeration]
The value passed to
:stream_format
action has to match the provided pattern. In this case, the requirement above would
be satisfied by eg.stream_format: %My.Custom.Format{field: :some}
-
Module name - eg.
accepted_format: My.Custom.Format
This would be equal to the match on the struct of the passed module, in this caseaccepted_format: %My.Custom.Format{}
-
Call to
any_of
function - you can pass as many arguments to it, as you want. Each argument should be an Elixir pattern
or a module name, eg.stream_format: any_of(My.Custom.Format, %My.Another.Custom.Format{field: :value})
If you use
any_of
, the value passed to:stream_format
will have to match at least one of the passed
arguments. In this case,stream_format: %My.Custom.Format{frequency: 1}
would be ok, but
stream_format: %My.Another.Custom.Format{field: :not_allowed_value}
would fail
Option :accepted_format
is required. If you don't want to perform any check on stream_format
, you can always write accepted_format: _any
, but it is not suggested.
Checks on stream_format
will be performed on both, intput
and output
pads, just as caps
were checked in those places.
New way to define children
Membrane.Bin.spec_t
andMembrane.Pipeline.spec_t
actions no more acceptMembrane.ParentSpec
structure.
Instead, a tuple with the children structure and options needs to be passed. (#458)- Functions used to spawn children and create links between them, available in the former
Membrane.ParentSpec
module, have been changed - till now on, the children structure needs to be defined with the use ofchild/3
,child/4
,get_child/2
andget_child/3
functions from theMembrane.ChildrenSpec
. (#458) Membrane.ParentSpec.link_bin_input/1
has been renamed toMembrane.ChildrenSpec.bin_input/1
(#458)Membrane.ParentSpec.link_bin_output/2
has been renamed toMembrane.ChildrenSpec.bin_output/2
(#458)
Changes in Membrane.Time
module
Membrane.Time.to_<unit name>/1
has been renamed toMembrane.Time.round_to_<unit name>/1
in order to indicate that the result will be rounded. (#435)
Changes with def_options
macro
- A
:type
field from thedef_options
keyword list has been removed, and the type specification of the option defined within the macro is determined by the:spec
field (#466)
New way to spawn pipeline
Membrane.Pipeline.start/3
andMembrane.Pipeline.start_link/3
now return{:ok, pipeline_supervisor, pipeline}
.(#432)
Changes in Membrane.Testing
Membrane.Testing.Pipeline.start_link/1
has been changed toMembrane.Testing.Pipeline.start_link_supervised!/1
(#432)- The
Membrane.Testing.Pipeline.options()
now have a single:structure
field allowing to specify the test pipeline's children structure, in place of the former:links
and:children
fields.
Other changes:
handle_call/3
callback in the pipeline and areply
and:reply_to
actions. (#334)- Improvements in documentation - till now on, in the documentation page for each of the following modules:
Membrane.Source
,Membrane.Filter
,Membrane.Endpoint
andMembrane.Sink
there is a list of all the callbacks available to be implemented for these modules. Membrane.Time.<plural unit name>/1
now acceptsRatio
structure as an argument. (#435)Membrane.Time.round_to_timebase/2
function has been added. (#435)Membrane.FilterAggregator
that allows running multiple filters sequentially within one process has been added (still experimental) (#355)- Information about the element's playback change is logged as debug, not as debug_verbose. (#430)
Membrane.Testing.MockResourceGuard
has been added, to help write tests with the new way of handling resources. (#478)
Release v0.10.2
What's changed?
Changes that do not affect API
- A bug with the distributed pipeline crashing has been fixed. The pipeline which elements were put on different nodes used to crash due to the fact, that the toilet between the elements was designed to be used by elements running on the same node.
Release v0.10.1
What's changed?
The changes that do not affect API:
- improvements in documentation and exemplary code snippets, concerning the latest changes in API
- the errors in Membrane's core are now raised as exceptions as low as they occur, instead of being propagated up with
{:error, ...}
monads - mechanism for checking if the static pads are unlinked only when the element dies, has been turned off for the further investigation since it's not working properly
- bug fix:
Membrane.Testing.Pipeline
with a custom module injected behaves in a desired way onceMembrane.Testing.Pipeline.execute_actions/2
function is called (the custom module does not need to implementhandle_other({:execute_actions, actions}, ...)
anymore)
Full changelog: v0.10.0 ... v0.10.1
v0.10.0
Release includes:
- removing deprecated stuff #399:
- Support for returning bare
Membrane.ParentSpec{}
fromhandle_init/1
- Support for callbacks without
context
argument inPipeline
andBin
Membrane.Element.WithInputPads.def_input_pads/1
Membrane.Element.WithOutputPads.def_output_pads/1
Membrane.Log.*
Membrane.ParentSpec.link_bin_input/2
Membrane.ParentSpec.to_bin_output/2
- Following functions in
Membrane.Time
:is_t/1
,system_time/0
,native_unit/1
,day/1
,hour/1
,minute/1
,second/1
,millisecond/1
,microsecond/1
,nanosecond/1
- Support for returning bare
- making
Membrane.Pipeline.{prepare, play, stop}
deprecated and adding:playback
action instead - making
Membrane.Pipeline.stop_and_terminate/2
deprecated and addingMembrane.Pipeline.terminate/2
instead - adding the
Membrane.RemoteControlled.Pipeline
- a basic implementation of aMembrane.Pipeline
that
can be spawned and controlled by an external process #366 - disallowing sending buffers through pads without sending the caps first, by raising an
Membrane.ElementError
exception if such a situation occurs #341 - refining the
Membrane.Testing.Pipeline
API - deprecating theMembrane.Testing.Pipeline.Options
usage, allowing to usepipeline_keyword_list_t
as options inMembrane.Testing.Pipeline.start/1
andMembrane.Testing.Pipeline.start_link/1
Full changelog: v0.9.0 ... v0.10.0
v0.9.0 - Automatic demands
Automatic demands
The Membrane Core can now handle the demands in filters for you! 🎉
To enable this, use demand_mode: :auto
in your pad's definition:
def_input_pad :input,
demand_mode: :auto,
caps: :any
This will make the Core send a demand automatically, no need to use :demand
action anymore.
By adding the same option to the output pad, the Core will also handle any incoming demands and demands on all input pads, so it is suitable for cases when a filter consumes data from all inputs uniformly.
See how automatic demands are used in funnel
What's Changed
- Automatic demands #313
- Stop forwarding notifications by default in bins #358
- More fine-grained control over emitted metrics #365
- Added log metadata when reporting init in telemetry #376
- Fix generation of pad documentation inside an element #377
- Leaving static pads unlinked and transiting to a playback state other than
:stopped
will result
in runtime error (previously only a warning was printed out). #389 - It is possible now to assert on crash group down when using Testing.Pipeline. #391
Full Changelog: v0.8.2...v0.9.0