public async Task RunAsync()
        {
            Console.WriteLine("Request processor starting up");
            await requestChannel.ReceiveAllAsync(async token =>
            {
                Stopwatch s = new Stopwatch();
                s.Start();

                await parser.ParseAsync(token);

                s.Stop();
                statsChannel.Publish(s.ElapsedMilliseconds);
            });

            Console.WriteLine("Request processor shutting down, channel is closed");
        }
        private async Task <IActionResult> TokenizedStreamInternalAsync(
            string channel,
            string token = null)
        {
            var tokenParseResult = await _tokenParser.ParseAsync(
                new TokenParserModel
            {
                Channel = channel, Token = token, HttpContext = HttpContext
            });

            var session = tokenParseResult.session;

            if (session == null)
            {
                return(tokenParseResult.actionResult);
            }

            M3U8Playlist playlist;

            try
            {
                var collectorModel = new ChunksCollectorModelByLast
                {
                    Channel       = session.Channel,
                    HlsListSize   = session.HlsListSize,
                    LastChunkPath = session.LastFilePath
                };
                playlist = _playlistAssembler.Aseemble(
                    session,
                    _chunkCollector.GetNextBatch(collectorModel));

                //playlist = _m3u8Generator.GenerateNextM3U8(
                //channel,
                //session.HlsListSize,
                //session.LastFileIndex,
                //session.LastFileTimeSpan);
            }
            catch (ChunkCollectorException e)
            { return(Content(e.Message)); }

            Console.WriteLine(
                "[StreamCtrl]:> m3u8: {0} TOKEN: {1}",
                string.Join(
                    ", ",
                    playlist.Files.Select(x => x.FilePath)),
                session.LastFilePath
                );

            session.LastFilePath = playlist.Files.First().FilePath;

            try
            {
                await _cache.SetObjAsync(
                    token,
                    session,
                    GetSessionExpiration());
            }
            catch (Exception)
            { return(View("RedisConnectionException")); }

            var result = playlist.Bake($"token={token}");

            if (session.DisplayContent)
            {
                return(Content(result));
            }
            else
            {
                return(GenerateDownloadableContent(result));
            }
        }