AwBus Update: Containers, Pubsub and Admin Service

September 28, 2009

When I last left the container service, all nodes were loading the same containers. That’s no longer the case; they each get exactly what they’re supposed to.

Currently, the admin utility gets all its information at startup, and that’s about it. I can easily add a refresh function to get the latest info, but to get it to keep up with all the on-goings, I need the pubsub.

Also, when a packages starts up, it loads components. We need to be able to see those components. Currently, they’re not exposed. Once again, the best solution for this will be the pubsub. In this case, it will just be a local admin topic.

I’ve started work on the pubsub; designing the objects, etc. The initial implementation will be very simple just to get the design right. Later, I’ll do a more robust multi-threaded implementation. One thing at a time.

Creating an Wcf Service on top of the bus service

Each node hosts one or more services. Those services run locally to the bus; they are not automatically exposed via Wcf.

To expose it via Wcf, you write a service contract and implementation, then associate it to the bus service.

I’ll use pubsub as an example since that’s what I just did. The pubsub service runs in the node. Everything in the node can use it directly. But, for outside publishers and subscribers, we need to expose the functionality externally.

Here’s how you do the association.

 [RemoteAdminService(typeof(IPubsub), typeof(Pubsub))] public class PubsubService : BusServiceBase { ...} 

The names are overlapping. I keep having that problem. Anyway: PubsubService is the service that runs in the node. The RemoteAdminService attribute is used to associate it to one or more Wcf services. IPubsub is the service contract. Pubsub is the service implementation. That’s all you need… The Wcf service fires up immediately.

I need to change the attribute name. Until I created the pubsub, this was only used for admin purposes. Since that’s no longer the case, the word ADMIN in the attribute name is no longer appropriate.

image

Advertisements

AwBus Update

September 20, 2009

I didn’t have a lot of time to work on it this week. But, I made some good progress tonight.

The broker service is the middle-man between the nodes. Nodes are stand alone and don’t need a broker, but if you want them to play together, that’s where the broker comes in.

When I last worked on this, the nodes register with the broker on startup. But, the gui only showed Node1. Now, it works properly. The broker window calls the broker service. The broker service responds with the list of registered nodes and their endpoint information. When you double-click a node, it opens the node admin for that particular node (rather than the previously hard coded node 1.)

The broker will also server as a common entry point for all nodes. So, you will be able to adminster any node without that node exposing any public endpoints. That’ll allow you to reduce the number of endpoints and security setup, etc. But, that doesn’t exist yet.

The screen shot shows 4 programs:

  1. Start the broker
  2. Start node 1
  3. Start node 2
  4. Start the admin program

The admin program shows that Node 1 and Node 2 are open.

image

NEXT: Both nodes are loading the same containers by default. The container store is node specific, I’m just not using it that way yet. For my next post, they should each have their own containers.

Vs 2010 in Windows 7 VM

I had a rude awakening today. Running VS2010 Beta 1 in a WIINDOWS 7 VM on a WINDOWS 7 HOST is not good. It worked 100% fine when the host was windows xp 32 bit, but on Windows 7 64bit… its not even functional. That’s unfortunate.

My Experience with Windows Forms

I’m not good with GUIS, nor do I aspire to correct that. There are plenty of things for me to code; I can leave the presentation to someone else. They can make it pretty.

But, I need to be proficient, and I am. I can’t make it pretty, but I can make it work. When I started AwBus, I considered using WPF. But, that would’ve been a brand new thing to learn and I’d rather focus my time on the back end. The front is very important because that’s the only way to demonstrate its abilities. I can do that with plain old windows forms.

Tree View

I’m not sure how you’re supposed to keep track of things in the Tree View. For example: in the nodes window, I’m displaying the node names. But, when you double click it, you need a ton of other info. Essentially, it needs the entire registration object that came back from the service call.

So, I created an awkwardly named class called “NodeTreeNode”. The first node pertains to the AwBus. TreeNode pertains to the Tree View. The NodeTreeNode object has a property that holds onto the registration object. Then, its just

treeViewBroker.Nodes.Add(new NodeTreeNode { Blah = blah});

I used BLAH because I’m too lazy to look at the actual property name.

I was also surprised to see that nodes don’t have double-click event; you can only get it from the tree. When the even fires, I look at TreeView.SelectedNode and see what the type is. Then, it branches base don type. Currently, there’s only one custom node type in the broker admin, but you see in the Node Admin there will be a lot of them.

Form Management

I spent more time on the GUI then on the backend. I created a Form Manager to keep track of which forms are open, etc. So, if you double click NODE 1 two times, it doesn’t open it two times.

