Whoops… I posted this on the wrong blog 2 days ago.
It’s been quite a while since my last post. I took a hiatus from major work on side projects.
Since about 2004 or 2005, I have building what I now call “Application Servers”. The first one I built was nameless. A former IBM employee that the company hired as a consultant spent some time with it and called it “An Application Server”, so it stuck.
DevDash, which I built a couple years ago, is a mini-application server that hosts just one application. I did just enough to host DevDash parts. I built that based on my experiences to that point; it solved every problem I had run into in previous versions. But then it introduced new things to learn from. In particular, the startup process are hard to control. It has services, and tasks, and it starts/executes them in order. IE: All services, then all tasks, etc. But, I ran into situations where I wanted to mix them up: Service A, Task A, Service B, etc. I had to putz around it.
Several months ago, I started writing a new app server primarily with the intent of working through all of the issues again. Really, it’s just an organizational/setup issue.
The solution to this was the command pattern. Rather than executing a bunch of things by type, it instead processes commands. You can add the commands in the desired order and it executes them one at a time. I use the command pattern for lots of things. It’s nice. It worked really well here.
That solved that problem. Then, it was onto the next issue which I struggled with quite a bit. I want this thing to be super simple to setup, and also super flexible. The flexibility is already there. You can wire it up to work anyway you want. You can swap out dependencies, add new stuff, remove stuff… but you need code/configuration to do it. The trick was to wrap that up in a user friendly way.
Several months ago, I wrote and threw away a lot of code a bunch of times. When the usability was reasonable, it didn’t work correctly behind the scenes. In some attempts, I was filling a unity container. One problem was when swapping dependencies, it didn’t have enough information to remove the old ones. It was quite the drama.
Then I didn’t touch it for a several months. I came back to it last week and made a few more attempts. At last, I have the setup working well.
It attempts to be a Fluent API, although I’m sure that can use some work. The setup objects keep track of everything they need without use of a container or anything else. Nothing is loaded until build time when the setup is converted into an appesrver object. So, if you swap out a dependency, the old setup object is replaced with the new one. It is extensible via subclassing and extension methods. When you put your own stuff into the appserver, you can do so directly. Or, if you’re in the mood, you can easily add it to the fluent API.
There are 3 out-of-the-box modes for the app server: Hub, Node, Application. Both HUB and NODE host applications. Unlike all previous versions, the application has it’s own server.
With the fluent API, you can prime it as one of the three then modify. Or, you can just build it from scratch on your own.
DevDash is self-updating. When you deploy changes to the repository, the nodes are alerted. They each download the updates and restart themslves. Sweet. That took A LOT of work. Also, you can deploy it remotely from the portal. Just give it a server name and the credentials, and it installs it and starts it. Pretty sweet.
That’s pretty involved. Configuration wise, it contains 2 list of files: one for the service and one for the application. Those files are automatically kept in sync.
For DevDash purposes, and also as research for a work project I’m championing, I’ve been looking into making that more configurable and reusable. I build some db objects to define (basically) as schema, and other tables to store the data. That’s all generic. Then I used that to store some deployment data, such as applicatoins/features/files (which the app server uses), and exposing that via services. That’s all working well. I haven’t actually done the deployment part as I’ve done that many times before and not much to figure out there. But, having the configurable model and services was a big help.
I spent untold hours on DevDash, and I’m proud of it. It deploys automatically. It stays updated automatically. It provides custom WS-Discovery, REST routing, pluggable rest services, and lots of other goodies. The portal site receives timely updates (usually within 10 seconds of an event).
It took a lot of work for that. The biggest challenge was having everything work even when it’s counterparts were down. IE: Nodes need to start even if the hub is down. WS-DISCOVERY in WCF doesn’t support that (the discovery service must be reachable), so I wrote a custom implementation to get around that. If the hub goes down, the nodes need to reconnect. If a node goes down, it needs to reconnect. It’s thorough and, while not perfect, works very well.
My biggest regret is that I didn’t know about SIGNALR at the time. That would’ve made everything so much simpler, from the node/hub communication to the website updates. I would’ve had several hours more sleep.
Bringing Them Together
Finally. Now, I am slowly working to bring them altogether.
Step 1 is geting the appserver as complete as I need it to host DevDash.
Step 2 is creating a DevDash application and host it in the app server
Step 3 is adding the deployment to the appservers
I have a lot of work ahead of me, and much free time to do it, so this is going to take forever. Plus, I tend to not to work on things for months at a time. The saving grace there is that I’ve done all the research and playing that I need to, so hopefully that minimizes distractions.
The insanity continues. I will post the setup code soon.