public Task <bool> SaveAsync(BackgroundTask task) { var db = GetDbConnection(); var t = BeginTransaction((SqlConnection)db, out var owner); var success = false; try { if (task.Id == default) { InsertBackgroundTask(task, db, t); } else { UpdateBackgroundTask(task, db, t); } UpdateTagMapping(task, db, t); success = true; } catch (Exception e) { _logger.Error(() => "Error saving task with ID {Id}", e, task.Id); } finally { if (owner) { if (success) { CommitTransaction(t); } else { RollbackTransaction(t); } } } return(Task.FromResult(success)); }
private object CreateHandler(BackgroundTask task) { try { var handlerInfo = Serializer.Deserialize <HandlerInfo>(task.Handler); var typeName = $"{handlerInfo.Namespace}.{handlerInfo.Entrypoint}"; var type = _typeResolver.FindByFullName(typeName) ?? _typeResolver.FindFirstByName(typeName); return(type == null ? null : _backgroundServices.AutoResolve(type)); } catch (Exception e) { _logger.Error(() => "Error creating handler for task", e); throw; } }
public static IEnumerable <LineConstructor> StreamLines(Stream stream, Encoding encoding, byte[] buffer, int maxWorkingMemoryBytes = 0, ISafeLogger logger = null, IMetricsHost metrics = null, CancellationToken cancellationToken = default) { buffer ??= Constants.Buffer; var queue = new BlockingCollection <LineConstructor>(new ConcurrentQueue <LineConstructor>()); logger?.Debug(() => "Started streaming lines"); var task = new Task(() => { if (!Task.CurrentId.HasValue) { throw new ArgumentNullException(nameof(buffer), "Could not find current thread ID"); } var id = Task.CurrentId.Value; long count = 0; var pendingLength = 0; try { unsafe { count = ReadLines(stream, encoding, PendingStreams[id], (lineNumber, partial, start, length, e) => { var line = new ReadOnlySpan <byte>(start, length); if (partial) { pendingLength = length; } else { var memory = new byte[length]; line.CopyTo(memory); var ctor = new LineConstructor { lineNumber = lineNumber, length = length + pendingLength, buffer = memory }; if (maxWorkingMemoryBytes > 0) { var usedBytes = queue.Count * (PendingStreams[id].Length + sizeof(long) + sizeof(int)); while (usedBytes > maxWorkingMemoryBytes) { Task.Delay(10, cancellationToken).Wait(cancellationToken); } } queue.Add(ctor, cancellationToken); pendingLength = 0; } }, logger, metrics, cancellationToken); } } catch (Exception ex) { logger?.Error(() => "Error streaming lines", ex); } finally { logger?.Debug(() => "Finished streaming {Count} lines", count); queue.CompleteAdding(); if (!PendingStreams.TryRemove(id, out _)) { throw new InvalidOperationException("Line stream failed trying to clean up"); } } }, cancellationToken); if (!PendingStreams.TryAdd(task.Id, buffer)) { throw new InvalidOperationException("Line stream failed trying to start up"); } task.Start(); return(queue.GetConsumingEnumerable(cancellationToken)); }