public IFetchedJob Dequeue(string[] queues, CancellationToken cancellationToken) { if (queues == null) { throw new ArgumentNullException(nameof(queues)); } if (queues.Length == 0) { throw new ArgumentException("Queue array must be non-empty.", nameof(queues)); } var pollInterval = _storage.Options.QueuePollInterval > TimeSpan.Zero ? _storage.Options.QueuePollInterval : TimeSpan.FromSeconds(15); var timeout = DateTimeOffset.UtcNow.AddSeconds((int)_storage.Options.SlidingInvisibilityTimeout.Value.Negate().TotalSeconds); RealmFetchedJob fetched = null; using var cancellationEvent = cancellationToken.GetCancellationEvent(); do { cancellationToken.ThrowIfCancellationRequested(); using (var realm = _storage.GetRealm()) using (var transaction = realm.BeginWrite()) { var jobs = new List <JobQueueDto>(); foreach (var queue in queues) { var jobsInQueue = realm.All <JobQueueDto>() .Where(_ => (_.FetchedAt == null || _.FetchedAt < timeout)) .Where(_ => _.Queue == queue); jobs.AddRange(jobsInQueue); } var job = jobs.OrderBy(_ => _.Created).FirstOrDefault(); if (job != null) { if (Logger.IsTraceEnabled()) { Logger.Debug($"Fetched job {job.JobId} with FetchedAt {job.FetchedAt} by Thread[{Thread.CurrentThread.ManagedThreadId}]"); } job.FetchedAt = DateTimeOffset.UtcNow; fetched = RealmFetchedJob.CreateInstance(_storage, job.Id, job.JobId, job.Queue, job.FetchedAt); transaction.Commit(); } if (fetched != null) { break; } } WaitHandle.WaitAny(new WaitHandle[] { cancellationEvent.WaitHandle, NewItemInQueueEvent }, pollInterval); cancellationToken.ThrowIfCancellationRequested(); } while (true); return(fetched); }
public void Init() { var storage = new RealmJobStorage(new RealmJobStorageOptions() { RealmConfiguration = ConnectionUtils.GetRealmConfiguration() }); _realm = storage.GetRealm(); _transaction = new RealmWriteOnlyTransaction(storage); _realm.Write(() => _realm.RemoveAll()); }
public void Init() { var storage = new RealmJobStorage(new RealmJobStorageOptions { RealmConfiguration = ConnectionUtils.GetRealmConfiguration() }); _realm = storage.GetRealm(); _realm.Write(() => _realm.RemoveAll()); _monitoringApi = new RealmMonitoringApi(storage); }
public void Init() { _storage = new RealmJobStorage(new RealmJobStorageOptions() { RealmConfiguration = ConnectionUtils.GetRealmConfiguration() }); _connection = new RealmStorageConnection(_storage); var realm = _storage.GetRealm(); realm.Write(() => realm.RemoveAll()); }
private void ExecuteKeepAliveQuery(object obj) { lock (_syncRoot) { if (!FetchedAt.HasValue) { return; } if (_queued || _removedFromQueue) { return; } try { var realm = _storage.GetRealm(); realm.Write(() => { var queuedJob = realm.Find <JobQueueDto>(_id); if (queuedJob == null) { return; } FetchedAt = DateTimeOffset.UtcNow; queuedJob.FetchedAt = FetchedAt; }); if (!FetchedAt.HasValue) { Logger.Warn($"Background job identifier '{JobId}' was fetched by another worker, will not execute keep alive."); } Logger.Trace($"Keep-alive query for message {_id} sent"); } catch (Exception ex) { Logger.DebugException($"Unable to execute keep-alive query for message {_id}", ex); } } }
public IList <Storage.Monitoring.ServerDto> Servers() { using (var realm = _storage.GetRealm()) { var servers = realm.All <Models.ServerDto>() .ToList() .Select(s => new Storage.Monitoring.ServerDto { Name = s.Id, Heartbeat = s.LastHeartbeat?.DateTime, Queues = s.Queues, StartedAt = s.StartedAt?.DateTime ?? default, WorkersCount = s.WorkerCount })
public void Execute(CancellationToken cancellationToken) { using (var realm = _storage.GetRealm()) using (var transaction = realm.BeginWrite()) { _logger.Debug("Removing outdated records..."); var expiredJobRecords = realm.All <JobDto>().Where(_ => _.ExpireAt < DateTimeOffset.UtcNow); _logger.Debug($"Removing {expiredJobRecords.Count()} outdated job records..."); foreach (var job in expiredJobRecords) { foreach (var param in job.Parameters) { realm.Remove(param); } foreach (var state in job.StateHistory) { foreach (var data in state.Data) { realm.Remove(data); } realm.Remove(state); } realm.Remove(job); } var expiredListRecords = realm.All <ListDto>().Where(_ => _.ExpireAt < DateTimeOffset.UtcNow); _logger.Debug($"Removing {expiredListRecords.Count()} outdated list records..."); realm.RemoveRange(expiredListRecords); var expiredSetRecords = realm.All <SetDto>().Where(_ => _.ExpireAt < DateTimeOffset.UtcNow); _logger.Debug($"Removing {expiredSetRecords.Count()} outdated set records..."); realm.RemoveRange(expiredSetRecords); var expiredHashRecords = realm.All <HashDto>().Where(_ => _.ExpireAt < DateTimeOffset.UtcNow); _logger.Debug($"Removing {expiredHashRecords.Count()} outdated hash records..."); realm.RemoveRange(expiredHashRecords); transaction.Commit(); } cancellationToken.Wait(_checkInterval); }
public IEnumerable <string> GetQueues() { lock (_cacheLock) { if (_queuesCache.Count != 0 && _cacheUpdated.Elapsed <= QueuesCacheTimeout) { return(_queuesCache.ToList()); } using (var realm = _storage.GetRealm()) { _queuesCache = realm.All <JobQueueDto>() .Select(q => q.Queue) .Distinct() .ToList(); } _cacheUpdated = Stopwatch.StartNew(); return(_queuesCache); } }
public void AnnounceServer_CreatesOrUpdatesARecord() { // ARRANGE var context1 = new ServerContext { Queues = new[] { "critical", "default" }, WorkerCount = 4 }; var context2 = new ServerContext { Queues = new[] { "default" }, WorkerCount = 1000 }; var realm = _storage.GetRealm(); // ACT - Create _connection.AnnounceServer("server", context1); // ASSERT var server = realm.Find <ServerDto>("server"); Assert.AreEqual("server", server.Id); Assert.AreEqual(context1.WorkerCount, server.WorkerCount); Assert.AreEqual(context1.Queues, server.Queues); Assert.NotNull(server.StartedAt); Assert.NotNull(server.LastHeartbeat); // ACT - Update _connection.AnnounceServer("server", context2); // ASSERT var sameServer = realm.Find <ServerDto>("server"); Assert.AreEqual("server", sameServer.Id); Assert.AreEqual(context2.WorkerCount, sameServer.WorkerCount); }