NobbZ

NobbZ

How to get monitor like thing for an `:ssh`-daemon and calm down dialyzer

I’m having a hard time to fix the following dialyzer warnings:

lib/foo.ex:36:pattern_match
The pattern
{:ok, _pid, _ref, _opts}

can never match the type
{:error, _}

issued about a case/2 expression:

case init_daemon(opts) do
  {:error, reason} ->
    {:error, reason}

  {:ok, pid, ref, opts} ->
    {:ok, %{options: opts, deamons: [%{pid: pid, ref: ref, options: opts}]}}
end

Where init_daemon/1 does roughly this and issues a warning for itself because of an opaque type:

lib/foo.ex:161:call_with_opaque
The call :erlang.monitor('process',_pid@1::ssh:daemon_ref()) contains an opaque term in 2nd argument when terms of different types are expected in these positions}.
def init_daemon(_) do # simplified
  daemon = :ssh.daemon(10022, …irrelevant set of options…)

  case daemon do
    {:ok, pid} ->
      ref = Process.monitor(pid)
      {:ok, pid, ref, %{}}

    {:error, reason} ->
      {:error, reason}
  end
end

My current assumption is, that dialyzer assumes, that in init_daemon/1 the :ok branch will never used, as it were violating opaque types, and therefore considers the :ok clause as superfluous in the first case/2 above. As if I temporarily remove the call to Process.monitor/1 and replace it with a static value, dialyzer does not complain anymore.

But how could I fix that? I need a monitor for the daemon process, or at least some monitorlike behaviour.

Most Liked

arnomi

arnomi

Isn’t the issue that :ssh.daemon does not return a pid? From the documentation it returns a

{ok, daemon_ref()} | {error, atom()}

where daemon_ref is some opaque type. Thus, for dialyzer the call to Process.monitor will fail since it expects as input a pid. One option you could try is to “clean up” the daemon ref in a custom function that you mark as returning a pid.

@spec clean_up(any) :: pid
defp clean_up(daemon_ref), do: daemon_ref

This certainly looks ugly. But in case daemon_ref is not always a pid, this would also allow for some error checking.

A second option I could think about is having a guard on the {:ok, pid} branch and rewriting it as {:ok, pid} when is_pid(pid)

I didn’t test any of this, so this is just wild speculation…

Where Next?

Popular in Questions Top

dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement