public async Task WriteStream(Stream stream, CitylineRequest request, IContext context, CancellationToken cancellationToken = default)
 {
     try
     {
         await DoWriteStream(stream, request, context, cancellationToken);
     }
     catch (TaskCanceledException) { }
 }
示例#2
0
        public async Task StartStream(CitylineRequest request, CancellationToken cancellationToken = default(CancellationToken))
        {
            var context = new CustomContext {
                RequestUrl = new Uri(Request.GetEncodedUrl()), User = User, SampleHeader = Request.Headers["sample"]
            };

            Response.Headers.Add("content-type", "text/event-stream");
            await _citylineService.WriteStream(Response.Body, request, context, cancellationToken);
        }
示例#3
0
 public ActionResult Simulate_500(CitylineRequest request, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(new StatusCodeResult(500));
 }
        public async Task DoWriteStream(Stream stream, CitylineRequest request, IContext context, CancellationToken cancellationToken = default)
        {
            ConcurrentDictionary <Task, object> tasks = new ConcurrentDictionary <Task, object>();

            var queue = new ConcurrentQueue <ICitylineProducer>(_providers);

            while (!cancellationToken.IsCancellationRequested)
            {
                if (queue.Count > 0)
                {
                    if (!queue.TryDequeue(out ICitylineProducer provider))
                    {
                        continue;
                    }

                    var          name   = provider.Name;
                    TicketHolder ticket = null;

                    if (request.Tickets == null)
                    {
                        request.Tickets = new Dictionary <string, string>();
                    }

                    if (request.Tickets.ContainsKey(name))
                    {
                        ticket = new TicketHolder(request.Tickets[name]);
                    }

                    ticket = ticket ?? new TicketHolder();

#pragma warning disable 4014
                    tasks.TryAdd(Task.Run(async() =>
                    {
                        try
                        {
                            var ownSource = new CancellationTokenSource();
                            cancellationToken.Register(ownSource.Cancel);

                            await RunProducer(provider, stream, ticket, context, ownSource.Token);

                            if (request.Tickets.ContainsKey(name))
                            {
                                request.Tickets[name] = ticket.AsString();
                            }
                            else
                            {
                                request.Tickets.Add(name, ticket.AsString());
                            }
                        }
                        catch (Exception ex) {
                            _logger.WriteLine($"Producer {provider.Name} failed: {ex}");
                        }
                        finally
                        {
                            queue.Enqueue(provider);
                        }
                    }).ContinueWith(task =>
                    {
                        _logger.WriteLine($"Task failed for {provider.Name} failed: {task.Exception}");

                        if (task.Exception != null)
                        {
                            throw task.Exception;
                        }
                    }, cancellationToken, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Current)
                                 .ContinueWith(task => tasks.TryRemove(task, out object value)), null);
#pragma warning restore 4014
                }

                await Task.Delay(200, cancellationToken);
            }

            await Task.WhenAll(tasks.Keys);
        }