My Writings. My Thoughts.

gen_server With Rotating List

// December 15th, 2009 // 3 Comments » // Uncategorized

For those of you who didn’t go to SF Erlounge, it was a blast.  In addition to getting to hear Tom Preston-Werner’s exciting presentation on BERT, BERT-RPC, and the new GitHub architecture, I also got to meet quite a few people who are interested in Erlang, but don’t have a lot of experience.

The great thing about these people is that they are great at bringing simple (for me) problems.  One of these problems was so simple that it occurred to me to write it and post the source.

This particular problem is dead simple.  He wanted to be able to have (possibly many) workers retrieve values from a list, rotating the list on each step.  Using gen_server to serialize the requests was obvious, but I also think that this is a great example that illustrates how gen_server can be used to wrap useful, functional (i.e. tail-recursive) code.

Have a look at the source.

It’s a simple gen_server that maintains two lists as its only state.  The first list is a list of "fresh" entries, and the second is a list of "stale" entries.  All it does is retrieve entries from the fresh list, one at a time; returns them to the user; and then accumulates them in another list of used entries.

When the fresh list would become empty, it returns the value to the caller, then automatically reverses the stale list (with the last value).  This is a minor optimization so that clients don’t have to wait on lists:reverse/1 unless absolutely necessary.

The demos each contain a start function, and the data they use is just the module list as managed by the code server.

To compile this, just use erlc on each file, or run erl -make with them in a directory.  To run them, try something like "erl -s demo_slow start".  You’ll need to kill the VM to stop it (use ctrl+c to break out and q to quit).


Using Ports to Communicate With External Programs

// December 10th, 2009 // Comments Off // Uncategorized

A rather nice fellow on the Erlang Questions list has been having some trouble with communicating with an external Java program.  Now, I’m not sure what he’s trying to do, exactly, but I thought that a good example is in order.

I wrote two programs to help with this.  One of them is an Erlang program (and escript, actually) that runs the second program.  The second program is supposed to, in his case, be the Java code he wants to chat with.  In my case, it’s a shell script that reads two lines, then prints out various things (including the data it was given, a random number, and the command line).  For added measure, it exits with an exit status of 42.

Thus, this example shows how to do the following core activities:

  • open an external program with port_open/2
  • write to an external program with port_control/2
  • read from that external program by receiving messages
  • use line-mode framing to receive whole lines of data

In addition, I’ve spiced it up a bit with some other useful tidbits:

  • collect a return status from the process
  • searching the path for your program
  • using spawn_executable to have strong control over your arguments
  • specifying an arg0 for those commands that need it (busybox, I’m looking at you)

Hopefully this is a help to all of the people who have been struggling with it.  Here’s a link to the code.

There are two final things that you should know.  First, if you need to move lots of data, using {packet,N} and binary are probably the way to go.  Second, if the program you’re running wants STDIN to close, there doesn’t seem to be any way to do this using a port.

Hello World!

// December 9th, 2009 // 1 Comment » // Uncategorized

Well, I founded a marginally successful Ruby startup, and I have no hardcore tech blog.  WTF?  How did that happen?

Let’s rectify that immediately.  Attention world!  I’m a hotshot Rubyist.  Read my words and fear me!

This is an opinionated community, filled with big ideas, big egos, and edgy san-serif fonts.

Look forward to various things Ruby, Erlang, Linux, etc.  Oh, and the forecast is cloudy, so make sure to put on your galoshes.