Example #1
0
        public MySqlFetchedJob(
            ElasticStorage.ElasticStorage storage,
            IDbConnection connection,
            FetchedJob fetchedJob,
            MySqlStorageOptions storageOptions)
        {
            if (storage == null)
            {
                throw new ArgumentNullException("storage");
            }
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }
            if (fetchedJob == null)
            {
                throw new ArgumentNullException("fetchedJob");
            }

            _storage        = storage;
            _connection     = connection;
            _storageOptions = storageOptions;
            _id             = fetchedJob.Id;
            JobId           = fetchedJob.JobId.ToString(CultureInfo.InvariantCulture);
            Queue           = fetchedJob.Queue;
        }
        public MySqlFetchedJob(
            MySqlStorage storage,
            FetchedJob fetchedJob)
        {
            if (storage == null)
            {
                throw new ArgumentNullException("storage");
            }
            if (fetchedJob == null)
            {
                throw new ArgumentNullException("fetchedJob");
            }

            _storage = storage;
            _id      = fetchedJob.Id;
            JobId    = fetchedJob.JobId.ToString(CultureInfo.InvariantCulture);
            Queue    = fetchedJob.Queue;
        }
Example #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;

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

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

                        int nUpdated = connection.Execute(
                            $"update `{_options.TablesPrefix}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.TablesPrefix}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));
        }
Example #4
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, "JobQueue", TimeSpan.FromSeconds(30)))
                    {
                        fetchedJob =
                            connection
                            .Query <FetchedJob>(
                                "select Id, JobId, Queue " +
                                "from JobQueue " +
                                "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
                        })
                            .SingleOrDefault();

                        if (fetchedJob != null)
                        {
                            connection
                            .Execute(
                                "update JobQueue set FetchedAt = @fetchedAt where Id = @id",
                                new { fetchedAt = DateTime.UtcNow, id = fetchedJob.Id });
                        }
                    }
                }
                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));
        }
Example #5
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();

                try
                {
                    connection = _storage.CreateAndOpenConnection();

                    //var joinedQueues = string.Join(",", queues.Select(q => "'" + q.Replace("'", "''") + "'"));

                    /*var resource = ("JobQueue:" + joinedQueues);
                     * if (resource.Length > 100)
                     *  resource = resource.Substring(0, 100);
                     *
                     * using (new MySqlDistributedLock(_storage, resource, TimeSpan.FromSeconds(70)))*/
                    {
                        string token = Guid.NewGuid().ToString();

                        int nUpdated;

                        while (!_semaphoreSlim.WaitOne(TimeSpan.FromSeconds(5)))
                        {
                            cancellationToken.ThrowIfCancellationRequested();
                        }
                        //_semaphoreSlim.Wait(cancellationToken);

                        try
                        {
                            nUpdated = MySqlStorageConnection.AttemptActionReturnObject(() => connection.Execute(
                                                                                            "update JobQueue set FetchedAt = DATE_ADD(UTC_TIMESTAMP(), INTERVAL @timeout SECOND), FetchToken = @fetchToken " +
                                                                                            "where (FetchedAt is null or FetchedAt < UTC_TIMESTAMP()) " +
                                                                                            "   and Queue in @queues " +
                                                                                            // "ORDER BY FIELD(Queue, " + joinedQueues + "), JobId " +
                                                                                            "ORDER BY Priority DESC, JobId " +
                                                                                            "LIMIT 1;",
                                                                                            new
                            {
                                queues     = queues,
                                timeout    = 45,  //_options.InvisibilityTimeout.Negate().TotalSeconds,
                                fetchToken = token
                            },
                                                                                            commandTimeout: 15), 3);
                        }
                        finally
                        {
                            _semaphoreSlim.Release();
                        }

                        if (nUpdated != 0)
                        {
                            fetchedJob =
                                MySqlStorageConnection.AttemptActionReturnObject(() => connection
                                                                                 .Query <FetchedJob>(
                                                                                     "select Id, JobId, Queue " +
                                                                                     "from JobQueue " +
                                                                                     "where FetchToken = @fetchToken;",
                                                                                     new
                            {
                                fetchToken = token
                            },
                                                                                     commandTimeout: 15)
                                                                                 .SingleOrDefault(), 3);

                            if (fetchedJob != null)
                            {
                                nUpdated = MySqlStorageConnection.AttemptActionReturnObject(() => connection.Execute(
                                                                                                "update JobQueue set FetchedAt = DATE_ADD(UTC_TIMESTAMP(), INTERVAL @timeout SECOND), FetchToken = @fetchToken " +
                                                                                                "where FetchToken = @fetchToken;",
                                                                                                new
                                {
                                    timeout    = _options.InvisibilityTimeout.TotalSeconds,
                                    fetchToken = token
                                }, commandTimeout: 15), 5);

                                if (nUpdated == 0)
                                {
                                    fetchedJob = null;
                                }
                            }
                        }
                    }
                }
                catch (MySqlException ex)
                {
                    Logger.ErrorException(ex.Message, ex);
                    throw;
                }
                finally
                {
                    _storage.ReleaseConnection(connection);
                }

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

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