Wishful Coding

Didn't you ever wish your
computer understood you?

TRC Open-sourced

pepijndevos/irc-deploy

I finally took some time to cut out the private bits from my deploy script and open source it to the world.

This script allows you to deploy an IRC server, bouncer, web interface, bot and some custom modules to anything you can think of: VirtualBox, VPS, EC2, OpenStack, Docker…

The only things that are missing are the SSL certificates and services.

You can add your own certificates, generate self-signed ones, or disable SSL altogether:

znc --makepem
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj \"/C=NL/ST=Gelderland/L=Loenen/O=Wishful Coding/CN=*.teamrelaychat.nl\" -keyout node.key  -out node.cert

Your services are entirely up to you, but I personally use a vbox service for testing:

{:vbox {:provider "vmfest"}}

Now you should be able to just run

lein pallet up --service vbox --roles dev

Of course you can also just let me deploy it for you or hire me to deploy other things.

Dining Philosophers in core.async

For the July Amsterdam Clojure meetup, a lot of people where curious what core.async is all about, so I proposed tackling the dining philosophers problem with core.async.

The problem is explained and a solution proposed in the CSP book section 2.5, but using events rather than channels.

We worked on the problem dojo style, switching the driver seat every few minutes. But with no one really knowing the library very well, progress was slow, and by the end of the meetup we could make one philosopher eat.

One problem we ran into was that go blocks are lexical, so you can’t easily write helper functions that use <!

(defn putdown [ch] (>! ch :fork))
(go (putdown (chan)))
Exception in thread "async-dispatch-1" java.lang.AssertionError: Assert failed: >! used not in (go ...) block

So this morning I sat down to make this thing work.

During the meetup we had a function that would do something silly to setup a vector with 5 forks represented by channels, which I replaced by some equally silly, until I just came up with this.

I use channels with a buffer of one and put a fork in that buffer. This makes sure a fork can but picked up and put down without blocking, but only once.

(defn set-table []
  (let [table [(chan 1) (chan 1) (chan 1) (chan 1) (chan 1)]]
    (doseq [ch table]
      (>!! ch :fork))
    table))

The butler making sure only 4 philosophers are seated is simply represented as

(chan 4)

This leads to the definition of the basic actions

(def pickup <!!)
(def putdown #(>!! % :fork))

(def sit-down #(>!! % :sit))
(def get-up <!!)

The simplified behaviour of a philosopher then becomes

(sit-down butler)
(alts!! my-forks)
(alts!! my-forks)
(println "eating")
(map putdown my-forks)
(get-up butler)
(println "thinking")
(recur)

And finally we can run 5 philos threads.

(doseq [p philosophers]
  (thread (philosopher table butler p)))

Be sure to check out the code and output and join the next meetup if you’re in the Netherlands.

Final Excavator

I found a nice place to put the RCX and NXT and got together some remotes to play with it.

</param> </param> </param></embed>

The video and slideshow might not work on the RSS feed or mailing list. Check the website.

Published on