(archive 'newLISPer)

October 4, 2006

Agents and daemons

Filed under: newLISP — newlisper @ 08:58
Tags:

As I wrote that title, I thought for one moment that I was going to start another parody of Dan Brown (his “Angels and Demons” thriller hasn’t yet been turned into a blockbuster movie, but I think it’s in the pipeline). But no, I stopped myself just in time. In fact I’ve been trying to develop a small utility for my own purposes, and I ended up reading a technical note from Apple about agents and daemons, which had a section wonderfully entitled Daemonomicon.

Apple’s note explains the difference between agents (background applications that work on behalf of a specific user) and daemons (programs that operate system-wide, not directly for the benefit of a user). So I ended up writing an agent rather than a daemon. A pity really, because I like the idea of conjuring up Unix daemons.

I think (but I’m not much of an expert) that newLISP is a good language for writing these agents. As a language it’s small, fast, and light on its feet, yet has many useful features.

One of the jobs I wanted to do was to keep a record of all the music being played in iTunes. With a bit of AppleScript and a bit of newLISP I rustled up this little script:

#!/usr/bin/newlisp

(set 'previous-music "")

(while true
   (and
      (exec {ps x | grep [/]Applications/iTunes.app/Contents/MacOS/iTunes}) ; iTunes running?
      (set 'current-music
       (exec [text]osascript -e 'tell application "iTunes" to if
         player state is playing then get (player state & "~~~" &
         name of current track & "~~~" & artist of current track &
         "~~~" & current stream title) as Unicode text'[/text]))
      (set 'current-music
       (parse (first current-music) "~~~"))
      (= (current-music 0) "playing")        ; and playing?
      (!= previous-music current-music)      ; different track?
      (set 'the-date (date (date-value) 0 "%Y-%m-%d %H:%M:%S "))
      (if (find "SomaFM" (current-music 1))
         ; streaming
         (set 'display-string
           (string the-date
           "[SomaFM] "
           (0 12 (current-music 1))
           "... : "
           (current-music 3) "\n"))
         ; not streaming
         (set 'display-string
          (string the-date
            "[Library] "
            (current-music 1)
            ": "
            (current-music 2) "\n")))

      (append-file "/Users/me/Music/itunes-playlist" display-string)
      (set 'previous-music current-music)) ; remember this one

   ; in any case, sleep for 20 seconds before trying again
   (sleep 20000))

Notice that I’ve been listening to SomaFM internet radio recently, so I’m asking iTunes for the current stream title as well as the current track’s name and artist. If you listen to – or record :-) – streaming radio, you can get the latest song details as the songs change, even though iTunes thinks it’s just playing the same track.

I’ve used a separator of “~~~” which makes parsing the string returned from iTunes easy. And I’ve found myself using that and construct again, which pleases me strangely.

This all seems to work fine, so the one remaining question is: how do I make it launch as a background ‘agent’ whenever I log in, without a visit to the terminal? Apple have done something a bit different, here. They’ve developed a new Unix architecture for launching processes, which uses the command ‘launchd’. This is gradually replacing the old Unix standards such as rc (whatever that is), and which is also going to supersede things like cron, eventually. (In fact, if you look at the /etc/crontab file, it says that “the periodic and atrun jobs have moved to launchd jobs”. So the supersession is already under way.)

Since this is a Mac, though, you can usually avoid learning all those command-line mystic runes by using a nice friendly GUI application. For controlling your daemons and agents, all you need is Lingon, a lovely bit of programming by Peter Borg that makes all the launchd and launchctl stuff easy to use: “Launch your dreams right here” is his slogan, and all you do is show it your script and a new agent will be sent on its mission.

In use, this secret agent doesn’t look like it’s using much memory, compared with cron, for example:


               %cpu  VMem      Real mem  User  PID   CPU  #   Private    Shared   Messages
   cron        0.00  26.88 MB  504.00 KB root   76  00.01 1  136.00 KB   352.00 KB   56
   newlisp     0.00  26.93 MB  512.00 KB me   5062  00.00 1  176.00 KB   532.00 KB   62

What’s cron like for programming in?

Advertisements

3 Comments »

  1. >Nice. I wish I had a mac book. All of these applescript things look cool. I like string based languages like that and tc. String-based langauges it easy to work with them from newLISP.

    Comment by Bob — October 5, 2006 @ 06:24 | Reply

  2. >You’d like AppleScript, Bob – an attempt by Apple to make an English-like scripting language suitable for non-programmers, while under the influence of stuff like Lisp and Hypercard. It’s loved and despised in equal measure by Mac users.For more, look here.

    Comment by newlisper — October 5, 2006 @ 07:38 | Reply

  3. >I think applescript looks nifty, as you say like proper English.By the way Angels and Demons — I tried reading it at the library the other day. Nice pictures! But pretty unreadable and pedestrian. I can’t believe how many copies of books the Mr. Brown sells, given the kind of writing he churns out.

    Comment by bob bae — October 6, 2006 @ 00:05 | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: