<commit_before>Daytona is an experimental Actor Model Framework written in C# and using ZeroMQ as the messaging library to support messaging between Actors. It is capable of the following requirements in support of the actor model 1. Single threaded within the actor. 2. Only communicates with other actors via messaging 3. Actors can create other actors

This is version 2 of this framework. It is built on version 1 but this version has been a little more influenced by Orleans than the first version was. In this version you can create a silo (name also borrowed from Orleans), register some entities in the silo, then use the Silo.ActorFactory to create your entity. Instead of creating an entity it uses NProxy to generate a dynamic proxy. This proxy intercepts the call to a method and instead sends a message to the object. The silo has been configured with a listener that will instantiate an actor of the type of your entity and start it with the data from the message. All subsequent calls to that address will go to this object.
Another major change is the update to the NetMq library, this had not started when this project was started but it appears to be the only way forward for a .Net Implmentation.

Under the hood the framework is still substantially the same. The Actor is the central object in the framework, and works in a recursive manor. You create an Actor then register additional actors which are started and will run on their own thread. As the Actors are created they set themselves up to listen for messages on a common ZeroMQ socket. They respond only to messages on that socket that are addressed to them. When sending messages to another actor they send on a separate ZeroMQ socket which is forwarded to the Receive socket by the Exchange Object. This is a simple class that implements message forwarding from the send to the receive socket.

**Usage**

You host this in a Windows application, Console, forms or Windows service.

1. First thing you need to do is create a ZeroMQ Context object their should be only one in your application and  you pass it in to all of the actors that you create. It is used to set up the send and receive sockets, and is thread safe to pass around. its normal to us the "using" pattern.
using (var context = NetMQContext.Create())
{}
2. Next set up the Exchange, and start it, again ZeroMQ handles the threading for you. The exchange forwards messages from the creation socket to the listening sockets. I will probably move the exchange into the Silo now that I am confidant that it is working as expected.

    var exchange = new Exchange(context);
    exchange.Start()

3. Then you can create and use your silo

##  
    using (var silo = new Silo(context, new BinarySerializer()))
    {
        silo.RegisterEntity(typeof(ConsoleReaderActor));
        silo.RegisterEntity(typeof(ConsoleWriterActor));
        silo.Start();
        var reader =    silo.ActorFactory.CreateInstance<IConsoleReaderActor>(typeof(ConsoleReaderActor));
        reader.Read();
        do
        {
            Thread.Sleep(1000);
        }
        while (DontBreak);
        silo.Stop();
    }

    exchange.Stop(true);

In the above sample you can see a consoleReaderActor and a ConsoleWriterActor being registered. Then you see the silo being started, which must occur in this order. Next you can see the reader object being created by the Actorfactory, this is a proxy object and will take what ever parameters you have passed the method and the method name and sen them to the actual object. The reader.Read call sends a message to the address inproc://<fullobjectname>/objectId the silo has an actor set up to monitor all addresses. If it can not find a working version it will create a new one. If one already exists then it will also read the message and respond to it.
The last few lines of code are just there to ensure that the thread does not exit before it is supposed to. The last lines silo.Stop, the close of the using statement and the exchange.stop are all part of the gracefull shut down of the app.
Not shown here is the reader and writer objects. On seperate threads one reads the console, then passes the information to the writer that writes out to the console, after writing out to the console but prior to waiting on the next message it tells the reader to read another line.<commit_msg>more updates<commit_after>Daytona is an experimental Actor Model Framework written in C# and using ZeroMQ as the messaging library to support messaging between Actors. It is capable of the following requirements in support of the actor model 1. Single threaded within the actor. 2. Only communicates with other actors via messaging 3. Actors can create other actors

This is version 2 of this framework. It is built on version 1 but this version has been a little more influenced by Orleans than the first version was. In this version you can create a silo (name also borrowed from Orleans), register some entities in the silo, then use the Silo.ActorFactory to create your entity. Instead of creating an entity it uses NProxy to generate a dynamic proxy. This proxy intercepts the call to a method and instead sends a message to the object. The silo has been configured with a listener that will instantiate an actor of the type of your entity and start it with the data from the message. All subsequent calls to that address will go to this object.
Another major change is the update to the NetMq library, this had not started when this project was started but it appears to be the only way forward for a .Net Implmentation.

Under the hood the framework is still substantially the same. The Actor is the central object in the framework, and works in a recursive manor. You create an Actor then register additional actors which are started and will run on their own thread. As the Actors are created they set themselves up to listen for messages on a common ZeroMQ socket. They respond only to messages on that socket that are addressed to them. When sending messages to another actor they send on a separate ZeroMQ socket which is forwarded to the Receive socket by the Exchange Object. This is a simple class that implements message forwarding from the send to the receive socket.

**Usage**

You host this in a Windows application, Console, forms or Windows service.

1. First thing you need to do is create a ZeroMQ Context object their should be only one in your application and  you pass it in to all of the actors that you create. It is used to set up the send and receive sockets, and is thread safe to pass around. its normal to us the "using" pattern.


    using (var context = NetMQContext.Create())
    {}

2. Next set up the Exchange, and start it, again ZeroMQ handles the threading for you. The exchange forwards messages from the creation socket to the listening sockets. I will probably move the exchange into the Silo now that I am confidant that it is working as expected.


    var exchange = new Exchange(context);
    exchange.Start()

3. Then you can create and use your silo


    using (var silo = new Silo(context, new BinarySerializer()))
    {
        silo.RegisterEntity(typeof(ConsoleReaderActor));
        silo.RegisterEntity(typeof(ConsoleWriterActor));
        silo.Start();
        var reader =    silo.ActorFactory.CreateInstance<IConsoleReaderActor>(typeof(ConsoleReaderActor));
        reader.Read();
        do
        {
            Thread.Sleep(1000);
        }
        while (DontBreak);
        silo.Stop();
    }

    exchange.Stop(true);

In the above sample you can see a consoleReaderActor and a ConsoleWriterActor being registered. Then you see the silo being started, which must occur in this order. Next you can see the reader object being created by the Actorfactory, this is a proxy object and will take what ever parameters you have passed the method and the method name and sen them to the actual object. The reader.Read call sends a message to the address inproc://<fullobjectname>/objectId the silo has an actor set up to monitor all addresses. If it can not find a working version it will create a new one. If one already exists then it will also read the message and respond to it.
The last few lines of code are just there to ensure that the thread does not exit before it is supposed to. The last lines silo.Stop, the close of the using statement and the exchange.stop are all part of the gracefull shut down of the app.
Not shown here is the reader and writer objects. On seperate threads one reads the console, then passes the information to the writer that writes out to the console, after writing out to the console but prior to waiting on the next message it tells the reader to read another line.

**Running Stuff**
this project is still in discovery phase so please excuse the mess. If you want to run anything yohu need to build and run the Monitor program first. The actors are sending messages to it to display in the console, I am using a request response pattern to guarantee the messages. At some point I will pull this out but for now its a (mostly) well behaved way to get messages.

The easiest place to start is with the ConsoleReaderWriter project. it should fire up and run quite nicely, I borrowed the example from the training offered by AKKA.Net, so shout out to them for the idea.
{'fraction_non_alphanumeric': 0.03390557939914163, 'fraction_numerical': 0.002575107296137339, 'mean_word_length': 3.8496357960457854, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '586624', 'n_tokens_mistral': 2178, 'n_tokens_neox': 2088, 'n_words': 1501}