intertwingly

It’s just data

IPC with Erlang


Previous status: I’ve shown Erlang code that sends a Jabber message.  I’ve shown Erlang code that parses a planet Venus generated Mememes feed.  Now, lets consider the problem of sending notifications for new items.

Typically, solutions for problems like these require some level of persistence: a database, serialized results, or the like.  But each of these options require additional maintenance commitments, and I’m looking for something with zero footprint and “just works”.

The memes feed is produced by a script invoked by a cron job.  Ideally, we would be looking for commands that could be added to that script.  In order to do so, we would need a command that is inserted near the beginning of the bash script, and a second command inserted near the end, and a way for these processes to communicate.  And, as it turns out, this is something that Erlang excels at.

In Erlang you can name the server, the process, and the thread, you can send a message to it.  A rough design for the server would be to register the thread under a given name, scan the atom feed retaining the Titles and Links found, and wait up to ten minutes for a message that simply says resume.  Once that message is received, perform a second scan, this time issuing alerts on all new entries.  The Erlang code for this is as follows:

start() ->
  register(meme_thread, self()),

  scan(mark),

  receive
    resume -> scan(alert)
  after 10 * 60 * 1000 ->
    xmppclient:send("meme", ["Timed out."])
  end,

  init:stop().

This code is invoked thus:

erl -noshell -sname meme_server -s newmemes start &

The code for the client is even simpler.  It simply needs to send a resume message to the named thread on a given Node, and exit.  The code for this is as follows:

resume([Node]) -> 
  {meme_thread, Node} ! resume,
  init:stop().

This code is invoked thus:

erl -noshell -sname meme_client -s newmemes resume meme_server@localhost

Everything else is straightforward.  scan now accepts a Mode parameter, and passes it to format_entries, which uses it in a case statement, thus:

case Mode of
  mark -> put(Link, Title);
  alert ->
     case get(Link) of
       Title -> nop;
       _Else -> xmppclient:send("meme", [{a,[{href,Link}],[Title]}])
     end
end,

Additionally xmppclient accepts the Resource and Message as parameters.  Given that the machine running this code has the feed on disk, I’ve also updated the code to parse the file directly, eliminating an http request.

The completed code: newmemes.erl, xmppclient.erl.

Notes: