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);
        }
Example #2
0
        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);
                }
            }
        }
Example #6
0
 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
         })
Example #7
0
        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);
        }