protected override async Task ExecuteAsync(CancellationToken cancelToken) { try { while (!cancelToken.IsCancellationRequested) { try { Func <CancellationToken, Task <KonluluStreamGrabStateObject> > workItem = await taskQueue.DequeueAsync(cancelToken); KonluluStreamGrabStateObject stateObj = await workItem(cancelToken); { switch (stateObj.State) { case KonluluStreamGrabState.GetUpcomingStream: { YouTubeService ytService = ytInterface.GetYoutubeService(); string livestreamId = await ytInterface.GetLiveStream(ytService, "Upcoming"); bool foundLivestream = livestreamId != null; if (livestreamId == null) { logger.LogInformation("found no upcoming stream"); if (stateObj.IsStartup) { livestreamId = await ytInterface.GetLiveStream(ytService, "Live"); foundLivestream = livestreamId != null; if (livestreamId == null) { logger.LogInformation("found no live stream"); } } } if (!foundLivestream) { taskQueue.QueueBackgroundWorkItem((c) => StateTimer(c, new KonluluStreamGrabStateObject( KonluluStreamGrabState.GetUpcomingStream, DateTime.UtcNow, DateTime.UtcNow.AddHours(1)) ) ); } else { logger.LogInformation($"found upcoming stream {livestreamId}"); VideoDto video = await ytInterface.GetVideoInfo(ytService, livestreamId, getScheduledTime : true); if (video == null) { taskQueue.QueueBackgroundWorkItem((c) => StateTimer(c, new KonluluStreamGrabStateObject( KonluluStreamGrabState.GetUpcomingStream, DateTime.UtcNow, DateTime.UtcNow.AddMinutes(20)) { VideoId = stateObj.VideoId } ) ); } else { taskQueue.QueueBackgroundWorkItem((c) => StateTimer(c, new KonluluStreamGrabStateObject( KonluluStreamGrabState.WaitForTheUpcomingStream, DateTime.UtcNow, video.StartTime) { VideoId = livestreamId } ) ); } } break; } case KonluluStreamGrabState.WaitForTheUpcomingStream: { taskQueue.QueueBackgroundWorkItem((c) => StateTimer(c, new KonluluStreamGrabStateObject( KonluluStreamGrabState.WaitForActualStartOfStream, DateTime.UtcNow, DateTime.UtcNow.AddSeconds(1)) { VideoId = stateObj.VideoId } ) ); break; } case KonluluStreamGrabState.WaitForActualStartOfStream: { YouTubeService ytService = ytInterface.GetYoutubeService(); VideoDto video = null; try { video = await ytInterface.GetVideoInfo(ytService, stateObj.VideoId); if (video == null) { taskQueue.QueueBackgroundWorkItem((c) => StateTimer(c, new KonluluStreamGrabStateObject( KonluluStreamGrabState.GetUpcomingStream, DateTime.UtcNow, DateTime.UtcNow.AddMinutes(20)) { VideoId = stateObj.VideoId } ) ); } } catch (StartCapturingTooSoonException) { taskQueue.QueueBackgroundWorkItem((c) => StateTimer(c, new KonluluStreamGrabStateObject( KonluluStreamGrabState.WaitForActualStartOfStream, DateTime.UtcNow, DateTime.UtcNow.AddMinutes(2)) { VideoId = stateObj.VideoId } ) ); break; } catch (Exception ex) { logger.LogError(ex, nameof(KonluluStreamGrabState.WaitForActualStartOfStream)); break; } using (IServiceScope scope = serviceScopeFactory.CreateScope()) { IVideoRepository videoDb = scope.ServiceProvider.GetRequiredService <IVideoRepository>(); ITagService tagService = scope.ServiceProvider.GetRequiredService <ITagService>(); videoDb.Save(new Video(video)); logger.LogInformation("captured {0}", video.VideoId); await tagService.StartTag(video.VideoId); } taskQueue.QueueBackgroundWorkItem((c) => StateTimer(c, new KonluluStreamGrabStateObject( KonluluStreamGrabState.WaitForEndOfStream, DateTime.UtcNow, DateTime.UtcNow.AddSeconds(1)) { VideoId = stateObj.VideoId } ) ); break; } case KonluluStreamGrabState.WaitForEndOfStream: { YouTubeService ytService = ytInterface.GetYoutubeService(); VideoDto video = null; try { video = await ytInterface.GetVideoInfo(ytService, stateObj.VideoId, getActualEndTime : true); if (video == null) { taskQueue.QueueBackgroundWorkItem((c) => StateTimer(c, new KonluluStreamGrabStateObject( KonluluStreamGrabState.GetUpcomingStream, DateTime.UtcNow, DateTime.UtcNow.AddMinutes(20)) { VideoId = stateObj.VideoId } ) ); } } catch (NoActualEndtimeException) { taskQueue.QueueBackgroundWorkItem((c) => StateTimer(c, new KonluluStreamGrabStateObject( KonluluStreamGrabState.WaitForEndOfStream, DateTime.UtcNow, DateTime.UtcNow.AddMinutes(15)) { VideoId = stateObj.VideoId } ) ); break; } catch (Exception ex) { logger.LogError(ex, nameof(KonluluStreamGrabState.WaitForActualStartOfStream)); break; } using (IServiceScope scope = serviceScopeFactory.CreateScope()) { IVideoRepository videoDb = scope.ServiceProvider.GetRequiredService <IVideoRepository>(); videoDb.Save(new Video(video)); logger.LogInformation("captured the end of {0}", video.VideoId); } taskQueue.QueueBackgroundWorkItem((c) => StateTimer(c, new KonluluStreamGrabStateObject( KonluluStreamGrabState.GetUpcomingStream, DateTime.UtcNow, DateTime.UtcNow.AddSeconds(1)) { VideoId = stateObj.VideoId } ) ); break; } default: logger.LogError("you shouldnt be here"); break; } } } catch (Exception ex) { StringBuilder sb = new StringBuilder(); sb.AppendLine(ex.Message); sb.AppendLine(ex.StackTrace); logger.LogError(sb.ToString()); } } } catch (Exception ex) { StringBuilder sb = new StringBuilder(); sb.AppendLine("Exception when loading command modules"); sb.AppendLine(ex.Message); sb.AppendLine(ex.StackTrace); logger.LogError(sb.ToString()); } }
private static Task <KonluluStreamGrabStateObject> StateTimer(CancellationToken cancellationToken, KonluluStreamGrabStateObject stateobj) { int time = (int)(stateobj.StateWaitUntil - DateTime.UtcNow).TotalMilliseconds; if (time < 0) { time = 0; } return(Task.Delay(time).ContinueWith((c) => { return stateobj; })); }