Massive improvements to Pigeon – Akka Actors for .NET


The last few weeks have been busy busy.
Me and Aaron have been making some massive improvements to Pigeon.
Most of the Akka features are now completed, remoting still needs some love and after that we will start porting Akka clustering.

One of the latest features we have added is logging.
We support the same features as real Akka, so logging can be done using the ActorSystem.EventStream, and there is also a BusLogging LoggingAdapter.

We are also leveraging the real Akka config, so we can enable logging based on the same configuration options that Akka has.
Here is a snapshot of the output from the StandardOutLogger when booting the ChatServer example:

2014-02-21 22:40:44 DebugLevel EventStream - subscribing [akka://all-systems/StandardOutLogger] to channel Pigeon.Event.Info [Thread 9]
2014-02-21 22:40:44 DebugLevel EventStream - subscribing [akka://all-systems/StandardOutLogger] to channel Pigeon.Event.Warning [Thread 9]
2014-02-21 22:40:44 DebugLevel EventStream - subscribing [akka://all-systems/StandardOutLogger] to channel Pigeon.Event.Error [Thread 9]
2014-02-21 22:40:44 DebugLevel EventStream - StandardOutLogger started [Thread 9]
2014-02-21 22:40:44 DebugLevel akka.tcp://MyServer@localhost:8081 - now supervising akka.tcp://MyServer@localhost:8081/user [Thread 10]
2014-02-21 22:40:44 DebugLevel akka.tcp://MyServer@localhost:8081 - now supervising akka.tcp://MyServer@localhost:8081/system [Thread 10]
2014-02-21 22:40:44 DebugLevel akka.tcp://MyServer@localhost:8081/system - now supervising akka.tcp://MyServer@localhost:8081/system/deadLetterListener [Thread 11]
2014-02-21 22:40:44 DebugLevel EventStream - subscribing [akka.tcp://MyServer@localhost:8081/system/deadLetterListener] to channel Pigeon.Event.DeadLetter [Thread 9]
2014-02-21 22:40:44 DebugLevel akka.tcp://MyServer@localhost:8081/system - now supervising akka.tcp://MyServer@localhost:8081/system/logMyServer-DefaultLogger [Thread 10]
2014-02-21 22:40:44 DebugLevel EventStream(MyServer) - Default Loggers started [Thread 11]
2014-02-21 22:40:44 DebugLevel EventStream - subscribing [akka.tcp://MyServer@localhost:8081/system/logMyServer-DefaultLogger] to channel Pigeon.Event.Error [Thread 11]
2014-02-21 22:40:44 DebugLevel EventStream - unsubscribing [akka.tcp://MyServer@localhost:8081/system/logMyServer-DefaultLogger] from channel Pigeon.Event.Debug [Thread 11]
2014-02-21 22:40:44 DebugLevel EventStream - unsubscribing [akka.tcp://MyServer@localhost:8081/system/logMyServer-DefaultLogger] from channel Pigeon.Event.Info [Thread 11]
2014-02-21 22:40:44 DebugLevel EventStream - unsubscribing [akka.tcp://MyServer@localhost:8081/system/logMyServer-DefaultLogger] from channel Pigeon.Event.Warning [Thread 11]
2014-02-21 22:40:44 WarningLevel ActorSystem(MyServer) - {
  akka : {
    log-config-on-start : on
    stdout-loglevel : DEBUG
    loglevel : ERROR
    actor : {
      provider : "Pigeon.Remote.RemoteActorRefProvider, Pigeon.Remote"
      debug : {
        receive : on
        autoreceive : on
        lifecycle : on
        event-stream : on
        unhandled : on
      }
    }
    remote : {
      server : {
        host : localhost
        port : 8081
      }
    }
  }
} [Thread 9]
2014-02-21 22:40:44 DebugLevel akka.tcp://MyServer@localhost:8081/user - now supervising akka.tcp://MyServer@localhost:8081/user/ChatServer [Thread 10]
2014-02-21 22:40:45 DebugLevel akka.tcp://MyServer@localhost:8081/user/ChatServer - received handled message ChatMessages.ConnectRequest [Thread 11]

Alot of the existing features have also been refined to conform even more to real Akka, e.g. ActorSelection have been rewritten to behave exactly like in Akka.
ActorRefs are now also serializable in messages, so you can send messages containing actorrefs across the wire and use them on remote systems.
The Akka RemoteDaemon is also coming along nicely, so we can create actors on remote nodes this way, the underlying deployment features are however not completed yet.

The Props class have also gotten new features, we can now configure dispatchers and mailboxes via the config and there is also a new dispatcher that lets you run actors in the main thread, to allow GUI updates in WPF/WinForms.

Well, there are alot of new features and bugfixes, so if you are interested in Actor Model Programming in .NET be sure to check out the Pigeon repository at https://github.com/rogeralsing/Pigeon

//Roger

 

AlbinoHorse – Class Designer


I have published my class designer component at CodePlex.

You can find binaries and sourcecode here:
http://www.codeplex.com/AlbinoHorse

AlbinoHorse is a Windows Forms control for UML Class diagrams that I’m currently developing.
The idea is to use it in our next version of ObjectMapper. (Mapper tool for ORM entities)

albinohorse.png

DSLisp


MyLisp is now named DSLisp – Domain Specific (Language) Lisp.

I have published it as a project on CodePlex:
http://www.codeplex.com/DSLisp

The new name imples the purpose of the project.
To act as a host for DSL’s.

The idea is to compile your DSL into the DSLisp AST.
And then run your DSL inside the DSLisp engine.
By doing this you can very easily add single step debugging and breakpoint support to your DSL. 

See the codeplex site for more info.

Adding Linq support to NPersist


I’m currently adding some real Linq support to NPersist.
I did start on it when the first public previews of Linq was released, but then I was kind of stuck in World of Warcraft for a while (OK, slightly more than a while).
But I’ve finally broken out of the world of Azeroth and I’m back in the real world again.

So, here is a few sneak peeks of what will be possible:

 var res = from cust in ctx.Repository<Customer>() 
          where (from order in cust.Orders 
                 where order.OrderDate == 
                 new DateTime(2008,01,01) && order.Total == 3.1 
                 select order).Count > 0 
          select cust;

 The Linq query will be turned into our own DSL NPath :

select * 
from Customer 
where ((( 
	select count(*) 
	from Orders 
         where ((OrderDate = #2008-01-01#) and (Total = 3.1)) 
        ) > 0))

The NPath query will then be transformed into SQL once the user tries to access the result.
Sure, it is some slight overhead to transform a 2nd query language, but the NPath parser is extremely fast, and NPersist use NPath internally so we just wanted to avoid making two SQL generators.

The SQL generation is by far the biggest beast inside NPersist, it’s big, furry and very angry, so we just want to stay away from it if we can. ;-)

We have also managed to solve the problem with Linq and Load spans that have haunted us since we first saw Linq.
“How the heck do we add load spans to the select when we cannot change the syntax of the select part?”
The solution is quite simple: “You don’t”
Instead, we pass the loadspan to the query source, like this:

var res = from cust in ctx.Repository(new LoadSpan<Customer> 
("Name","Email","Address.StreetName"))    

          select cust; 

This way we do not need to invent weird hacks that don’t really fit into the Linq syntax.
The solution might have been obvious for others, but we were really stuck on it, pretty much because we have always specified load spans in the select clause of NPath.

Lisp Debugger


I’m still working on my Lisp language clone.
Today I started to add debugging support to it.
I made the AST aware of the original source code, so each node can reference back to the place it was parsed from, and I also added a bit of call stack features.

I’m pretty satisfied with it so far, it almost feels like a real language now ;-)

Anyway, here is a screenshot of the not so well designed GUI.

 Debugger
Click for full size.

Downloads are available at: 

Source: http://www.puzzleframework.com/roger/mylisp.zip
Binaries: http://www.puzzleframework.com/roger/mylispbin.zip

(The code is written in C#3, VS.NET 2008 solution)

Lisp weekend


I’ve been reading up a bit on functional programming the last few week, the reason is just to comprehend the new features and possibilities in .NET 3.5 as much as possible.

Anyway, I got a bit carried away and started to read about Lisp, and decided to learn what it’s all about.
So what better way to learn a language than to make your own parser for it is there? ;-)

I started to hammer away on a simple parser, and once the parser was done, I couldn’t stop, so I began writing an engine too.
So after a few hours of Aha moments, I finally got my very own Lisp(ish) code executor and a bit more understanding for the language. ;-)

Well, enough blabbering, here are a few samples of whats currently possible in my still un-named language.

Hello world:

(print 'Hello world!')

Simple function and call:

(defun Mul (x y) 
 (* x y))       

(print (Mul 2 3))

Variables:

(let my-var 'hello lisp') 
(let my-int 123) 
(let my-double 123.456) 
(let half-pi (/ pi 2)) 
(let my-arr (arr 1 2 3 4 5 6 7))

Loops:

(foreach item my-arr 
 (print item))      

(for i 1 20 
 (print i))      

(let i 0) 
(while (< i 20) 
 ((print i) (++ i)))

Lambdas:

(let my-lambda (lambda (x y) (* x y))) 
(my-lambda 2 3)

Delegates:

(let my-delegate Mul) // delegate to Mul 
(let print other-print-func) //redirect the print function to "other-print-func"

Objects:

(let form (new Form)) 
(set form Text 'hello windows forms') 
(let button (new Button)) 
(set button Text 'my button') 
(set-event button Click MyButtonClick) 
(list-add (get form Controls) button) 
(call form Show)

List comprehensions:

(foreach item (select (lambda (concat 'transformed: ' item '!')) 
              (where (lambda (> (get item Length) 3)) 
              (list 'foo' 'bar' 'roger' '.net' 'lisp')))       

      (print item))

The next step will be to make it possible to define your own classes.
Im thinking of emitting true .NET classes and let the methods redirect the calls to the engine.
Thus making it possible to redefine the behaviour of a method in runtime.

That, and find some reason to use it :-P