public Task Dispatch(DashboardContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var consoleId = ConsoleId.Parse(context.UriMatch.Groups[1].Value);

            var startArg = context.Request.GetQuery("start");

            // try to parse offset at which we should start returning requests
            int start;

            if (string.IsNullOrEmpty(startArg) || !int.TryParse(startArg, out start))
            {
                // if not provided or invalid, fetch records from the very start
                start = 0;
            }

            var buffer = new StringBuilder();

            using (var data = new ConsoleStorage(context.Storage.GetConnection()))
            {
                ConsoleRenderer.RenderLineBuffer(buffer, data, consoleId, start);
            }

            context.Response.ContentType = "text/html";
            return(context.Response.WriteAsync(buffer.ToString()));
        }
        public NonEscapedString Render(HtmlHelper helper, IDictionary <string, string> stateData)
        {
            var builder = new StringBuilder();

            builder.Append("<dl class=\"dl-horizontal\">");

            string serverId = null;

            if (stateData.ContainsKey("ServerId"))
            {
                serverId = stateData["ServerId"];
            }
            else if (stateData.ContainsKey("ServerName"))
            {
                serverId = stateData["ServerName"];
            }

            if (serverId != null)
            {
                builder.Append("<dt>Server:</dt>");
                builder.Append($"<dd>{helper.ServerId(serverId)}</dd>");
            }

            if (stateData.ContainsKey("WorkerId"))
            {
                builder.Append("<dt>Worker:</dt>");
                builder.Append($"<dd>{stateData["WorkerId"].Substring(0, 8)}</dd>");
            }
            else if (stateData.ContainsKey("WorkerNumber"))
            {
                builder.Append("<dt>Worker:</dt>");
                builder.Append($"<dd>#{stateData["WorkerNumber"]}</dd>");
            }

            builder.Append("</dl>");

            var page = helper.GetPage();

            if (page.RequestPath.StartsWith("/jobs/details/"))
            {
                // We cannot cast page to an internal type JobDetailsPage to get jobId :(
                var jobId = page.RequestPath.Substring("/jobs/details/".Length);

                var startedAt = JobHelper.DeserializeDateTime(stateData["StartedAt"]);
                var consoleId = new ConsoleId(jobId, startedAt);

                builder.Append("<div class=\"console-area\">");
                builder.AppendFormat("<div class=\"console\" data-id=\"{0}\">", consoleId);

                using (var storage = new ConsoleStorage(page.Storage.GetConnection()))
                {
                    ConsoleRenderer.RenderLineBuffer(builder, storage, consoleId, 0);
                }

                builder.Append("</div>");
                builder.Append("</div>");
            }

            return(new NonEscapedString(builder.ToString()));
        }