I saw something like this once before at an undisclosed location. The problem with that implementation is that it works as follows:

  1. Instantiate the form
  2. See if the form (plus key info) is already in the list of known forms
  3. If so, close the form

Instantiating the form to see if you need the form isn’t the best approach. I attempted to correct that implementation by adding a static method to the forms that constructs a key based on input criteria. It wasn’t ideal, but it was the best I could do with what I had to work with. I don’t know if those who came after me kept up that pattern.

The form manager in AWBus is cleaner. You pass it: The Form Type, the Key, and a list of any constructor parameters that you want to pass the form should it need to be instantiated.

In the case of the node admin form:

Type = typeof(NodeAdminForm)

Key = Node 1 (the name of the node; the uniqueness)

Parameters = The endpoint object stored on the tree


Cool Singleton Article

September 13, 2009

Three years ago, I wasn’t against singletons. Times change. You learn more. Once fully committed to TDD, loose coupling and reusability, there’s really no place for a singleton. In my browsing today, I saw it referred to as an anti-pattern. I don’t know if that’s a shared opinion across the masses, but I concur.

That’s not to say that sometimes your application doesn’t need a shared object. When it does, though, it should be the application that manages the shared object,  not the the object itself.

For the same reasons, except in rare known circumstances, statics are automatically red flags when used in objects. Its ok for a consumer of the object to keep a static reference if it chooses but, again, that’s the choice of the consumer not of the object. (A valid exception is private read only literals. For example:

 </p>  <p>// based on a true story.    <br />private static readonly string[] _logCategories = new string[]     <br />{ &quot;cat 1&quot;, &quot;cat 2&quot;, &quot;cat 3&quot; };    <br />

These days, I’m very passionate about my position on statics and singletons. SINGLETONS = BAD. OBJECT LEVEL STATICS = BAD. Two weeks ago it was suggested, at work, that one of our major components should be converted to a singleton. I disagreed. Everything in the object is already static anyway; instantiating it doesn’t really do anything other than give access to the static cache. Anyway, I expressed my opinion about it. We’ll see what happens, but its none of my business.

Unity and its lifetime manager eliminates the need for singletons and statics. If you’re not using unity, then maybe you need to hang on to a static reference. Even if you are using unity, maybe you have a static reference to the unity container to eliminate all other static references. (Or, maybe not. I prefer to inject the container rather than have everything use a common static container. But, I know that lots of people just put a static reference for the entire app to share. If you do that, though, then you’re compromising the design.)

Anyhoo, I was poking around on StackOverFlow.com and came across a question about singletons. One of the responses referred to this article.

http://www.yoda.arachsys.com/csharp/singleton.html

I tried writing something like this once, but his is much better. I remember mine being a disaster. In fact, I’m not going to bother looking it up. (Also, I think I wrote it before I was against them.)

This lays it out pretty nicely, though I don’t fully agree with it.

I’m not responding to the author’s comments here… I’m just looking at the code samples and responding with my own opinion which may or may not agree with is.

Version 1 – Complete crap. This is a very common mistake not only with singletons but with thread-safety in general.

Version 2 – No good. That lock is only ever useful once, yet you lock every time you need it.

Version 3 – He doesn’t like this one. I do, though I write it a little differently. He makes some interesting comments. For example: it doesn’t work in java. I knew that, I just didn’t remember why. (I ran into that several years ago, but forgot the explanation). More relevant, he states it may work in .Net 2.0 but doesn’t conform to the standard. That’s food for thought. I didn’t know that. Regardless, this would be third on my list of best approaches.

Sidebar: I prefer a get method rather than a property (even though fxcop hates that), but I’ll go with the property.

 private static Singleton _instance = null; private static object _lock = new object(); public static Singleton Instance { get { if (_instance != null) { return _instance; } lock (_lock) { if (_instance != null) { return _instance; } _instance = new Singleton(); return _instance; } } } 

Version 4 – Now we’re getting somewhere. This is the way to do it.

Of course, this isn’t lazy loading. If you do something with the class other than call the singleton, the singleton is going to get instantiated for no reason. But, your class should do exactly one thing, so that shouldn’t be the case.

This would be my second on my list of best approaches.

Version 5 – I’ve never done this one, but have seen it twice at work. (One of them was a demo of a non-work related project. I don’t remember what the first one was). If you need lazy loading, then sure, this will work. But, per my point in Version 4, you shouldn’t need lazy loading.

Version 6 ?!?!?! – The article doesn’t have a version 6, but another way to do it is to use the static constructor rather than the variables initializer. In the end, they end up being the same thing because the static initializers just get moved to the static constructor anyway. I think that using the initializer reads much better.

It was once argued to me that you can’t do anything complex in the initializer. All you can do is instantiate something. Not true… you can intialize to the result of a static method call. Put all the work in the method call.

So there you go. To summarize, here’s my list of preferred approaches

  1. I the name of all that is holy in the religion of your choice, don’t do it. Say nay to the singleton. there are plenty of swell better alternatives.
  2. Version 4 – Static initializer.
  3. If you must lazy load (in the scenario where the object only exists for purposes of the singleton), this is the way to lazy load. Despite the other guy’s valid objections, I’ve been doing this and preaching this for years. It always works. (I call it check/lock/check).

One is the overwhelming winner. There is always an alternative to singelton. Don’t put the lifetime management of your object inside the object. Its none of your object’s business about how its used… its a unit of work. Let the consumer decide how to best implement that unit of work.


The Aw Bus Remote Client

September 11, 2009

All of the Wcf contracts for Aw Bus are in an assembly by themselves. That assembly will be distributable. The admin program uses the service contract types directly rather than creating a proxy.

To use the channel factory, you need to specify the binding, address, contracts, etc. There’s a lot of setup there.

I usually wrap this up into an object than does the work for me. The constructor creates the service; the dispose destroys it.

This snippet is used to retrieve a list of all of the services hosted on a particular node.

NOTE: I don’t know why the code samples aren’t rendering correctly.

 BusServiceDescription[] descriptions; using (RemoteClient<INodeService> client1 = RemoteClient<INodeService>.GetClient("NodeAdmin")) { 	descriptions = client1.Proxy.GetServiceDescriptions(""); } tvOverview.Invoke(new MethodInvoker(delegate 

“NodeAdmin” is the name of the service. I append that to the base uri. Later, it will be used to determine all of the things it needs to properly connect to the service.

It handles all of the binding information, etc. Currently, all of the necessary goodies are hard coded. This will seriously evolve as new types of endpoints are exposed. There will be an endpoint provider on the back end.

I’ve used this wrapper approach before. I thought there was a problem with the dispose, though. We saw that if an exception occurs within the using clause, then another exception occurs within the dispose, the first exception is lost and the second bubbles up. We hacked a solution to that i’m not proud of, but it works.

When I built this new wrapper for Aw Bus, I set out to conquer that problem elegantly. And I did so, which I’ll get to. I started to prepare some code samples to demonstrate the problem and the solution; and wouldn’t you know it… I couldn’t reproduce it. I think I understand why, but what I don’t yet understand is why I didn’t figure it out before. I have to look at the other wrapper and see if I’m remembering it correctly. Simply putting a catch-all in the dispose allows the original exception to bubble up.

Anyway. Prior to realizing I didn’t need a solution, I built the solution. The solution no longer appears to be useful for that problem, but will be helpful for other purposes. Basically, I use reflection to inspect the service contract, then generate my own implementation of that interface which will call the service. Its an on-the-fly proxy generator. I control the code that gets generated, so I can put in any injection points or tracking that I’d like.

The generated type is stored in a cache, so it only gets generated once as long as each call uses the same cache. That will all be hidden form the user anyway; RemoteClient will take care of it.

Example:

INodeService is the service contract.

I generate INodeServiceProtectedProxy, which implements the interface. (I will drop the leading I.) The constructor creates the channel factory and the binding. The methods call the method on the channel. The dispose closes the channel, etc.

Here’s an example of a generated proxy. This is pretty minimal. But, as I said, its all template based. So, I can just slap around the template and have it do anything I want to. (I haven’t implemented the dispose pattern yet.

using System; using System.Collections.Generic; using System.Text; using System.ServiceModel; using System.ServiceModel.Channels;  namespace AllardWorks.AwBus.RemoteClient.ProtectedProxy {     public class INodeServiceProtectiveProxy : AllardWorks.AwBus.Contracts.Services.INodeService, IDisposable     {         private readonly ChannelFactory<AllardWorks.AwBus.Contracts.Services.INodeService> _proxy;         private readonly AllardWorks.AwBus.Contracts.Services.INodeService _instance; 		 		// temporary. remove soon 		public INodeServiceProtectiveProxy() 		{ 		} 		         public INodeServiceProtectiveProxy(Binding binding, string url)         {             _proxy = new ChannelFactory<AllardWorks.AwBus.Contracts.Services.INodeService>(binding, new EndpointAddress(url));             _instance = _proxy.CreateChannel();         }  		             [OperationContract]             public AllardWorks.AwBus.Contracts.BusServiceDescription[] GetServiceDescriptions (System.String token)             {                 try                 {                     return  _instance.GetServiceDescriptions(token);                 }                 catch                 {                     Close();                     throw;                 }             }                                  [OperationContract]             public AllardWorks.AwBus.Contracts.RemoteWcfEndpointDescription[] GetAdminServiceEndpoints (System.String token, System.String serviceName)             {                 try                 {                     return  _instance.GetAdminServiceEndpoints(token, serviceName);                 }                 catch                 {                     Close();                     throw;                 }             }                                  [OperationContract]             public AllardWorks.AwBus.Contracts.RemoteNodeDescription GetNodeDescription (System.String token)             {                 try                 {                     return  _instance.GetNodeDescription(token);                 }                 catch                 {                     Close();                     throw;                 }             }                      		         private bool _closed;         private void Close()         {             if (_closed)             {                 return;             }             try             {                 _proxy.Close();             } 			catch 			{ 			}         }          private bool _disposed;         public void Dispose()         {             Close();         }     } } 

Aw Bus Update

September 11, 2009

image

Progress continues

– finished the RemoteClient so that it is sufficient for current needs. Its going to continuously evolved.

– created an MDI form – no big deal there. IT comes out of the box as shown; I just added the base url text box. I created an ISessionContext interface that wraps up all of the things from the parent form that the other forms may need. That will be passed to all new child forms.

– Changed all communication to Wcf. The form was using a local server object to start with.

– Separated the server from the form. Now that its all Wcf, the form app is strictly a client

– Added a GetNodeInfo() method to the NodeAdmin service. Its results are shown in the lower right corner.

You’ll see that the container service is currently stopped. That’s because I deleted one file too many during a cleanup. I lost the ContainerStore.xml, which is the default container store. I haven’t retrieved it back from Svn yet. Whoops.

What’s next?

Currently, the server is hard coded to start as Node 1. I have to break that up so that I can start multiple nodes. The console host will allow you to pick which one you want to start, etc.

I have a couple things I want to do after that, but I’m pretty sure the one I’ll actually focus on will be the drag-and-drop of packages from one node to another.

Something I should do before that (but won’t because it won’t be as much fun) is expose the logging. I had been planning to do that via the pub-sub, but since that’s not progressing right now, I may look at other possibilities. Right now, in the screenshot, it would obviously be good to know why the container service didn’t start.


AwBus – First Screenshot

September 7, 2009

image

I’ve been spending a lot of time working on a service bus. I have a lot of goals for it; they’re all based on it being extremely simple. When you unzip it, you can launch the executable and be up and running without any additional configuration. There will be a lot you can do and should do, but nothing will be required to get started.

The bus contains one or more nodes which exists in one or more processes on one or more machines. You can drag and drop containers and individual packages from one node to another; it will continue to exist in the old node until all pending requests are complete. In the meantime, the broker will switch to the new one for new requests.

Each node contains services that the node needs. 4 of them are shown above;

  1. Wcf Host Service – manages all of the Wcf endpoints.
  2. App Domain Host Services – every package runs in its own app domain. Additionally, temporary app domains are used to explore all of the assemblies in a particular folder to determine what things should be auto-started. (Currently, self starts include Subscribers. Wcf services are next)
  3. The container service manages all of the containers in the node. A container is a home for a package. A package can contain one or more pieces of functionality; publisher, subscriber, Wcf service, etc
  4. Folder service – When a package is deployed, it is deployed to a folder. The folder service keeps track of what folders have been created and why

Each bus service can be decorated with an attribute that identifies a Wcf admin service. The screenshot shows that the Wcf Host Service and Container Service each have an admin service. Node service is also an admin service, but its admin for the node itself, not a particular service.

Currently, the containers node is empty. I’m converting that to retrieve the container info remotely.

The very early stages of the pub-sub are in there, but it only works on the local node.

I’ve been focusing on the client for the last couple days. Some of the things in the screen shot are built from references to the server object. Others are retrieved via Wcf. It should be via Wcf, so I’m moving them over. To facilitate that, I had to start building the client. (You can create any old Wcf client for the service, but I wrapped it up with some bus specific functionality.)

I’m pretty excited about this project. Let’s see how it goes. So far, I’m very pleased with its progress.

More to come.


Code Test

September 6, 2009

 

I’m switching to WordPress.

Trying a code sample….

namespace testing
{
    public class Something\
    {
        public void Whatever()
        {
        }
    }
}