Skip to content

Instantly share code, notes, and snippets.

@ismaelhamed
Last active March 29, 2021 06:30
Show Gist options
  • Save ismaelhamed/61b5baf5284f497ca681195f906dc626 to your computer and use it in GitHub Desktop.
Save ismaelhamed/61b5baf5284f497ca681195f906dc626 to your computer and use it in GitHub Desktop.
Hello Akka Http Server
internal class Program
{
private static readonly HttpResponse NotFound = HttpResponse.Create()
.WithStatus(404)
.WithEntity("Unknown resource!");
public static void Main(string[] _)
{
var system = ActorSystem.Create("HelloAkkaHttpServer");
var cs = CoordinatedShutdown.Get(system);
// sync handler
static HttpResponse RequestHandler(HttpRequest request) => request.Path switch
{
"/" => HttpResponse.Create().WithEntity("text/html(UTF-8)", "<html><body>Hello world!</body></html>"),
"/ping" => HttpResponse.Create().WithEntity("PONG!"),
_ => NotFound
};
var bindingTask = Http.Get(system).NewServerAt("localhost", 8085).BindSync(RequestHandler);
bindingTask.WhenComplete((binding, exception) =>
{
if (binding != null)
{
var address = (DnsEndPoint) binding.LocalAddress;
system.Log.Info("Server online at http://{0}:{1}/",
address.Host,
address.Port);
// make sure Akka HTTP is shut down in a proper way
cs.AddTask(CoordinatedShutdown.PhaseServiceStop, "shut-down-server-http",
() => binding.Terminate(10.Seconds()).Map(_ => Done.Instance));
}
else
{
system.Log.Error(exception, "Failed to bind HTTP endpoint, terminating system");
}
});
Console.WriteLine("Press Enter to exit...");
Console.ReadLine();
cs.Run(CoordinatedShutdown.UnknownReason.Instance);
}
}
// Just for fun
public static class TaskExtensions
{
public static Task<TResult> Map<TResult>(this Task source, Func<Task, TResult> selector)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (selector == null) throw new ArgumentNullException(nameof(selector));
return source.ContinueWith(selector, TaskContinuationOptions.NotOnCanceled);
}
public static Task<TResult> Map<TSource, TResult>(this Task<TSource> source, Func<TSource, TResult> selector)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (selector == null) throw new ArgumentNullException(nameof(selector));
return source.ContinueWith(t => selector(t.Result), TaskContinuationOptions.NotOnCanceled);
}
public static Task WhenComplete<TSource>(this Task<TSource> source, Action<TSource, Exception> continuationAction)
{
return source.ContinueWith(t =>
{
if (t.IsFaulted)
{
var exception = t.Exception?.InnerExceptions != null && t.Exception.InnerExceptions.Count == 1
? t.Exception.InnerExceptions[0]
: t.Exception;
continuationAction(default, exception);
}
else
{
continuationAction(t.Result, null);
}
}, TaskContinuationOptions.NotOnCanceled);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment