-
Notifications
You must be signed in to change notification settings - Fork 5
Standalone server #88
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
base: master
Are you sure you want to change the base?
Conversation
93c744e
to
2dcd808
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we spoke, let's remove Boombox.Server
from the public API
lib/boombox/application.ex
Outdated
case System.get_env("RELEASE_NAME") do | ||
"server" -> | ||
node_to_ping = System.get_env("NODE_TO_PING") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we prefix these environment variables with "BOOMBOX_"
, like "BOOMBOX_NODE_TO_PING"
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll prefix NODE_TO_PING
, but RELEASE_NAME
is an internal one and I don't have control over it.
Mode in which Boombox is operating: | ||
* `:consuming` - Boombox consumes packets provided with `consume_packet/2` calls, | ||
`{:consume_packet, packet}` GenServer calls or receiving | ||
`{:call, sender, {:consume_packet, packet}. | ||
* `:producing` - Boombox produces packets in response to `produce_packet/1` calls, | ||
being called directly with `:produce_packet` or receiving | ||
`{:call, sender, :produce_packet}` messages. | ||
* `:standalone` - Boombox neither consumes nor produces packets. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would specify that we are talking about %Boombox.Packet{}
. Boombox.run{input: rtp, output: {:webrtc, signaling})
consumes and produces packets in some way, but they are not %Boombox.Packet{}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a line in the moduledoc comment clarifying that
0363590
to
18be1b9
Compare
18be1b9
to
74dba9f
Compare
@@ -31,8 +31,14 @@ defmodule Boombox.InternalBin.ElixirStream do | |||
|> via_out(Pad.ref(:output, :audio))} | |||
end) | |||
|
|||
audio_options = | |||
case Map.take(options, @options_audio_keys) do | |||
audio_options when map_size(audio_options) == 3 -> audio_options |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not use magic numbers like 3
here
def handle_info(:boombox_demand, ctx, state) do | ||
available_pads = | ||
state.last_pts | ||
|> Enum.reject(fn {kind, _pts} -> ctx.pads[Pad.ref(:input, kind)].end_of_stream? end) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we remove the entry in last_pts
on handle_end_of_stream
instead?
lib/boombox/application.ex
Outdated
node_to_ping = System.get_env("NODE_TO_PING") | ||
|
||
if node_to_ping != nil do | ||
Node.ping(String.to_atom(node_to_ping)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't you want to match the return value of that function?
lib/boombox/application.ex
Outdated
Boombox application. When released as a standalone server will start Boombox.Server under the | ||
supervision tree. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about describing how the user should set RELEASE_NAME
and NODE_TO_PING
?
@@ -31,8 +31,14 @@ defmodule Boombox.InternalBin.ElixirStream do | |||
|> via_out(Pad.ref(:output, :audio))} | |||
end) | |||
|
|||
audio_options = | |||
case Map.take(options, @options_audio_keys) do | |||
audio_options when map_size(audio_options) == 3 -> audio_options |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That 3
looks like a magic number to me, wouldn't it be better to match on particular structure of the audio_options
map?
lib/boombox/internal_bin/hls.ex
Outdated
@@ -61,6 +62,7 @@ defmodule Boombox.InternalBin.HLS do | |||
output_stream_format: %H264{alignment: :au, stream_structure: :avc3}, | |||
transcoding_policy: transcoding_policy | |||
}) | |||
|> child(:hls_video_realtimer, Membrane.Realtimer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it requires some further consideration. We currently use the default HTTPAdaptiveStream.SinkBin
mode
being :vod
.
I am not sure if we want to generate VOD playlist in realtime. Perhaps we should add HLS specific option and either spawn SinkBin with :live
mode and the realtimer, or spawn SinkBin with :vod
and without the realtimer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're right, but I think it's out of scope for this PR, so I'll just revert it.
lib/boombox/server.ex
Outdated
end | ||
|
||
@doc """ | ||
Starts the server for more information see `GenServer.start/3` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starts the server for more information see `GenServer.start/3` | |
Starts the server. | |
For more information see `GenServer.start/3` |
lib/boombox/server.ex
Outdated
def start_link(arg) do | ||
GenServer.start_link(__MODULE__, arg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's get rid of passing arg
to Server.start_link
because it is ignored in init
callback
lib/boombox/server.ex
Outdated
def start(arg) do | ||
GenServer.start(__MODULE__, arg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same as in start_link
def consume_packet(server, packet) do | ||
GenServer.call(server, {:consume_packet, packet}) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure it should be a call, instead of cast or send?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the idea is that this call returns once Boombox is ready to consume a next packet, and is a packpressure mechanism
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get it, but be aware that it adds an additional complexity and it will behave badly when the CPU usage starts hitting max
@impl true | ||
def handle_info({:call, sender, message}, state) do | ||
{:reply, reply, state} = handle_call(message, sender, state) | ||
send(sender, reply) | ||
{:noreply, state} | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Man, this looks weird
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but Pyrlang can communicate only through messages, there's no way to call the GenServer directly from there and I didn't want to use the internal GenServer message structures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So let's move the implementation of these fake GenServer calls to the function that doesn't have handle_call
in the name. It would be misleading to e.g. see errors from handle_call
function that called by handle_info
. What about handle_synchronous_request
?
Beyond that, the second argument in GenServer handle_call
isn't just pid where we should send response.
lib/boombox/server.ex
Outdated
@impl true | ||
def handle_info({:DOWN, _ref, :process, pid, :normal}, %State{boombox_pid: pid} = state) do | ||
{:stop, :normal, state} | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's stop Server
also when reason
is not :normal
, we shouldn't ignore it
|
||
[Boombox.Server] | ||
defp start_server() do | ||
case System.fetch_env("NODE_TO_PING") do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was supposed to be BOOMBOX_NODE_TO_PING
def start_link(_arg) do | ||
GenServer.start_link(__MODULE__, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about def start_link() do
def handle_info({:DOWN, _ref, :process, pid, :normal}, %State{boombox_pid: pid} = state) do | ||
{:stop, :normal, state} | ||
def handle_info({:DOWN, _ref, :process, pid, reason}, %State{boombox_pid: pid} = state) do | ||
{:stop, reason, state} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{:stop, reason, state} | |
reason = | |
case reason do | |
:normal -> :normal | |
reason -> {:boombox_crash, reason} | |
end | |
{:stop, reason, state} |
""" | ||
@spec start(term()) :: GenServer.on_start() | ||
def start(arg) do | ||
GenServer.start(__MODULE__, arg) | ||
def start(_arg) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def start(_arg) do | |
def start() do |
This PR:
:stream
input they are passed to theElixirStream.Source
.ElixirStream.Source
- remembering last format, either passed via options or received in aBoombox.Packet
, and sending stream format if the format changed.Boombox.Server
when running aserver
releaseBoombox.Server
, that allows for running Boombox in a separate process and communicate with it through synchronous functions, GenServer calls and functions.To do: