I would like to send messages from an external script to a running Elixir app. The script should be short-lived and terminate immediately after forwarding the message. It could of course be written in Elixir too and they’ll run on the same server.
I hope your document root is not pointed at /var/www
You have directory listing and all the other nice stuff disabled with the default apache or another unix handler
For the future please create a specific user for your projects, applications, scripts and put them into respective directories and run from that location with that user
ie: blog
user: blog
homedir: /home/blog
$ > ps
... blog ...... /home/blog/bin/mebe ......
Hi and thanks for the concern. My document root is indeed not /var/www, and directory listing is not enabled. The blog could sure run with a different user, but there is nothing interesting on the server that the user could access, so I’m not too worried about it. But should leave a note to do it the next time I do something on the box.
But this is not at all related to the matter at hand.
To do this in development, you can start your application with a name (--name or --sname) and then use IEx’s --rpc-eval flag (and I think IEx also needs to be given a different name).
rpc is good; however fairly slow because it need to start up a separate erlang node just to talk to the existing running system. If you need to interact with the running system every second, you can make a simple server listening on a UNIX domain socket, that respond to a minimal text based API. This is fairly simple with gen_tcp. Another benefit (at least in my view) is you get to limit what you respond to. My client program is just a shell script that invokes socat.
defmodule Notify do
use GenServer
def start_link(args) do
GenServer.start_link(__MODULE__, args, name: __MODULE__)
end
@impl true
def init(_opts) do
BEAMNotify.start_link(
path: "/tmp/notify_socket",
dispatcher: &send(__MODULE__, {:notify, &1, &2})
)
end
@impl true
def handle_info({:notify, msg, _}, state) do
IO.inspect(msg)
{:noreply, state}
end
end