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

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
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
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call t...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 48475 226
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
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
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43806 214
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39523 209
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New

We're in Beta

About us Mission Statement