public async Task RetryTask(string message) { var taskToRetry = JsonConvert.DeserializeObject <RetryTask>(message); using (var applicationDbContext = ApplicationDbContext.FromConnectionString(_config)) { var username = Context.User.FindFirstValue(ClaimTypes.NameIdentifier); var user = await applicationDbContext.Users.Where(x => x.NormalizedEmail == username.ToUpper()) .Select(x => new { x.Id, x.Credits }) .FirstOrDefaultAsync(); if (user.Credits <= 0) { var error = new CannotCreateTask { Reason = "Insufficient credits." }; await Clients.Caller.SendAsync("CannotCreateTask", JsonConvert.SerializeObject(error)); return; } var userId = user.Id; #if DEBUG var workerUser = await applicationDbContext.Workers .Where(x => x.ConnexionId != null) .OrderBy(x => Guid.NewGuid()) .Select(x => new { x.ConnexionId, WorkerId = x.Id, x.UserId }) .FirstOrDefaultAsync(); #else var workerUser = await applicationDbContext.Workers .Where(x => x.ConnexionId != null && x.UserId != userId) .OrderBy(x => Guid.NewGuid()) .Select(x => new { x.ConnexionId, WorkerId = x.Id, x.UserId }) .FirstOrDefaultAsync(); #endif if (workerUser == null) { var error = new CannotCreateTask { Reason = "Not enough nodes." }; await Clients.Caller.SendAsync("CannotCreateTask", JsonConvert.SerializeObject(error)); return; } var workerTask = await applicationDbContext.WorkerTasks .Include(x => x.RequestorTask) .Where(x => x.Id == taskToRetry.Id) .FirstOrDefaultAsync(); workerTask.IsExecuted = false; workerTask.IsSuccessful = null; workerTask.ProviderId = workerUser.UserId; workerTask.WorkerId = workerUser.WorkerId; var response = new ReceivedTask { Parameter = workerTask.Parameter, WasmB64 = workerTask.RequestorTask.WasmB64, TaskId = workerTask.Id, SubTaskTimeout = 3600000 }; await applicationDbContext.SaveChangesAsync(); await Clients.Client(workerUser.ConnexionId).SendAsync("NewTask", JsonConvert.SerializeObject(response)); var requestorConnexions = _connections.GetConnections(username.ToUpper()).ToList(); if (requestorConnexions.Any()) { await Clients.Clients(requestorConnexions).SendAsync("UpdateWorkerTask", JsonConvert.SerializeObject(new WorkerTaskDetail { Id = workerTask.Id, Result = workerTask.Result, Parameter = workerTask.Parameter, Output = workerTask.Output, IsSuccessful = workerTask.IsSuccessful, IsExecuted = workerTask.IsExecuted, ElapsedMilliseconds = workerTask.ElapsedMilliseconds })); } } }
public async Task CreatedTask(string message) { var createdTask = JsonConvert.DeserializeObject <TaskCreation>(message); using (var applicationDbContext = ApplicationDbContext.FromConnectionString(_config)) { var username = Context.User.FindFirstValue(ClaimTypes.NameIdentifier); var user = await applicationDbContext.Users.Where(x => x.NormalizedEmail == username.ToUpper()) .Select(x => new { x.Id, x.Credits }) .FirstOrDefaultAsync(); if (user.Credits <= 0) { var error = new CannotCreateTask { Reason = "Insufficient credits." }; await Clients.Caller.SendAsync("CannotCreateTask", JsonConvert.SerializeObject(error)); return; } var userId = user.Id; var dbRequestorTask = new RequestorTask { RequestorId = userId, WasmB64 = createdTask.WasmB64, WorkerTasks = new List <WorkerTask>() }; #if DEBUG var allConnections = await applicationDbContext.Workers .Where(x => x.ConnexionId != null) .OrderBy(x => Guid.NewGuid()) .ToDictionaryAsync(x => x.ConnexionId, x => new { WorkerId = x.Id, x.UserId }); #else var allConnections = await applicationDbContext.Workers .Where(x => x.ConnexionId != null && x.UserId != userId) .OrderBy(x => Guid.NewGuid()) .ToDictionaryAsync(x => x.ConnexionId, x => new { WorkerId = x.Id, x.UserId }); #endif var i = 0; Dictionary <string, string> tasksToSend = new Dictionary <string, string>(); foreach (var conn in allConnections) { var workerTask = new WorkerTask { Parameter = i, ProviderId = conn.Value.UserId, WorkerId = conn.Value.WorkerId }; dbRequestorTask.WorkerTasks.Add(workerTask); var response = new ReceivedTask { Parameter = i, WasmB64 = createdTask.WasmB64, TaskId = workerTask.Id, SubTaskTimeout = 3600000 }; tasksToSend.Add(conn.Key, JsonConvert.SerializeObject(response)); i++; if (i == createdTask.NumberOfNodes) { break; } } if (tasksToSend.Count < createdTask.NumberOfNodes) { var error = new CannotCreateTask { Reason = "Not enough nodes." }; await Clients.Caller.SendAsync("CannotCreateTask", JsonConvert.SerializeObject(error)); return; } applicationDbContext.RequestorTasks.Add(dbRequestorTask); await applicationDbContext.SaveChangesAsync(); foreach (var task in tasksToSend) { await Clients.Client(task.Key).SendAsync("NewTask", task.Value); } await SendNewStatisicsInternal(username.ToUpper(), true); } }