<commit_before>![Logo](https://raw.githubusercontent.com/justinjstark/Verdeler/master/Verdeler.png)

# Verdeler

[![Build status](https://ci.appveyor.com/api/projects/status/bc2sduxl2rjwehyo?svg=true)](https://ci.appveyor.com/project/justinjstark/verdeler) [![MIT license](https://img.shields.io/github/license/justinjstark/verdeler.svg)](https://img.shields.io/github/license/justinjstark/verdeler.svg)

(vur-**dey**-ler)

A .NET distribution framework supporting custom distributables and endpoints.

## How It Works

Verdeler is designed to coordinate the delivery of files or other custom distributables to recipient endpoints. It is possible for one recipient to have multiple endpoints of various types (FTP, Sharepoint, Web Service, etc). Once Verdeler is configured, calling the `Distribute(distributable, recipient)` method will send the distributable to all endpoints associated with the recipient. Verdeler chooses which endpoint delivery service(s) to use based on the type of the endpoint returned from the registered endpoint repositories.

## Setup

**1. Define a distributable, recipient, and endpoint(s)**

```C#
public class File : Distributable
{
    public string Name;
    public byte[] Contents;
}

public class Vendor : Recipient
{
    public string Name;
    public int Port;
}

public class FtpEndpoint : Endpoint
{
    public string Host;
}
```

**2. Define a repository to retrieve endpoints for a recipient**

```C#
public class FtpEndpointRepository : IEndpointRepository<Vendor>
{
    public IEnumerable<Endpoint> GetEndpointsForRecipient(Vendor vendor)
    {
        //Get the FTP endpoints for the vendor
    }
}
```

**3. Define an endpoint delivery service that sends the distributable to the endpoint**

```C#
public class FtpDeliveryService : EndpointDeliveryService<File, FtpEndpoint>
{
    public override async Task DoDeliveryAsync(File file, FtpEndpoint ftpEndpoint)
    {
        //Deliver the file to the FTP endpoint
    }
}
```

**4. Register the repository and delivery service with the distributor and run the distributor**

```C#
var distributor = new Distributor<File, Vendor>();
distributor.RegisterEndpointRepository(new FtpEndpointRepository());
distributor.RegisterEndpointDeliveryService(new FtpDeliveryService());

distributor.DistributeAsync(someFile, someVendor).Wait();
```

## Concurrency

When endpoint delivery services are implemented asynchronously (ex: using [FtpClient.Async](https://github.com/rkttu/System.Net.FtpClient.Async)), the deliveries will be performed asynchronously.

```C#
var task1 = distributor.DistributeAsync(someFile1, someVendor);
var task2 = distributor.DistributeAsync(someFile2, someVendor);
Task.WaitAll(task1, task2);
```

Verdeler offers concurrency limitation functionality. There are two places where the maximum concurrency level can be specified.

**1. Distributor Concurrency Limitation**

```C#<commit_msg>Change name in README to Delivered<commit_after>![Delivered Logo](https://raw.githubusercontent.com/justinjstark/Verdeler/master/Delivered.png)

[![Build status](https://ci.appveyor.com/api/projects/status/bc2sduxl2rjwehyo?svg=true)](https://ci.appveyor.com/project/justinjstark/verdeler) [![MIT license](https://img.shields.io/github/license/justinjstark/verdeler.svg)](https://img.shields.io/github/license/justinjstark/verdeler.svg)

A .NET distribution framework supporting custom distributables and endpoints.

## How It Works

Delivered is designed to coordinate the delivery of files or other custom distributables to recipient endpoints. It is possible for one recipient to have multiple endpoints of various types (FTP, Sharepoint, Web Service, etc). Once configured, calling the `Distribute(distributable, recipient)` method will send the distributable to all endpoints associated with the recipient. Delivered chooses which endpoint delivery service(s) to use based on the type of the endpoint returned from the registered endpoint repositories.

## Setup

**1. Define a distributable, recipient, and endpoint(s)**

```C#
public class File : Distributable
{
    public string Name;
    public byte[] Contents;
}

public class Vendor : Recipient
{
    public string Name;
    public int Port;
}

public class FtpEndpoint : Endpoint
{
    public string Host;
}
```

**2. Define a repository to retrieve endpoints for a recipient**

```C#
public class FtpEndpointRepository : IEndpointRepository<Vendor>
{
    public IEnumerable<Endpoint> GetEndpointsForRecipient(Vendor vendor)
    {
        //Get the FTP endpoints for the vendor
    }
}
```

**3. Define an endpoint delivery service that sends the distributable to the endpoint**

```C#
public class FtpDeliveryService : EndpointDeliveryService<File, FtpEndpoint>
{
    public override async Task DoDeliveryAsync(File file, FtpEndpoint ftpEndpoint)
    {
        //Deliver the file to the FTP endpoint
    }
}
```

**4. Register the repository and delivery service with the distributor and run the distributor**

```C#
var distributor = new Distributor<File, Vendor>();
distributor.RegisterEndpointRepository(new FtpEndpointRepository());
distributor.RegisterEndpointDeliveryService(new FtpDeliveryService());

distributor.DistributeAsync(someFile, someVendor).Wait();
```

## Concurrency

When endpoint delivery services are implemented asynchronously (ex: using [FtpClient.Async](https://github.com/rkttu/System.Net.FtpClient.Async)), the deliveries will be performed asynchronously.

```C#
var task1 = distributor.DistributeAsync(someFile1, someVendor);
var task2 = distributor.DistributeAsync(someFile2, someVendor);
Task.WaitAll(task1, task2);
```

Delivered offers concurrency limitation functionality. There are two places where the maximum concurrency level can be specified.

**1. Distributor Concurrency Limitation**

```C#
{'fraction_non_alphanumeric': 0.09644582470669427, 'fraction_numerical': 0.004485852311939268, 'mean_word_length': 5.342450765864332, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 12, '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': '1905570', 'n_tokens_mistral': 1689, 'n_tokens_neox': 1594, 'n_words': 533}