public IBrokerTransaction BeginTransaction(IJobServiceScope scope) { var dbContext = scope.GetRequiredService <TDbContext>(); var tx = dbContext.Database.BeginTransaction(); return(new BrokerTransaction(tx)); }
public void AckMessageProcessed(IJobServiceScope scope, ulong deliveryTag) { var dbContext = scope.GetRequiredService <TDbContext>(); var affectedCount = _sqlDialect.MessageQueueAckProcessed(dbContext, _instanceName, _timeProvider.GetCurrentTimeUtc()); if (affectedCount != 1) { throw new Exception($"Ack failed. Expected 1 row, but instead, {affectedCount} rows were affected"); } }
protected Worker(string queueName, int batchSize, int masMaxDegreeOfParallelism, bool singleActiveConsumer, IJobServiceScopeFactory serviceScopeFactory, IJobLogger <Worker> logger) : base(batchSize, logger) { ServiceScopeFactory = serviceScopeFactory; ServiceScope = ServiceScopeFactory.CreateScope(); _maxDegreeOfParallelism = masMaxDegreeOfParallelism; _singleActiveConsumer = singleActiveConsumer; _messageConsumer = ServiceScope.GetRequiredService <IMessageConsumer>(); QueueName = queueName; }
public SqlServerMessageReceiver(string queueName, bool singleActiveConsumer, IJobServiceScopeFactory scopeFactory, IJobLogger <SqlServerMessageReceiver <TDbContext> > logger) { _scopeFactory = scopeFactory; _scope = scopeFactory.CreateScope(); _queueName = queueName; _singleActiveConsumer = singleActiveConsumer; _sqlDialect = _scope.GetRequiredService <ISqlDialect>(); _timeProvider = _scope.GetRequiredService <ITimeProvider>(); _logger = logger; _instanceName = $"{Environment.MachineName}/{Guid.NewGuid()}"; _timer = _scope.GetRequiredService <ITimer>(); _timer.TimeElapsed += TimerCallback; }
public WorkerCoordinator(IJobServiceFactory serviceFactory, IJobLogger <WorkerCoordinator> logger = null) { ServiceScopeFactory = serviceFactory.GetRequiredService <IJobServiceScopeFactory>(); ServiceScope = ServiceScopeFactory.CreateScope(); _settings = ServiceScope.GetRequiredService <MassiveJobsSettings>(); _reconnectTimer = ServiceScope.GetRequiredService <ITimer>(); _reconnectTimer.TimeElapsed += Reconnect; Workers = new List <IWorker>(); Logger = logger ?? ServiceScope.GetRequiredService <IJobLogger <WorkerCoordinator> >(); MessageConsumer = ServiceScope.GetRequiredService <IMessageConsumer>(); MessageConsumer.Disconnected += MessageBrokerDisconnected; }
protected bool TryDeserializeJob(RawMessage rawMessage, IJobServiceScope scope, out JobInfo job) { job = null; var argsTag = rawMessage.TypeTag; if (string.IsNullOrEmpty(argsTag)) { return(false); } var serializer = scope.GetRequiredService <IJobSerializer>(); var typeProvider = scope.GetRequiredService <IJobTypeProvider>(); job = serializer.Deserialize(rawMessage.Body, argsTag, typeProvider); return(job != null); }
public void AckBatchMessageProcessed(IJobServiceScope scope, ulong deliveryTag) { }
public void AckMessageProcessed(IJobServiceScope scope, ulong deliveryTag) { _model.BasicAck(deliveryTag, false); }
public IBrokerTransaction BeginTransaction(IJobServiceScope scope) { return(null); }
public void AckBatchMessageProcessed(IJobServiceScope scope, ulong deliveryTag) { _messages.RemoveMessage(_queueName, deliveryTag); }
protected void OnMessageProcessed(IJobServiceScope scope, ulong deliveryTag) { _messageReceiver.AckMessageProcessed(scope, deliveryTag); }
protected void InvokePerform(IJobPublisher publisher, IMessageReceiver receiver, JobInfo jobInfo, ulong deliveryTag, IJobServiceScope serviceScope, CancellationToken cancellationToken) { IBrokerTransaction tx = null; try { var reflectionInfo = ReflectionUtilities.ReflectionCache.GetJobReflectionInfo(jobInfo.JobType, jobInfo.ArgsType); object job; switch (reflectionInfo.CtorType) { case ReflectionUtilities.ConstructorType.NoArgs: job = reflectionInfo.Ctor.Invoke(null); break; case ReflectionUtilities.ConstructorType.NeedsPublisher: job = reflectionInfo.Ctor.Invoke(new object[] { publisher }); break; default: var parametersInfo = reflectionInfo.Ctor.GetParameters(); var parameters = new object[parametersInfo.Length]; for (var i = 0; i < parametersInfo.Length; i++) { if (parametersInfo[i].IsOut) { throw new Exception("Out parameters are not supported."); } parameters[i] = serviceScope.GetRequiredService(parametersInfo[i].ParameterType); } job = reflectionInfo.Ctor.Invoke(parameters); break; } if (job == null) { throw new Exception($"Job type {jobInfo.JobType} is not registered in service scope and appropriate constructor does not exist!"); } if ((bool)reflectionInfo.UseTransactionGetter(job)) { tx = receiver.BeginTransaction(serviceScope); } object result; switch (reflectionInfo.PerfMethodType) { case ReflectionUtilities.PerformMethodType.NoArgs: result = reflectionInfo.PerformDelegate1(job); break; case ReflectionUtilities.PerformMethodType.NeedsArgs: result = reflectionInfo.PerformDelegate2(job, jobInfo.Args); break; case ReflectionUtilities.PerformMethodType.NeedsCancellationToken: result = reflectionInfo.PerformDelegate3(job, cancellationToken); break; case ReflectionUtilities.PerformMethodType.NeedsArgsAndCancellationToken: result = reflectionInfo.PerformDelegate4(job, jobInfo.Args, cancellationToken); break; default: throw new ArgumentOutOfRangeException(nameof(reflectionInfo.PerfMethodType)); } if (result != null && result is Task taskResult) { taskResult.Wait(cancellationToken); } receiver.AckBatchMessageProcessed(serviceScope, deliveryTag); tx?.Commit(); } catch (TargetInvocationException ex) { try { tx?.Rollback(); } catch (Exception rollbackEx) { _logger.LogError(rollbackEx, "Rollback failed"); } if (ex.InnerException == null) { throw; } ExceptionDispatchInfo.Capture(ex.InnerException).Throw(); } finally { tx.SafeDispose(_logger); } }
public void RunJob(IJobPublisher publisher, IMessageReceiver receiver, JobInfo jobInfo, ulong deliveryTag, IJobServiceScope serviceScope, CancellationToken cancellationToken) { try { using (var timeoutTokenSource = new CancellationTokenSource(jobInfo.TimeoutMs ?? DefaultJobTimeoutMs)) { var timeoutToken = timeoutTokenSource.Token; using (var combinedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutToken)) { try { InvokePerform(publisher, receiver, jobInfo, deliveryTag, serviceScope, combinedTokenSource.Token); } catch (OperationCanceledException) { if (timeoutToken.IsCancellationRequested) { throw new OperationCanceledException("A job timed out."); } throw; } } } } catch (Exception ex) { _logger.LogError(ex, $"Failed running job: {jobInfo.JobType} / {jobInfo.ArgsType} / {jobInfo.GroupKey}"); publisher.RescheduleJob(jobInfo, ex); receiver.AckBatchMessageProcessed(serviceScope, deliveryTag); } }