private void RunJob(string name, WorkerJob job) { try { _logger.Debug("Executing Job '{0}'", name); DateTime before = DateTime.UtcNow; try { job.RunOnce(); DateTime after = DateTime.UtcNow; } catch (Exception ex) { DateTime after = DateTime.UtcNow; _logger.ErrorException(String.Format("Error Executing Job '{0}': {1}", name, ex.Message), ex); } } catch (Exception ex) { _logger.ErrorException(String.Format("Infrastructure Error Executing Job '{0}': {1}", name, ex.Message), ex); } }
public async Task Handle(RefreshCalculations message, IMessageHandlerContext context) { Log.Info($"RefreshCalculations. ProcessId: '{Process.GetCurrentProcess().Id}'"); var currentJob = new WorkerJob() { ProcessId = Process.GetCurrentProcess().Id, StartDate = DateTime.UtcNow }; var lastJob = await _db.WorkerJobs.OrderByDescending(o => o.EndDate).FirstOrDefaultAsync(); var lastJobEndDate = lastJob?.EndDate ?? DateTime.MinValue; var checkpoint = DateTime.UtcNow; var unprocessedSessionWords = await _db.SessionWords.Where(w => w.DateCreated > lastJobEndDate).ToListAsync(); Log.Info($"{unprocessedSessionWords.Count} new words found."); await CalculateWordsPerSession(unprocessedSessionWords); await CalculateWordFrequency(unprocessedSessionWords); Log.Info($"Saving checkpoint. Next time will process words from date '{checkpoint:s}'."); currentJob.EndDate = DateTime.UtcNow; await _db.WorkerJobs.AddAsync(currentJob); await _db.SaveChangesAsync(); }
public async UnaryResult <Nil> ReportResult(Guid jobId, Heroine heroine, IReadOnlyList <int> selectionIds) { var workerId = await this.WorkerInitializeAsync().ConfigureAwait(false); await this.RetryWhenLocked(() => { this.RunInImmediateTransaction(conn => { var job = conn.FindWithQuery <WorkerJob>( "SELECT Choices, SearchResultId FROM WorkerJob WHERE Id = ?", jobId); if (job.SearchResultId.HasValue) { // すでに結果報告済み Utils.Log.WriteMessage($"報告が重複しています (Worker: {workerId})"); return; } var jobChoices = ModelUtils.ParseChoices(job.Choices); // 実際に選択したものは、 job.Choices + ずっと上 var choices = jobChoices.Concat( Enumerable.Repeat(ChoiceAction.SelectUpper, selectionIds.Count - jobChoices.Length)); var searchResult = new SearchResult() { Selections = ModelUtils.ToSelectionsString(selectionIds), Choices = ModelUtils.ToChoicesString(choices), Heroine = heroine, Timestamp = DateTimeOffset.Now, }; conn.Insert(searchResult); conn.Execute( "UPDATE WorkerJob SET WorkerId = ?, SearchResultId = ? WHERE Id = ?", workerId, searchResult.Id, jobId); // このレポートで発見された未探索のジョブを作成 for (var i = jobChoices.Length; i < selectionIds.Count; i++) { // 未探索の下を選ぶ var newChoices = choices.Take(i).Append(ChoiceAction.SelectLower); var newJob = new WorkerJob() { Id = Guid.NewGuid(), Choices = ModelUtils.ToChoicesString(newChoices), EnqueuedAt = DateTimeOffset.Now, }; conn.Insert(newJob); } }); }).ConfigureAwait(false); return(Nil.Default); }
public async UnaryResult <SeekDirectionResult> SeekDirection() { var workerId = await this.WorkerInitializeAsync().ConfigureAwait(false); return(await this.RetryWhenLocked(() => { return this.RunInImmediateTransaction(conn => { // 未着手のジョブを取得する // Choices が短いものから順に着手することで、新たなジョブを開拓していく var job = conn.FindWithQuery <WorkerJob>( "SELECT Id, Choices FROM WorkerJob WHERE WorkerId IS NULL ORDER BY length(Choices) LIMIT 1"); ChoiceAction[] actions; if (job == null) { var incompletedJobCount = conn.ExecuteScalar <int>( "SELECT count(*) FROM WorkerJob WHERE SearchResultId IS NULL"); if (incompletedJobCount > 0) { // 未完了のジョブがあるが、現在着手可能なジョブはない return new SeekDirectionResult(SeekDirectionResultKind.NotAvailable); } if (conn.Table <SearchResult>().Count() > 0) { // 探索結果が揃っているので、探索完了とみなす return new SeekDirectionResult(SeekDirectionResultKind.Finished); } // 初回ジョブを作成 job = new WorkerJob() { Id = Guid.NewGuid(), Choices = "", WorkerId = workerId, EnqueuedAt = DateTimeOffset.Now, }; conn.Insert(job); actions = Array.Empty <ChoiceAction>(); } else { actions = ModelUtils.ParseChoices(job.Choices); conn.Execute( "UPDATE WorkerJob SET WorkerId = ? WHERE Id = ?", workerId, job.Id); } Utils.Log.WriteMessage($"ワーカー #{workerId} にジョブ {job.Id} を指示"); return new SeekDirectionResult(SeekDirectionResultKind.Ok, job.Id, actions); }); }).ConfigureAwait(false)); }
public override void MakeRequest(I input, UnityAction <O> onJobDone) { var request = new CancelableRequest() { input = input, onJobDone = onJobDone }; _requests.Enqueue(request); var jobInfo = new JobInfo { request = request, responses = _responses, job = _job }; if (!_jobInfos.TryAdd(jobInfo.GetHashCode(), jobInfo)) { Debug.LogError($"Failed to add Request in {GetType()}."); } var workerJob = new WorkerJob { workerId = GetHashCode(), jobId = jobInfo.GetHashCode() }; workerJob.Schedule(); }