Fork me on GitHub

Tuesday, February 23, 2010

Simple Reactive Programming in Ruby

Reactive Programming is an interesting programming paradigm based on propogation of changes, data flows. A programming model based on side effects, I think this is especially useful when we need to control the state of one entity based on what goes on in outside itself. For example take the equation


x = 1; y = 3
z = x + y
puts z #<= z = 4


Since z depends on x and y, what will happen when we update value of x or y. z remains same as 4 because z is already computed and stored using the values of x and y. Now if the values of x and y changes z will still remain the same.

But what if you want z to get adjusted depending upon x and y. This is more common problem in everyday programming than we think. Imagine you have to update the GUI based on what is changing in underlying model (MVC?) or take an example of spreadsheet where changing a value in a cell recalculates some other cell based on a formula.

Here is a very simple example of Reactive Programming in Ruby using EventTarget.
Here in this example value of z is x + 2. We evaluate z by setting an initial value for x and then later we change value of x and observe the value of z changed as well.


require 'EventTarget'

module Rx
class Change
attr_accessor :old, :new
end
class ObservableValue
include EventTarget
def initialize(value, on_change)
add_event_listener(:change, &on_change)
self.value = value
end
def value=( v )
change = Change.new
change.old = @value
change.new = v
@value = v
evt = Event.new( :change, change )
dispatch_event( evt )
end
end
end

if $0 == __FILE__
z = 0
on_change = Proc.new {|e| z = e.change.new + 2}
x = Rx::ObservableValue.new(3, on_change)
puts "Initial value of z is #{z}" #<= z=5
x.value = 5
puts "Current value of z is #{z}" # <= z=7
end


This is a very simple and contrived example of Reactive programming but I hope this illustrates the point. The concept is way more powerful and is (Functional Reactive Programming) available in a lot of functional languages like Haskell. Take a look at Reactive Framework in .Net and Javascript, Traits, Trellis in Python or Cells in Common Lisp for more understanding of how Reactive Programming works.

Let me know your thoughts and happy hacking :)

Friday, February 19, 2010

Software Transactional Memory in JRuby - Redux with Cloby

After I wrote about using Clojure's Software Transactional Memory infrastructure in JRuby in my previous post. @headius has written an awesome wrapper Cloby in Java to use Clojure STM in JRuby and writing Ruby objects which can be used as Clojure Refs.

Here is an example code of using a Ruby object in STM.


require 'clojure'

class MyClojureObj < Clojure::Object
def initialize
dosync { @foo = 'foo' }
end

attr_accessor :foo
end

obj = MyClojureObj.new
puts "obj.foo = " + obj.foo

begin
puts "Setting obj.foo to 'bar'"
obj.foo = 'bar'
rescue ConcurrencyError
puts "Oops, need a transaction"
end

puts "Trying again with a transaction"
dosync { obj.foo = 'bar' }
puts "Success"

puts "obj.foo = " + obj.foo


Some pretty good abstractions of using dosync and Refs in STM. So how do we use it?
Clone the code from http://github.com/headius/cloby/blob/. Build ClojureLibrary.jar with clojure and jruby.jar. Keep ClojureLibrary.jar and clojure.jar in classpath.
And here is the bridge I wrote between your awesome code using STM and ClojureLibrary.jar


#!/usr/bin/env jruby

require "java"
require "ClojureLibrary.jar"
require "clojure-1.0.0.jar"
include_class "org.jruby.clojure.ClojureLibrary"

clj_lib = ClojureLibrary.new
clj_lib.load(JRuby.runtime, true)


Now its pretty easy to use Clojure's STM. No raw usage of LockingTransactions or Refs. Enjoy Cloby... :)

Thursday, February 18, 2010

#Concurrency - Software Transactional Memory in JRuby with Clojure

Still playing with JRuby and concurrency... For me JRuby is one of the best implementations of Ruby VM. It has this amazing property of taking the most boring Java projects and turning them into something exciting. Not that clojure is boring but on the other hand it is one of the most wonderful languages I have worked with. Being a big fan of Lisp Clojure is a dream come true.

This post is about my exploration with JRuby and Clojure more in terms of how to use the Clojure's STM infrastructure. Whenever I find an interesting Java library the first thing I do is to import it into JRuby and play with it for sometime. After working with Clojure I wanted to use its STM in Ruby and finally found time to do it. The code is really crude as it explores very basic functionality of STM. May be as I keep working I will try to build something around this and who knows it can end up as a library for JRuby :)...

Instead of defining STMs myself - Here it is from Wikipedia..
"In computer science, software transactional memory (STM) is a concurrency control mechanism analogous to database transactions for controlling access to shared memory in concurrent computing. It functions as an alternative to lock-based synchronization. A transaction in this context is a piece of code that executes a series of reads and writes to shared memory. These reads and writes logically occur at a single instant in time; intermediate states are not visible to other (successful) transactions."

As most of you know the problem is with sharing the state.. In this example my_account balance. Imagine when two different threads of execution trying to update the value at the same time. Disastrous results may ensue. So the typical approach is locking of the shared resource. Problem with locking is it effectively limits concurrency as well is too hard to get it right. So we have started looking for other models of concurrency. Actors, Dataflow and STMs are some of the popular form. As you see in the example let's say there is a shared resource. If we need to update it we can't update it in a separate context. We need to run this as a part of transaction and as database transactions it is all or nothing.

In Clojure's term a ref can be updated only inside the context of a transaction. Else it will throw IllegalStateException. As well the ref getting updated will not be visible to outside work till the end of the transaction. The transactions are composable which is difficult in cases of threads and locks. Also as the example shows STM is a form of optimistic concurrency. Everyone can update the shared resource but whoever finishes first and commits wins. Others fail because the state now is different from what they started with and they can try.





The code is almost self explanatory and simple. Using clojure STM is pretty simple and straightforward. And this will help us to effectively manage concurrent access of shared resource by multiple threads.

Let me know your thoughts...

Tuesday, February 16, 2010

JRuby + Jetlang => Awesome Message Passing Concurrency

It has been quiet sometime since I played around with JRuby.. The last I seriously worked on JRuby was during schnell-jruby age :). And now that celerity has taken the main stage I was back in MRI land for a long time. I recently got a chance to return to JRuby land and play with it for sometime.

Interested in concurrency I tried to work on Software Transactional Memory in JRuby with Akka... But as things didn't go great I was searching for something else interesting to work on and I found Jetlang. Jetlang has been in my interest list of sometime but I never got a chance to work with Java.

Jetlang is based on message passing concurrency. It has the concept of fibers which are independent threads of execution and channels which are conduits attached to fibers. We can pass messages to a fiber through channels and when a message is passed into a channel to a fiber the on receive callback is called with the corresponding parameters..

Following are two examples illustrating the use of fibers and channels for message passing concurrency. The last one is the popular ping pong example used for illustrating message passing across fibers :).








Writing code in Erlang and using Jetlang based message passing concurrency has made me think that... Can Actors (and Message passing fibers) be considered as ideal representations of objects? Isn't this how we want object oriented systems to behave?
Let me know your thoughts...