Compare commits

...
6 Commits
Author SHA1 Message Date
Vishal ddc554a7ef Fix typo in changelog (#8114)
beind => being
2018-08-19 13:54:25 +02:00
Arkadiusz Gil b6d27b5333 Ignore unknown child info in Logger.Translator (#7892)
This prevents Logger application from crashing when supervisors report
children progress with fields unknown to Logger.Translator.

Closes #7889

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2018-07-12 20:20:08 +02:00
YMasuo 2e54537524 Fix typo on mix run docs (#7840)
ant -> and
2018-07-08 13:11:57 +02:00
José Valim 0d8fa1a0ff Add missing backtick to logger docs
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2018-06-23 19:12:17 +02:00
Unai Esteibar 764d0c1008 Take into account structs from stale local deps (#7776)
Closes #7765
2018-06-21 17:53:53 +02:00
José Valim 5f86d6158b Document long running processes pitfall in mix cmd, closes #7495 2018-06-21 12:55:35 +02:00
7 changed files with 59 additions and 8 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ The Elixir codebase itself has been already fully formatted and all further cont
Supervisors in Elixir are responsible for starting, shutting down and restarting child process when things go wrong. Most of the interaction with supervisors happen with the Supervisor module and it contains three main strategies: `:one_for_one`, `:rest_for_one` and `:one_for_all`.
However, sometimes the children of a supervisor are not known upfront and are rather started dynamically. For example, if you are building a web server, you have each request beind handled by a separate supervised process. Those cases were handled in the Supervisor module under a special strategy called `:simple_one_for_one`.
However, sometimes the children of a supervisor are not known upfront and are rather started dynamically. For example, if you are building a web server, you have each request being handled by a separate supervised process. Those cases were handled in the Supervisor module under a special strategy called `:simple_one_for_one`.
Unfortunately, this special strategy changed the semantics of the supervisor in regards to initialization and shutdown. Plus some APIs expected different inputs or would be completely unavailable depending on the supervision strategy.
+1 -1
View File
@@ -117,7 +117,7 @@ defmodule Port do
reimplementing core part of the Runtime System, such as the `:user` and
`:shell` processes.
## Zombie processes
## Zombie OS processes
A port can be closed via the `close/1` function or by sending a `{pid, :close}`
message. However, if the VM crashes, a long-running program started by the port
+5 -1
View File
@@ -14,7 +14,7 @@ defmodule Logger.Translator do
* `min_level` - the current Logger level
* `level` - the level of the message being translated
* `kind` - if the message is a `:report` or `:format`
* `message` - the message to format. If it is :report`, it is a tuple
* `message` - the message to format. If it is `:report`, it is a tuple
with `{report_type, report_data}`, if it is `:format`, it is a
tuple with `{format_message, format_args}`.
@@ -331,6 +331,10 @@ defmodule Logger.Translator do
["\nStart Module: ", inspect(mod) | child_debug(min_level, debug)]
end
defp child_info(_min_level, _child) do
[]
end
defp child_debug(:debug, restart_type: restart, shutdown: shutdown, child_type: type) do
["\nRestart: ", inspect(restart), "\nShutdown: ", inspect(shutdown)] ++
["\nType: ", inspect(type)]
+7 -1
View File
@@ -84,7 +84,13 @@ defmodule Mix.Compilers.Elixir do
stale_local_deps = stale_local_deps(manifest, modified)
{modules, structs, changed} =
update_stale_entries(all_modules, all_sources, removed ++ changed, stale_local_deps, %{})
update_stale_entries(
all_modules,
all_sources,
removed ++ changed,
stale_local_deps,
stale_local_deps
)
stale = changed -- removed
+12
View File
@@ -18,6 +18,18 @@ defmodule Mix.Tasks.Cmd do
mix cmd --app app1 --app app2 echo pwd
Aborts when a command exits with a non-zero status.
## Zombie OS processes
Beware that the Erlang VM does not terminate child processes
when it shuts down. Therefore, if you use `mix cmd` to start
long running processes and then shutdown the VM, it is likely
that those child processes won't be terminated with the VM.
A solution is to make sure the child processes listen to the
stdndard input and terminate when standard input is closed.
We discuss this topic at length in the "Zombie OS processes"
of the `Port` module documentation.
"""
def run(args) do
+1 -1
View File
@@ -7,7 +7,7 @@ defmodule Mix.Tasks.Run do
Starts and runs the current application.
`mix run` can be used to start the current application dependencies
ant the application itself. For long running systems, this is typically
and the application itself. For long running systems, this is typically
done with the `--no-halt` option:
mix run --no-halt
+32 -3
View File
@@ -326,7 +326,7 @@ defmodule Mix.UmbrellaTest do
end
end
test "recompiles after path dependency changes" do
test "recompiles after runtime path dependency changes" do
in_fixture("umbrella_dep/deps/umbrella/apps", fn ->
Mix.Project.in_project(:bar, "bar", fn _ ->
Mix.Task.run("compile", ["--verbose"])
@@ -360,22 +360,51 @@ defmodule Mix.UmbrellaTest do
# Noop for runtime dependencies
mtime = File.stat!("_build/dev/lib/bar/.mix/compile.elixir").mtime
ensure_touched("_build/dev/lib/foo/ebin/Elixir.Foo.beam", mtime)
mtime = File.stat!("_build/dev/lib/bar/.mix/compile.elixir").mtime
ensure_touched("_build/dev/lib/foo/.mix/compile.elixir", mtime)
assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:noop, []}
end)
end)
end
test "recompiles after compile time path dependency changes" do
in_fixture("umbrella_dep/deps/umbrella/apps", fn ->
Mix.Project.in_project(:bar, "bar", fn _ ->
Mix.Task.run("compile", ["--verbose"])
# Add compile time dependency
File.write!("lib/bar.ex", "defmodule Bar, do: Foo.foo")
assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:ok, []}
assert_receive {:mix_shell, :info, ["Compiled lib/bar.ex"]}
# Recompiles for compile time dependencies
mtime = File.stat!("_build/dev/lib/bar/.mix/compile.elixir").mtime
ensure_touched("_build/dev/lib/foo/ebin/Elixir.Foo.beam", mtime)
ensure_touched("_build/dev/lib/foo/.mix/compile.elixir", mtime)
assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:ok, []}
assert_receive {:mix_shell, :info, ["Compiled lib/bar.ex"]}
end)
end)
end
test "recompiles after struct path dependency changes" do
in_fixture("umbrella_dep/deps/umbrella/apps", fn ->
Mix.Project.in_project(:bar, "bar", fn _ ->
File.write!("../foo/lib/foo.ex", "defmodule Foo, do: defstruct [:bar]")
Mix.Task.run("compile", ["--verbose"])
# Add struct dependency
File.write!("lib/bar.ex", "defmodule Bar, do: %Foo{bar: true}")
assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:ok, []}
assert_receive {:mix_shell, :info, ["Compiled lib/bar.ex"]}
# Recompiles for struct dependencies
mtime = File.stat!("_build/dev/lib/bar/.mix/compile.elixir").mtime
ensure_touched("_build/dev/lib/foo/ebin/Elixir.Foo.beam", mtime)
ensure_touched("_build/dev/lib/foo/.mix/compile.elixir", mtime)
assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:ok, []}