예제 #1
0
        public MySqlFetchedJob(
            MySqlStorage storage,
            IDbConnection connection,
            FetchedJob fetchedJob)
        {
            if (fetchedJob == null)
            {
                throw new ArgumentNullException("fetchedJob");
            }

            _storage    = storage ?? throw new ArgumentNullException("storage");
            _connection = connection ?? throw new ArgumentNullException("connection");
            _id         = fetchedJob.Id;
            JobId       = fetchedJob.JobId.ToString(CultureInfo.InvariantCulture);
            Queue       = fetchedJob.Queue;
        }
예제 #2
0
        public IFetchedJob Dequeue(string[] queues, CancellationToken cancellationToken)
        {
            if (queues == null)
            {
                throw new ArgumentNullException("queues");
            }
            if (queues.Length == 0)
            {
                throw new ArgumentException("Queue array must be non-empty.", "queues");
            }

            FetchedJob      fetchedJob = null;
            MySqlConnection connection = null;

            do
            {
                cancellationToken.ThrowIfCancellationRequested();
                connection = _storage.CreateAndOpenConnection();

                try
                {
                    using (new MySqlDistributedLock(_storage, _options, "JobQueue", TimeSpan.FromSeconds(30)))
                    {
                        string token = Guid.NewGuid().ToString();

                        int nUpdated = connection.Execute(
                            $"update {_options.TablePrefix}_JobQueue set FetchedAt = UTC_TIMESTAMP(), FetchToken = @fetchToken " +
                            "where (FetchedAt is null or FetchedAt < DATE_ADD(UTC_TIMESTAMP(), INTERVAL @timeout SECOND)) " +
                            "   and Queue in @queues " +
                            "LIMIT 1;",
                            new
                        {
                            queues     = queues,
                            timeout    = _options.InvisibilityTimeout.Negate().TotalSeconds,
                            fetchToken = token
                        });

                        if (nUpdated != 0)
                        {
                            fetchedJob =
                                connection
                                .Query <FetchedJob>(
                                    $"select Id, JobId, Queue  from {_options.TablePrefix}_JobQueue where FetchToken = @fetchToken;",
                                    new
                            {
                                fetchToken = token
                            })
                                .SingleOrDefault();
                        }
                    }
                }
                catch (MySqlException ex)
                {
                    Logger.ErrorException(ex.Message, ex);
                    _storage.ReleaseConnection(connection);
                    throw;
                }

                if (fetchedJob == null)
                {
                    _storage.ReleaseConnection(connection);

                    cancellationToken.WaitHandle.WaitOne(_options.QueuePollInterval);
                    cancellationToken.ThrowIfCancellationRequested();
                }
            } while (fetchedJob == null);

            return(new MySqlFetchedJob(_storage, connection, fetchedJob, _options));
        }
예제 #3
0
        public IFetchedJob Dequeue(string[] queues, CancellationToken cancellationToken)
        {
            if (queues == null)
            {
                throw new ArgumentNullException("queues");
            }
            if (queues.Length == 0)
            {
                throw new ArgumentException("Queue array must be non-empty.", "queues");
            }

            FetchedJob      fetchedJob = null;
            MySqlConnection connection = null;

            int    timeOut = 0;
            string token   = string.Empty;
            bool   updated = false;

            do
            {
                cancellationToken.ThrowIfCancellationRequested();
                connection = _storage.CreateAndOpenConnection();

                updated = false;
                try
                {
                    using (new MySqlDistributedLock(_storage, "JobQueue", TimeSpan.FromSeconds(30)))
                    {
                        token = Guid.NewGuid().ToString();

                        timeOut = _options.InvisibilityTimeout.Negate().Seconds;
                        int nUpdated = connection.Execute(
                            "update JobQueue set FetchedAt = UTC_TIMESTAMP(), FetchToken = @fetchToken " +
                            "where (FetchedAt is null or FetchedAt < DATE_ADD(UTC_TIMESTAMP(), INTERVAL @timeout SECOND)) " +
                            "   and Queue in @queues " +
                            "LIMIT 1;",
                            new
                        {
                            queues     = queues,
                            timeout    = timeOut,
                            fetchToken = token
                        });

                        updated = true;
                        if (nUpdated != 0)
                        {
                            fetchedJob =
                                connection
                                .Query <FetchedJob>(
                                    "select Id, JobId, Queue " +
                                    "from JobQueue " +
                                    "where FetchToken = @fetchToken;",
                                    new
                            {
                                fetchToken = token
                            })
                                .SingleOrDefault();
                        }
                    }
                }
                catch (MySqlException ex)
                {
                    Logger.ErrorException(ex.Message, ex);
                    _storage.ReleaseConnection(connection);

                    throw new Exception($"Error dequeue in {(updated ? "select" : "update")}" +
                                        $"Parameters: queues = {queues}, timeout = {timeOut}, fetchToken = {token} ", ex);
                }

                if (fetchedJob == null)
                {
                    _storage.ReleaseConnection(connection);

                    cancellationToken.WaitHandle.WaitOne(_options.QueuePollInterval);
                    cancellationToken.ThrowIfCancellationRequested();
                }
            } while (fetchedJob == null);

            return(new MySqlFetchedJob(_storage, connection, fetchedJob));
        }