예제 #1
0
        private async void TimedCleanAsync(object state)
        {
            logger.LogInformation("Starting broadcast cleaning task");

            var inactiveLimit = DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(1));
            Expression <Func <Broadcast, bool> > filter = x => x.Expired != true && x.Activity.Value.CompareTo(inactiveLimit) <= 0;

            var broadcasts = await repository.FindRangeAsync(filter);

            var first = broadcasts.FirstOrDefault();

            if (first == null)
            {
                return;
            }

            logger.LogDebug("Inactive broadcast: {object}", new { id = first.Id, timestamp = first.Activity.Value.Ticks });



            HttpResponseMessage response = default;

            var clusteringClient = new HttpClient
            {
                BaseAddress = new Uri(configuration.GetValue <string>("CLUSTERING_URL"))
            };

            var relayClient = new HttpClient
            {
                BaseAddress = new Uri($"{configuration.GetValue<string>("RELAY_URL")}")
            };

            HttpStatusCode statusCode = default;

            foreach (var id in broadcasts.Select(x => x.Id))
            {
                try
                {
                    await relayClient.DeleteAsync(id);

                    response = await clusteringClient.PostAsJsonAsync("/data/remove", new { id = id });
                }
                catch (OperationCanceledException)
                {
                    continue;
                }

                if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.NotFound)
                {
                    // Calculate score
                    var viewerResponse = await viewers.FindRangeAsync(x => x.BroadcastId == id);

                    var date  = DateTime.UtcNow;
                    var score = BroadcastUtility.CalculateScore(viewerResponse, date);

                    var broadcast = await repository.UpdateAsync(
                        x => x.Id == id,
                        new Broadcast { Expired = true, Activity = DateTime.UtcNow, Score = score });

                    // Update account score
                    var account = await accounts.FindAsync(x => x.Id == broadcast.AccountId);

                    if (account != null)
                    {
                        var accountScore = account.Score;

                        if (accountScore == null)
                        {
                            accountScore = 0;
                        }

                        account.Score = score + accountScore;

                        await accounts.UpdateAsync(x => x.Id == broadcast.AccountId, account);
                    }

                    logger.LogDebug(
                        "Broadcast {id} stopped due to inactivity",
                        id);
                }
                else
                {
                    if (statusCode == response.StatusCode)
                    {
                        continue;
                    }

                    logger.LogError(
                        "{status}: {message}",
                        response.StatusCode.ToString(),
                        await response.Content.ReadAsStringAsync());

                    statusCode = response.StatusCode;
                }
            }
        }
예제 #2
0
        public BroadcastType(IRepository <Account> accounts, IRepository <Viewer> viewers)
        {
            Field(x => x.Id);
            Field(x => x.Location, type: typeof(LocationType));
            Field(x => x.Activity, type: typeof(DateTimeGraphType));
            Field(x => x.Categories);

            FieldAsync <NonNullGraphType <IntGraphType> >(
                "score",
                resolve: async context => {
                if (context.Source.Score == null)
                {
                    var response = await viewers.FindRangeAsync(x => x.BroadcastId == context.Source.Id, context.CancellationToken);
                    var score    = BroadcastUtility.CalculateScore(response, context.Source.Activity);
                    // TODO: Update broadcast to contain score?
                    return(score);
                }
                else
                {
                    return(context.Source.Score);
                }
            }
                );

            FieldAsync <ListGraphType <ViewerDateTimePairType> >(
                "joinedTimeStamps",
                resolve: async context => {
                var response = await viewers.FindRangeAsync(x => x.BroadcastId == context.Source.Id, context.CancellationToken);
                return(BroadcastUtility.GetJoinedTimeStamps(response));
            }
                );

            FieldAsync <ListGraphType <ViewerDateTimePairType> >(
                "leftTimeStamps",
                resolve: async context => {
                var response = await viewers.FindRangeAsync(x => x.BroadcastId == context.Source.Id, context.CancellationToken);

                return(BroadcastUtility.GetLeftTimeStamps(response));
            }
                );

            Field(x => x.Reports);

            Field <NonNullGraphType <IntGraphType> >(
                "positiveRatings",
                resolve: context => context.Source.PositiveRatings.GetValueOrDefault()
                );

            Field <NonNullGraphType <IntGraphType> >(
                "negativeRatings",
                resolve: context => context.Source.NegativeRatings.GetValueOrDefault()
                );

            FieldAsync <ListGraphType <ViewerType> >(
                "viewers",
                "The viewers associated with this broadcast",
                resolve: async context =>
                await viewers.FindRangeAsync(x => x.BroadcastId == context.Source.Id, context.CancellationToken)
                );

            FieldAsync <IntGraphType>(
                "viewer_count",
                "The number of viewers currently viewing this broadcast.",
                resolve: async context =>
                (await viewers.FindRangeAsync(x => x.BroadcastId == context.Source.Id, context.CancellationToken))
                .GroupBy(x => x.AccountId)
                .Count(x => x.Count() % 2 != 0),
                deprecationReason: "'viewer_count' is changed to 'current_viewer_count' in the coming update"
                );

            FieldAsync <IntGraphType>(
                "current_viewer_count",
                "The number of viewers currently viewing this broadcast.",
                resolve: async context =>
                (await viewers.FindRangeAsync(x => x.BroadcastId == context.Source.Id, context.CancellationToken))
                .GroupBy(x => x.AccountId)
                .Count(x => x.Count() % 2 != 0)
                );

            FieldAsync <IntGraphType>(
                "total_viewer_count",
                "The total number of viewers that has viewed this broadcast.",
                resolve: async context =>
                (await viewers.FindRangeAsync(x => x.BroadcastId == context.Source.Id, context.CancellationToken))
                .GroupBy(x => x.AccountId)
                .Count()
                );

            FieldAsync <AccountType>(
                "broadcaster",
                "the broadcast owner",
                resolve: async context =>
                await accounts.FindAsync(x => x.Id == context.Source.AccountId, context.CancellationToken)
                );
        }