# ASP.NET and Windows Service Microservices with Akka.Cluster
The goal of this sample is to show you how to use `Akka.Cluster` to form resilient systems that can scale out across multiple processes or machines without complicated user-defined code or expensive tools.
In this sample you'll also see how to integrate Akka.NET with the following technologies:
- **[ASP.NET MVC5](http://www.asp.net/mvc/mvc5)**;
- **[SignalR](http://signalr.net/ "Websockets for .NET")** - Websockets library for .NET;
- **[Topshelf](http://topshelf-project.com/ "Topshelf Project - easily turn console apps into Windows Services")** - Windows Services made easy;
- **[HTML Agility Pack](http://htmlagilitypack.codeplex.com/)** - for parsing crawled web pages; and
- **[Lighthouse](https://github.com/petabridge/lighthouse "Lighthouse - Service Discovery for Akka.NET")** - a lightweight service discovery platform for Akka.Cluster.
## Sample Overview
In the `WebCrawler` sample we're actually going to run four different pieces of software concurrently:
* **`[Lighthouse]`** - An instance of the **[Lighthouse](https://github.com/petabridge/lighthouse "Lighthouse - Service Discovery for Akka.NET")** service, so you'll want to clone and build that repository in you intend to run this sample;
* **`[Crawler]`** - A dedicated Windows Service built using **[Topshelf](http://topshelf-project.com/ "Topshelf Project - easily turn console apps into Windows Services")**. This is where all of the scalable processing work is done in this sample, and multiple instances of these services can be run in parallel in order to cooperatively execute a web crawl. The source for `[Crawler]` is inside the [`src\WebCrawler.CrawlService`](src/WebCrawler.CrawlService) folder. This is a stateless service, designed to be scaled out dynamically.
* **`[Tracker]`** - A dedicated Windows Service built using **[Topshelf](http://topshelf-project.com/ "Topshelf Project - easily turn console apps into Windows Services")**. This is where all the state of a webcrawl is managed, and the service that ensures that processing isn't wasted by allowing only one `CrawlJob` per domain. This is a stateful service that remotely deploys fan-out processing hierarchies under the `DownloadCoordinator` onto `[Crawler]` nodes in the cluster. The source for `[Tracker]` is inside the [`src\WebCrawler.TrackingService`](src/WebCrawler.Service) folder.
* **`[Web]`** - An ASP.NET MVC5 application that uses **[SignalR](http://signalr.net/ "Websockets for .NET")** to send commands to and receive data from `[Tracker]` instances. Multiple `[Web]` instances may be run in parallel, but they're unaware of eachother's crawl jobs by default.
> NOTE: `WebCrawler.sln` should attempt to launch one instance of `[Crawler]`, `[Tracker]` and `[Web]` by default.
### Goal: Use Microservices Built with Akka.Cluster to Crawl Web Domains with Elastic Scale
The goal of this sample is to have all three of these services work cooperatively together to crawl multiple web domains in parallel. Here's what the data flow of an individual domain crawl looks like:

The crawl begins by downloading the root document of the domain, so if we were to crawl [http://petabridge.com/](http://petabridge.com "Petabridge LLC homepage") we'd begin by downloading `index.html`.
On `index.html` we discover links to more images and documents, so we mark those new pages as "discovered" and repeat the downloading / parsing process until no more content has discovered.
> NOTE: the only thing this sample does not attempt to do is save the documents to a persistent store; that's an exercise left up to readers.
Here's an example of the service in-action, crawling MSDN and Rotten Tomatoes simultaneously across two `[Crawler]` processes:
<a href=
"diagrams/crawler-live-run.gif"><img src="diagrams/crawler-live-run.gif" style="width:600px; margin:auto;" alt="WebCrawler Demo In-Action (animated gif)"/><p>Click for a full-sized image.</p></a>
## Critical Concepts
In this example you'll be exposed to the following concepts:
1. **Akka.NET Remoting** - how remote addressing, actor deployment, and message delivery works in Akka.NET.
2. **Microservices** - the software architecture style used to organize the WebCrawler sample into dedicated services for maximum resiliency and parallelism.
3. **Clustering** - a distributed programming technique that uses peer-to-peer networking, gossip protocols, addressing systems, and other tools to allow multiple processes and machines to work cooperatively together in an elastic fashion.
4. **ASP.NET & Windows Services Integration** - how to integrate Akka.NET into the most commonly deployed types of networked applications in the .NET universe.
### Akka.NET Remoting
Akka.NET's true power is unleashed when you start using `Akka.Remote` and the remoting capabilities it brings to Akka.NET.
#### Actors can be "deployed" anywhere
One of the important concepts behind Akka.NET is the notion of actor "deployments" - when you create an actor it can be deployed in any one of the following three modes:
1. **Local** deployments - this actor will be deployed on the machine calling `Context.ActorOf`.
2. **Remote** deployments - this actor will be deployed on a specific remote machine on the network, identified by its `Address`.
3. **Cluster** deployments - when the `Akka.Cluster` module is running, an actor can be deployed on *any* of the nodes that satisfy the cluster deployment criteria.
Here's an example of what a remote deployment actually looks like:
```csharp
var remoteActorRef = myActorSystem.ActorOf(Props.Create<Echo>()
.WithDeploy(new Deploy(
new RemoteScope(new Address("akka.tcp", "mySys", "localhost", 4033))), "remote-actor");
/*
* If an actor system can be found at `akka.tcp://mySys@localhost:4033`
* then a new actor will be deployed at `akka.tcp://mySys@localhost:4033/user/remote-actor`.
*/
```
**When this code is run, `IActorRef` is still returned on the actor system who deployed onto `akka.tcp://mySys@localhost:4033`.** And that `IActorRef` can be passed around locally anywhere within that process and all messages sent to it will be delivered remotely to the actual actor instance running on `akka.tcp://mySys@localhost:4033` .
#### An `IActorRef` is just an `IActorRef`, regardless of how it was deployed
[Because Akka.NET `IActorRef`s have location transparency](http://petabridge.com/blog/akkadotnet-what-is-an-actor/), one of the amazing benefits of this is that when you write your Akka.NET actor code it will work seamlessly for all actors regardless of how they're deployed.
This means that [the following code from the `[Crawler]` service](src/WebCrawler.Shared.IO/DownloadCoordinator.cs) will work equally well with actors running on remote systems or locally within the same process:
```csharp
// commander and downloadstracker can both be running on different systems
public DownloadCoordinator(CrawlJob job, IActorRef commander, IActorRef downloadsTracker, long maxConcurrentDownloads)
{
Job = job;
DownloadsTracker = downloadsTracker;
MaxConcurrentDownloads = maxConcurrentDownloads;
Commander = commander;
Stats = new CrawlJobStats(Job);
Receiving();
}
```
Location transparency and the ability to send messages to any actor of regardless of where it's actually deployed is how Akka.NET is able to achieve elastic scale-out so seamlessly - you, as the application developer, simply don't need to care how an actor was deployed.
### Microservice Architecture
"Microservice" is a relatively new term in the lexicon of distributed systems programming. Here's [how "Microservice" is defined by Martin Fowler](http://martinfowler.com/articles/microservices.html):
> In short, the microservice architectural style [1] is an approach to developing a single application as a suite of small service