Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@cybermaxs
Created December 19, 2014 11:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cybermaxs/4f635c21cca466adb389 to your computer and use it in GitHub Desktop.
Save cybermaxs/4f635c21cca466adb389 to your computer and use it in GitHub Desktop.
Batch requests experiments in Web Api. Like the async & parallel processing on server-side
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap 101 Template</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
</head>
<body>
<h1>Hello, world!</h1>
<button onclick='sendBatch();'>Send Sync batch</button>
<button onclick='sendAsyncBatch();'>Send Async batch</button>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<script src="https://rawgit.com/volpav/batchjs/master/src/batch.js"></script>
<script type="text/javascript">
function sendBatch() {
$.ajaxBatch({
url: '/api/batch',
data: [
{
type: 'GET',
url: '/get1'
},
{
type: 'GET',
url: '/get2',
},
{
type: 'GET',
url: '/get3',
}
],
complete: function (xhr, status, data) {
for (var i = data.length - 1; i >= 0; i--) {
console.log(data[i]);
};
}
});
}
function sendAsyncBatch() {
$.ajaxBatch({
url: '/api/asyncbatch',
data: [
{
type: 'GET',
url: '/get1'
},
{
type: 'GET',
url: '/get2',
},
{
type: 'GET',
url: '/get3',
}
],
complete: function (xhr, status, data) {
for (var i = data.length - 1; i >= 0; i--) {
console.log(data[i]);
};
}
});
}
</script>
</body>
</html>
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.2" targetFramework="net451" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.2" targetFramework="net451" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.2" targetFramework="net451" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.2" targetFramework="net451" />
<package id="Microsoft.Owin" version="3.0.0" targetFramework="net451" />
<package id="Microsoft.Owin.FileSystems" version="3.0.0" targetFramework="net451" />
<package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net451" />
<package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net451" />
<package id="Microsoft.Owin.StaticFiles" version="3.0.0" targetFramework="net451" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net451" />
<package id="Owin" version="1.0" targetFramework="net451" />
</packages>
using Microsoft.Owin.Hosting;
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Threading.Tasks;
namespace BatchRequestDemo
{
class Program
{
const string baseAddress = "http://localhost:9000/";
static void Main(string[] args)
{
// Start OWIN host
using (WebApp.Start<Startup>(url: baseAddress))
{
// Create HttpCient and make a request to api/values
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(baseAddress);
//no batch
Profile("SingleRequest", () =>
{
Task.WaitAll(
client.GetAsync("get1"),
client.GetAsync("get2"),
client.GetAsync("get3"));
});
//sync batch
Profile("SyncBatch", () =>
{
var batchrequest = CreateBatch(client, "api/batch");
var response = client.SendAsync(batchrequest).Result;
});
//async batch
Profile("AsyncBatch", () =>
{
var batchrequest = CreateBatch(client, "api/asyncbatch");
var response = client.SendAsync(batchrequest).Result;
});
Console.ReadLine();
}
Console.ReadLine();
}
private static void Profile(string name, Action action)
{
var watcher = Stopwatch.StartNew();
action();
watcher.Stop();
Console.WriteLine("{0} : {1} ms", name, watcher.ElapsedMilliseconds);
}
private static HttpRequestMessage CreateBatch(HttpClient client, string endpoint)
{
HttpRequestMessage get1Values = new HttpRequestMessage(HttpMethod.Get, client.BaseAddress+ "get1");
HttpRequestMessage get2Values = new HttpRequestMessage(HttpMethod.Get, client.BaseAddress + "get2");
HttpRequestMessage get3Values = new HttpRequestMessage(HttpMethod.Get, client.BaseAddress + "get3");
HttpMessageContent get1Content = new HttpMessageContent(get1Values);
HttpMessageContent get2Content = new HttpMessageContent(get2Values);
HttpMessageContent get3Content = new HttpMessageContent(get3Values);
MultipartContent content = new MultipartContent("mixed", "batch_" + Guid.NewGuid().ToString());
content.Add(get1Content);
content.Add(get2Content);
content.Add(get3Content);
HttpRequestMessage batchRequest = new HttpRequestMessage(HttpMethod.Post, endpoint);
//Associate the content with the message
batchRequest.Content = content;
return batchRequest;
}
}
}
using Owin;
using System.Web.Http;
using System.Web.Http.Batch;
namespace BatchRequestDemo
{
public class Startup
{
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
HttpServer server = new HttpServer(config);
config.Routes.MapHttpBatchRoute(
routeName: "batch",
routeTemplate: "api/batch",
batchHandler: new DefaultHttpBatchHandler(server));
config.Routes.MapHttpBatchRoute(
routeName: "abatch",
routeTemplate: "api/asyncbatch",
batchHandler: new DefaultHttpBatchHandler(server) { ExecutionOrder = BatchExecutionOrder.NonSequential });
appBuilder.UseWebApi(config);
appBuilder.UseStaticFiles();
}
}
}
using System.Threading.Tasks;
using System.Web.Http;
namespace BatchRequestDemo
{
public class ValuesController : ApiController
{
[Route("get1")]
// GET api/values
public async Task<string> Get1()
{
await Task.Delay(1000);
return "I am Get1 !";
}
[Route("get2")]
// GET api/values
public async Task<string> Get2()
{
await Task.Delay(1000);
return "I am Get2 !";
}
[Route("get3")]
// GET api/values
public async Task<string> Get3()
{
await Task.Delay(1000);
return "I am Get3 !";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment