Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into refactor-closing-is…
Browse files Browse the repository at this point in the history
…sue-message
  • Loading branch information
FelonEkonom committed Oct 18, 2023
2 parents 73e73b3 + d0680e9 commit 59a152f
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 0 deletions.
181 changes: 181 additions & 0 deletions guides/upgrading/v1.0.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Upgrading to v1.0.0

Comparing to v0.12, v1.0.0 introduces some minor changes in the public API of the framework. This guide was created to help you migrate to v1.0.0 of `membrane_core`.

### Deps

Update `membrane_core` to `v1.0.0`
```elixir
defp deps do
[
{:membrane_core, "~> 1.0.0"},
...
]
end
```

### Rename `handle_process/4` and `handle_write/4` into `handle_buffer/4`

Names of the callbacks that are used to process buffers have been unified. This applies to:
* _Membrane.Filter.handle_process/4_
* _Membrane.Endpoint.handle_write/4_
* _Membrane.Sink.handle_write/4_

and they became `c:Membrane.Element.WithInputPads.handle_buffer/4`

```diff
@impl true
- def handle_process(pad, buffer, ctx, state) do
+ def handle_buffer(pad, buffer, ctx, state) do
...
end
```

### Remove `handle_process_list/4` and `handle_write_list/4` callback

Since `v1.0.0`, you have to handle every single buffer separately in `handle_buffer/4` callback, instead of handling whole list of buffers in this in `handle_process_list/4` or `handle_write_list/4`.

```diff
@impl true
- def handle_process_list(pad_ref, buffers_list, ctx, state) do
+ def handle_buffer(pad_ref, buffer, ctx, state) do
...
end
```

```diff
@impl true
- def handle_write_list(pad_ref, buffers_list, ctx, state) do
+ def handle_buffer(pad_ref, buffer, ctx, state) do
...
end
```

### Change `mode` and `demand_mode` options to `flow_control` in pads' definitions in elements

For input pads, change:

```diff
use Membrane.Filter
# or Sink or Endpoint

- def_input_pad :input, mode: :push, ...
+ def_input_pad :input, flow_control: :push, ...

- def_input_pad :input, mode: :pull, demand_mode: :auto, demand_unit: :buffers, ...
+ def_input_pad :input, ...
# (because `flow_control: :auto` is the default whenever available - currently in Filters)
# Note that having `flow_control: :auto` doesn't allow to pass `demand_unit`,
# as it's determined automatically

- def_input_pad :input, mode: :pull, demand_unit: :buffers, ...
+ def_input_pad :input, flow_control: :manual, demand_unit: :buffers, ...
```

Same goes for output pads:

```diff
use Membrane.Filter
# or Source or Endpoint

- def_output_pad :output, mode: :push, ...
+ def_output_pad :output, flow_control: :push, ...

- def_output_pad :output, mode: :pull, demand_mode: :auto, ...
+ def_output_pad :output, ...

- def_output_pad :output, mode: :pull, ...
+ def_output_pad :output, flow_control: :manual, ...
```

Check `t:Membrane.Pad.element_spec/0` for details.

### Remove `mode` and `demand_unit` from pads definitions in bins

```diff
use Membrane.Bin

- def_input_pad :input, mode: :pull, demand_unit: :buffers, ...
+ def_input_pad :input, ...

- def_output_pad :output, mode: :push, ...
+ def_output_pad :output, ...
```

Check `t:Membrane.Pad.bin_spec/0` for details.

### Don't refer to callback contexts as to structs

Callback contexts are now plain maps instead of structs. So, for example, if you happen to have a match like below, convert it to a match on a map:

```diff
@impl true
- def handle_info(message, %Membrane.Element.CallbackContext.Info{pads: pads}, state) do
+ def handle_info(message, %{pads: pads}, state) do
...
end
```

Additionally, there's no `direction` field anymore in the callback context for `handle_pad_added` and `handle_pad_removed` - the direction can be determined by the pad name. All other fields remain the same.

```diff
@impl true
- def handle_pad_added(_pad, %{direction: :input}, state) do
+ def handle_pad_added(Pad.ref(:input, _id), _ctx, state) do
...
end
```

Check `t:Membrane.Element.CallbackContext.t/0`, `t:Membrane.Bin.CallbackContext.t/0` and `t:Membrane.Pipeline.CallbackContext.t/0` for outline of what can be found in the contexts. Additionally, each callback that provides extra fields in the context, has them mentioned in its docs.

### Use `Membrane.RCPipeline` instead of `Membrane.RemoteControlled.Pipeline`

```diff
- pipeline = Membrane.RemoteControlled.Pipeline.start_link!()
+ pipeline = Membrane.RCPipeline.start_link!()
```

Same goes for `Membrane.RemoteControlled.Message` -> `Membrane.RCMessage`

```diff
receive do
- %Membrane.RemoteControlled.Message.Notification{data: data} -> data
+ %Membrane.RCMessage.Notification{data: data} -> data
end
```

### Use `Membrane.Time.as_<unit>(time, :round)` instead of `Membrane.Time.round_to_<unit>(time)`

```diff
- Membrane.Time.round_to_milliseconds(time)
+ Membrane.Time.as_milliseconds(time, :round)
```

There is one exception for `round_to_timebase`, which changed to `divide_by_timebase`:
```diff
- Membrane.Time.round_to_timebase(time, timebase)
+ Membrane.Time.divide_by_timebase(time, timebase)
```

Check `Membrane.Time` for details.

### Implement you own `start/*`, `start_link/*` or `terminate/1` function (if you want to)

Until `v1.0.0-rc0` and `v0.12`, Membrane has generated `start/2`, `start_link/2`, and `terminate/1` functions in modules using `Membrane.Pipeline`, if code developer hadn't done it explicitly. Since `v1.0.0`, if you want to have these functions implemented in your pipeline module, you have to implement them on your own. Alternatively, you can always call `Membrane.Pipeline.start(YourPipelineModule, init_arg, opts)`, `Membrane.Pipeline.start_link(YourPipelineModule, init_arg, opts)`, and `Membrane.Pipeline.terminate(pipeline_pid)` from beyond `YourPipelineModule` without wrapping it into public functions.

### Rename `:structure` option passed to the `Membrane.Testing.Pipeline` into `:spec`

```diff
import Membrane.ChildrenSpec

spec =
child(:source, %Membrane.Testing.Source{some_field: some_arg})
|> child(:sink), %Membrane.Testing.Sink{another_filed: another_arg}

- pipeline = Membrane.Testing.Pipeline.start_link_supervised(structure: spec)
+ pipeline = Membrane.Testing.Pipeline.start_link_supervised(spec: spec)
```

### Adjust to possibility of receiving `end of stream` on pads, that haven't received `start of stream` yet.

Since `v1.0.0`, Membrane will execute `c:Membrane.Element.WithInputPads.handle_end_of_stream/3` for all pads, including these having `start_of_stream?: false`.
1 change: 1 addition & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ defmodule Membrane.Mixfile do
"guides/upgrading/v0.12.md",
"guides/upgrading/v1.0.0-rc0.md",
"guides/upgrading/v1.0.0-rc1.md",
"guides/upgrading/v1.0.0.md",
LICENSE: [title: "License"]
],
formatters: ["html"],
Expand Down

0 comments on commit 59a152f

Please sign in to comment.