shinq 0.8.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +6 -6
- data/README.md +2 -0
- data/lib/generators/shinq/worker/templates/create_table_migration.erb +1 -0
- data/lib/shinq.rb +10 -2
- data/lib/shinq/active_job/queue_adapters/shinq_adapter.rb +17 -0
- data/lib/shinq/cli.rb +12 -5
- data/lib/shinq/client.rb +33 -5
- data/lib/shinq/configuration.rb +14 -4
- data/lib/shinq/launcher.rb +31 -11
- data/shinq.gemspec +6 -5
- data/spec/db/structure.sql.erb +15 -0
- data/spec/helpers/my_worker.rb +4 -0
- data/spec/integration_spec.rb +82 -10
- data/spec/shinq/cli_spec.rb +38 -0
- data/spec/shinq/client_spec.rb +46 -0
- data/spec/shinq/configuration_spec.rb +15 -0
- data/spec/shinq_spec.rb +52 -34
- data/spec/spec_helper.rb +18 -1
- metadata +47 -16
- data/spec/db/structure.sql +0 -6
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 2 | 
            +
            SHA256:
         | 
| 3 | 
            +
              metadata.gz: c0cdad6cb88d95c3f54ef38ac64b7db0314850912693d9f87eae2d88c59c11be
         | 
| 4 | 
            +
              data.tar.gz: aed02806856d77fda982ae5d2039be2bf4558f32e7732a6d3681299fc25aac26
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 7f8e92ee4d147158524f66aa2d1bfb596abe66c0dddf49924d1e642a379f8ae30075127cee711dc535da8c97305025a983753802ead7b5f11eebccda399522f7
         | 
| 7 | 
            +
              data.tar.gz: 45ee3dcf8f20c696c078cb2db67475da5aa66160f1699b0db03108540a42cf641595f05ebd529e5110a9972e61710b7e9644e9881d74e2ffd799618a5cef3207
         | 
    
        data/.travis.yml
    CHANGED
    
    | @@ -3,14 +3,14 @@ sudo: false | |
| 3 3 | 
             
            cache: bundler
         | 
| 4 4 | 
             
            rvm:
         | 
| 5 5 | 
             
              - 2.1
         | 
| 6 | 
            -
              - 2.2 | 
| 7 | 
            -
              - 2. | 
| 8 | 
            -
              - 2. | 
| 9 | 
            -
              - 2. | 
| 10 | 
            -
              - 2. | 
| 11 | 
            -
              - 2.4.1
         | 
| 6 | 
            +
              - 2.2
         | 
| 7 | 
            +
              - 2.3
         | 
| 8 | 
            +
              - 2.4
         | 
| 9 | 
            +
              - 2.6
         | 
| 10 | 
            +
              - 2.7
         | 
| 12 11 | 
             
            gemfile:
         | 
| 13 12 | 
             
              - Gemfile
         | 
| 14 13 | 
             
            before_install:
         | 
| 14 | 
            +
              - gem update bundler
         | 
| 15 15 | 
             
              - mysql -e "create database IF NOT EXISTS shinq_test;" -uroot
         | 
| 16 16 | 
             
            script: bundle exec rspec
         | 
    
        data/README.md
    CHANGED
    
    | @@ -58,6 +58,7 @@ class CreateWorkerNames < ActiveRecord::Migration | |
| 58 58 | 
             
                create_table :worker_names, id: false, options: "ENGINE=QUEUE" do |t|
         | 
| 59 59 | 
             
                  t.string :job_id, null: false
         | 
| 60 60 | 
             
                  t.string :title
         | 
| 61 | 
            +
                  t.integer :scheduled_at, limit: 8, default: 0, null: false
         | 
| 61 62 | 
             
                  t.datetime :enqueued_at, null: false
         | 
| 62 63 | 
             
                end
         | 
| 63 64 | 
             
              end
         | 
| @@ -78,6 +79,7 @@ mysql> show create table worker_names\G | |
| 78 79 | 
             
            Create Table: CREATE TABLE `worker_names` (
         | 
| 79 80 | 
             
              `job_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
         | 
| 80 81 | 
             
              `title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
         | 
| 82 | 
            +
              `scheduled_at` bigint(20) NOT NULL DEFAULT '0',
         | 
| 81 83 | 
             
              `enqueued_at` datetime NOT NULL
         | 
| 82 84 | 
             
            ) ENGINE=QUEUE DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
         | 
| 83 85 | 
             
            ```
         | 
| @@ -5,6 +5,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration | |
| 5 5 | 
             
            <% attributes.each do |attribute| -%>
         | 
| 6 6 | 
             
                  t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
         | 
| 7 7 | 
             
            <% end -%>
         | 
| 8 | 
            +
                  t.integer :scheduled_at, limit: 8, default: 0, null: false
         | 
| 8 9 | 
             
                  t.datetime :enqueued_at, null: false
         | 
| 9 10 | 
             
                end
         | 
| 10 11 | 
             
              end
         | 
    
        data/lib/shinq.rb
    CHANGED
    
    | @@ -24,12 +24,20 @@ module Shinq | |
| 24 24 |  | 
| 25 25 | 
             
              def self.setup_db_connection(db_name)
         | 
| 26 26 | 
             
                raise Shinq::ConfigurationError unless self.configuration.db_defined?(db_name)
         | 
| 27 | 
            -
                @connections[db_name] = Mysql2::Client.new(self.configuration.db_config[db_name])
         | 
| 27 | 
            +
                @connections[db_name.to_sym] = Mysql2::Client.new(self.configuration.db_config[db_name])
         | 
| 28 28 | 
             
              end
         | 
| 29 29 |  | 
| 30 30 | 
             
              def self.connection(db_name: self.default_db)
         | 
| 31 31 | 
             
                @connections ||= {}
         | 
| 32 | 
            -
                @connections[db_name] ||= setup_db_connection(db_name)
         | 
| 32 | 
            +
                @connections[db_name.to_sym] ||= setup_db_connection(db_name)
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              def self.clear_all_connections!
         | 
| 36 | 
            +
                return unless @connections
         | 
| 37 | 
            +
                @connections.each do |_db_name, connection|
         | 
| 38 | 
            +
                  connection && connection.close
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
                @connections = {}
         | 
| 33 41 | 
             
              end
         | 
| 34 42 |  | 
| 35 43 | 
             
              def self.logger
         | 
| @@ -1,6 +1,14 @@ | |
| 1 1 | 
             
            module ActiveJob
         | 
| 2 2 | 
             
              module QueueAdapters
         | 
| 3 3 | 
             
                class ShinqAdapter
         | 
| 4 | 
            +
                  def enqueue(job)
         | 
| 5 | 
            +
                    self.class.enqueue job
         | 
| 6 | 
            +
                  end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  def enqueue_at(job, timestamp)
         | 
| 9 | 
            +
                    self.class.enqueue_at job, timestamp
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 4 12 | 
             
                  class << self
         | 
| 5 13 | 
             
                    def enqueue(job)
         | 
| 6 14 | 
             
                      Shinq::Client.enqueue(
         | 
| @@ -9,6 +17,15 @@ module ActiveJob | |
| 9 17 | 
             
                        args: job.arguments.first
         | 
| 10 18 | 
             
                      )
         | 
| 11 19 | 
             
                    end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    def enqueue_at(job, timestamp)
         | 
| 22 | 
            +
                      Shinq::Client.enqueue(
         | 
| 23 | 
            +
                        table_name: job.queue_name,
         | 
| 24 | 
            +
                        job_id: job.job_id,
         | 
| 25 | 
            +
                        args: job.arguments.first,
         | 
| 26 | 
            +
                        scheduled_at: timestamp,
         | 
| 27 | 
            +
                      )
         | 
| 28 | 
            +
                    end
         | 
| 12 29 | 
             
                  end
         | 
| 13 30 | 
             
                end
         | 
| 14 31 | 
             
              end
         | 
    
        data/lib/shinq/cli.rb
    CHANGED
    
    | @@ -15,6 +15,7 @@ module Shinq | |
| 15 15 | 
             
                def initialize(args=ARGV)
         | 
| 16 16 | 
             
                  setup_option(args)
         | 
| 17 17 | 
             
                  bootstrap
         | 
| 18 | 
            +
                  initialize_shinq
         | 
| 18 19 | 
             
                end
         | 
| 19 20 |  | 
| 20 21 | 
             
                def setup_option(args)
         | 
| @@ -31,10 +32,7 @@ module Shinq | |
| 31 32 | 
             
                    end
         | 
| 32 33 |  | 
| 33 34 | 
             
                    opt.on('-w', '--worker VALUE', 'Name of worker class') do |v|
         | 
| 34 | 
            -
                      worker_class = v.camelize.safe_constantize
         | 
| 35 | 
            -
                      raise OptionParseError, "worker class #{v.camelize} corresponding to #{v} does not exist" unless worker_class
         | 
| 36 35 | 
             
                      opts[:worker_name] = v
         | 
| 37 | 
            -
                      opts[:worker_class] = worker_class
         | 
| 38 36 | 
             
                    end
         | 
| 39 37 |  | 
| 40 38 | 
             
                    opt.on('-p', '--process VALUE', 'Number of workers') do |v|
         | 
| @@ -75,6 +73,10 @@ module Shinq | |
| 75 73 | 
             
                      opts[:abort_on_error] = v
         | 
| 76 74 | 
             
                    end
         | 
| 77 75 |  | 
| 76 | 
            +
                    opt.on('--sleep-sec-on-error N', Integer, 'Allow worker to sleep(sec) after exception') do |v|
         | 
| 77 | 
            +
                      opts[:sleep_sec_on_error] = v
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
             | 
| 78 80 | 
             
                    opt.on('-v', '--version', 'Print version') do |v|
         | 
| 79 81 | 
             
                      puts "Shinq #{Shinq::VERSION}"
         | 
| 80 82 | 
             
                      exit(0)
         | 
| @@ -104,6 +106,11 @@ module Shinq | |
| 104 106 | 
             
                  end
         | 
| 105 107 | 
             
                end
         | 
| 106 108 |  | 
| 109 | 
            +
                def initialize_shinq
         | 
| 110 | 
            +
                  Shinq::Client.fetch_column_names(table_name: Shinq.configuration.worker_name.pluralize)
         | 
| 111 | 
            +
                  Shinq.configuration.worker_class # check if worker_class is constantizable before running ServerEngine
         | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
             | 
| 107 114 | 
             
                def run
         | 
| 108 115 | 
             
                  klass = !options.statistics.nil? && options.statistics ? Shinq::Statistics : Shinq::Launcher
         | 
| 109 116 |  | 
| @@ -112,8 +119,8 @@ module Shinq | |
| 112 119 | 
             
                    worker_type: 'process',
         | 
| 113 120 | 
             
                    pid_file: 'shinq.pid',
         | 
| 114 121 | 
             
                    workers: options.process,
         | 
| 115 | 
            -
                    worker_graceful_kill_timeout: options.graceful_kill_timeout
         | 
| 116 | 
            -
                    logger: options.daemonize ? Shinq.logger : nil
         | 
| 122 | 
            +
                    worker_graceful_kill_timeout: options.graceful_kill_timeout,
         | 
| 123 | 
            +
                    logger: options.daemonize ? Shinq.logger : nil,
         | 
| 117 124 | 
             
                  })
         | 
| 118 125 |  | 
| 119 126 | 
             
                  se.run
         | 
    
        data/lib/shinq/client.rb
    CHANGED
    
    | @@ -8,13 +8,19 @@ module Shinq | |
| 8 8 | 
             
                  @builder ||= SQL::Maker.new(driver: 'mysql', auto_bind: true)
         | 
| 9 9 | 
             
                end
         | 
| 10 10 |  | 
| 11 | 
            -
                def self.enqueue(table_name: , job_id: , args:)
         | 
| 11 | 
            +
                def self.enqueue(table_name: , job_id: , args:, scheduled_at: nil)
         | 
| 12 | 
            +
                  if scheduled_at && !schedulable?(table_name: table_name)
         | 
| 13 | 
            +
                    raise ArgumentError, "table #{table_name} is not schedulable. You need column `scheduled_at`"
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 12 16 | 
             
                  case args
         | 
| 13 17 | 
             
                  when Hash
         | 
| 14 | 
            -
                     | 
| 18 | 
            +
                    attributes = args.merge(
         | 
| 15 19 | 
             
                      job_id: job_id,
         | 
| 16 | 
            -
                       | 
| 17 | 
            -
             | 
| 20 | 
            +
                      scheduled_at: scheduled_at ? scheduled_at.to_i : nil,
         | 
| 21 | 
            +
                      enqueued_at: Time.now,
         | 
| 22 | 
            +
                    ).compact
         | 
| 23 | 
            +
                    sql = builder.insert(table_name, attributes)
         | 
| 18 24 | 
             
                    Shinq.connection.query(sql)
         | 
| 19 25 | 
             
                  else
         | 
| 20 26 | 
             
                    raise ArgumentError, "`args` should be a Hash"
         | 
| @@ -22,7 +28,9 @@ module Shinq | |
| 22 28 | 
             
                end
         | 
| 23 29 |  | 
| 24 30 | 
             
                def self.dequeue(table_name:)
         | 
| 25 | 
            -
                   | 
| 31 | 
            +
                  condition = schedulable?(table_name: table_name) ? ":scheduled_at<=#{Time.now.to_i}" : ''
         | 
| 32 | 
            +
                  quoted = SQL::Maker::Quoting.quote("#{table_name}#{condition}")
         | 
| 33 | 
            +
             | 
| 26 34 | 
             
                  queue_timeout_quoted = SQL::Maker::Quoting.quote(Shinq.configuration.queue_timeout)
         | 
| 27 35 |  | 
| 28 36 | 
             
                  wait_query = "queue_wait(#{quoted}, #{queue_timeout_quoted})"
         | 
| @@ -52,6 +60,26 @@ module Shinq | |
| 52 60 | 
             
                  )
         | 
| 53 61 | 
             
                end
         | 
| 54 62 |  | 
| 63 | 
            +
                def self.schedulable?(table_name:)
         | 
| 64 | 
            +
                  self.column_names(table_name: table_name).include?('scheduled_at')
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                def self.column_names(table_name:)
         | 
| 68 | 
            +
                  @column_names_by_table_name ||= {}
         | 
| 69 | 
            +
                  @column_names_by_table_name[table_name.to_sym] ||= begin
         | 
| 70 | 
            +
                    quoted = SQL::Maker::Quoting.quote(table_name)
         | 
| 71 | 
            +
                    column = Shinq.connection.query(<<-EOS).map { |record| record['column_name'] }
         | 
| 72 | 
            +
            select column_name from information_schema.columns where table_schema = database() and table_name = #{quoted}
         | 
| 73 | 
            +
                    EOS
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                def self.fetch_column_names(table_name:)
         | 
| 78 | 
            +
                  @column_names_by_table_name ||= {}
         | 
| 79 | 
            +
                  @column_names_by_table_name.delete(table_name.to_sym)
         | 
| 80 | 
            +
                  column_names(table_name: table_name)
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 55 83 | 
             
                def self.done
         | 
| 56 84 | 
             
                  Shinq.connection.query('select queue_end()')
         | 
| 57 85 | 
             
                end
         | 
    
        data/lib/shinq/configuration.rb
    CHANGED
    
    | @@ -10,7 +10,7 @@ module Shinq | |
| 10 10 | 
             
              #   You may need to set it +false+ for jobs which take very long time to proceed.
         | 
| 11 11 | 
             
              #   You may also need to handle performing error manually then.
         | 
| 12 12 | 
             
              class Configuration
         | 
| 13 | 
            -
                attr_accessor :require, :worker_name, : | 
| 13 | 
            +
                attr_accessor :require, :worker_name, :db_config, :queue_db, :default_db, :process, :graceful_kill_timeout, :queue_timeout, :daemonize, :statistics, :lifecycle, :abort_on_error, :sleep_sec_on_error
         | 
| 14 14 |  | 
| 15 15 | 
             
                DEFAULT = {
         | 
| 16 16 | 
             
                  require: '.',
         | 
| @@ -18,15 +18,25 @@ module Shinq | |
| 18 18 | 
             
                  graceful_kill_timeout: 600,
         | 
| 19 19 | 
             
                  queue_timeout: 1,
         | 
| 20 20 | 
             
                  daemonize: false,
         | 
| 21 | 
            -
                  abort_on_error: true
         | 
| 21 | 
            +
                  abort_on_error: true,
         | 
| 22 | 
            +
                  sleep_sec_on_error: 1,
         | 
| 22 23 | 
             
                }
         | 
| 23 24 |  | 
| 24 25 | 
             
                def initialize(opts)
         | 
| 25 | 
            -
                  %i(require worker_name db_config queue_db default_db process queue_timeout daemonize statistics lifecycle abort_on_error).each do |k|
         | 
| 26 | 
            -
                     | 
| 26 | 
            +
                  %i(require worker_name db_config queue_db default_db process queue_timeout daemonize statistics lifecycle abort_on_error sleep_sec_on_error).each do |k|
         | 
| 27 | 
            +
                    value = opts.key?(k) ? opts[k] : DEFAULT[k]
         | 
| 28 | 
            +
                    send(:"#{k}=", value)
         | 
| 27 29 | 
             
                  end
         | 
| 28 30 | 
             
                end
         | 
| 29 31 |  | 
| 32 | 
            +
                def worker_class
         | 
| 33 | 
            +
                  worker_class = worker_name.camelize.safe_constantize
         | 
| 34 | 
            +
                  unless worker_class
         | 
| 35 | 
            +
                    raise ConfigurationError, "worker class #{worker_name.camelize} corresponding to #{worker_name} does not exist"
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
                  worker_class
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 30 40 | 
             
                def default_db_config
         | 
| 31 41 | 
             
                  raise ConfigurationError if !(default_db && db_defined?(default_db))
         | 
| 32 42 | 
             
                  db_config[default_db]
         | 
    
        data/lib/shinq/launcher.rb
    CHANGED
    
    | @@ -3,6 +3,10 @@ require 'active_support/inflector' | |
| 3 3 |  | 
| 4 4 | 
             
            module Shinq
         | 
| 5 5 | 
             
              module Launcher
         | 
| 6 | 
            +
                def initialize
         | 
| 7 | 
            +
                  Shinq.clear_all_connections!
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 6 10 | 
             
                # Wait configured queue and proceed each of them until stop.
         | 
| 7 11 | 
             
                # @see Shinq::Configuration#abort_on_error
         | 
| 8 12 | 
             
                def run
         | 
| @@ -12,21 +16,26 @@ module Shinq | |
| 12 16 | 
             
                  @loop_count = 0
         | 
| 13 17 |  | 
| 14 18 | 
             
                  until @stop
         | 
| 15 | 
            -
                     | 
| 16 | 
            -
             | 
| 19 | 
            +
                    begin
         | 
| 20 | 
            +
                      queue = Shinq::Client.dequeue(table_name: worker_name.pluralize)
         | 
| 21 | 
            +
                      next Shinq.logger.info("Queue is empty (#{Time.now})") unless queue
         | 
| 17 22 |  | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 23 | 
            +
                      if Shinq.configuration.abort_on_error
         | 
| 24 | 
            +
                        worker_class.new.perform(queue)
         | 
| 25 | 
            +
                        Shinq::Client.done
         | 
| 26 | 
            +
                      else
         | 
| 27 | 
            +
                        Shinq::Client.done
         | 
| 20 28 | 
             
                        worker_class.new.perform(queue)
         | 
| 21 | 
            -
                      rescue => e
         | 
| 22 | 
            -
                        Shinq::Client.abort
         | 
| 23 | 
            -
                        raise e
         | 
| 24 29 | 
             
                      end
         | 
| 25 30 |  | 
| 26 | 
            -
                      Shinq | 
| 27 | 
            -
                     | 
| 28 | 
            -
                      Shinq | 
| 29 | 
            -
                       | 
| 31 | 
            +
                      Shinq.clear_all_connections!
         | 
| 32 | 
            +
                    rescue => e
         | 
| 33 | 
            +
                      Shinq.logger.error(format_error_message(e))
         | 
| 34 | 
            +
                      sleep Shinq.configuration.sleep_sec_on_error
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                      Shinq::Client.abort if Shinq.configuration.abort_on_error && queue
         | 
| 37 | 
            +
                      Shinq.clear_all_connections!
         | 
| 38 | 
            +
                      break
         | 
| 30 39 | 
             
                    end
         | 
| 31 40 |  | 
| 32 41 | 
             
                    @loop_count += 1
         | 
| @@ -46,5 +55,16 @@ module Shinq | |
| 46 55 | 
             
                  return false unless Shinq.configuration.lifecycle
         | 
| 47 56 | 
             
                  return (Shinq.configuration.lifecycle < @loop_count)
         | 
| 48 57 | 
             
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                private
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                def format_error_message(error)
         | 
| 62 | 
            +
                  if defined?(::Rails) && ::Rails.backtrace_cleaner
         | 
| 63 | 
            +
                    backtrace = ::Rails.backtrace_cleaner.clean(error.backtrace || []).presence || error.backtrace
         | 
| 64 | 
            +
                  else
         | 
| 65 | 
            +
                    backtrace = error.backtrace
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                  "#{error.message} at #{backtrace.join('  <<<   ')}"
         | 
| 68 | 
            +
                end
         | 
| 49 69 | 
             
              end
         | 
| 50 70 | 
             
            end
         | 
    
        data/shinq.gemspec
    CHANGED
    
    | @@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) | |
| 4 4 |  | 
| 5 5 | 
             
            Gem::Specification.new do |spec|
         | 
| 6 6 | 
             
              spec.name          = "shinq"
         | 
| 7 | 
            -
              spec.version       = '0. | 
| 7 | 
            +
              spec.version       = '1.0.2'
         | 
| 8 8 | 
             
              spec.authors       = ["Ryoichi SEKIGUCHI"]
         | 
| 9 9 | 
             
              spec.email         = ["ryopeko@gmail.com"]
         | 
| 10 10 | 
             
              spec.summary       = %q{Worker and enqueuer for Q4M using the interface of ActiveJob.}
         | 
| @@ -16,17 +16,18 @@ Gem::Specification.new do |spec| | |
| 16 16 | 
             
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         | 
| 17 17 | 
             
              spec.require_paths = ["lib"]
         | 
| 18 18 |  | 
| 19 | 
            -
              spec.add_development_dependency "bundler" | 
| 19 | 
            +
              spec.add_development_dependency "bundler"
         | 
| 20 20 | 
             
              spec.add_development_dependency "rake", "~> 10.0"
         | 
| 21 21 | 
             
              spec.add_development_dependency "pry"
         | 
| 22 22 | 
             
              spec.add_development_dependency "tapp"
         | 
| 23 23 | 
             
              spec.add_development_dependency "rspec"
         | 
| 24 24 | 
             
              spec.add_development_dependency "rspec-mocks"
         | 
| 25 25 | 
             
              spec.add_development_dependency "simplecov"
         | 
| 26 | 
            +
              spec.add_development_dependency "timecop"
         | 
| 26 27 |  | 
| 27 | 
            -
              spec.add_dependency "mysql2", ">= 0.3.16", "< 0. | 
| 28 | 
            +
              spec.add_dependency "mysql2", ">= 0.3.16", "< 0.6"
         | 
| 28 29 | 
             
              spec.add_dependency "sql-maker", "~> 0.0.4"
         | 
| 29 | 
            -
              spec.add_dependency "activesupport", " | 
| 30 | 
            -
              spec.add_dependency "activejob", " | 
| 30 | 
            +
              spec.add_dependency "activesupport", ">= 4.2.0", "< 6"
         | 
| 31 | 
            +
              spec.add_dependency "activejob", ">= 4.2.0", "< 6"
         | 
| 31 32 | 
             
              spec.add_dependency 'serverengine', '~> 1.5.9'
         | 
| 32 33 | 
             
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            DROP TABLE IF EXISTS `queue_test`;
         | 
| 2 | 
            +
            CREATE TABLE `queue_test` (
         | 
| 3 | 
            +
              `job_id` varchar(255) NOT NULL,
         | 
| 4 | 
            +
              `title` varchar(255),
         | 
| 5 | 
            +
              `scheduled_at` bigint(20) NOT NULL DEFAULT '0',
         | 
| 6 | 
            +
              `enqueued_at` datetime NOT NULL
         | 
| 7 | 
            +
            ) ENGINE=<%= engine %>;
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            DROP TABLE IF EXISTS `queue_test_without_scheduled_at`;
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            CREATE TABLE `queue_test_without_scheduled_at` (
         | 
| 12 | 
            +
              `job_id` varchar(255) NOT NULL,
         | 
| 13 | 
            +
              `title` varchar(255),
         | 
| 14 | 
            +
              `enqueued_at` datetime NOT NULL
         | 
| 15 | 
            +
            ) ENGINE=<%= engine %>;
         | 
    
        data/spec/integration_spec.rb
    CHANGED
    
    | @@ -3,7 +3,6 @@ require 'shinq' | |
| 3 3 | 
             
            require 'shinq/client'
         | 
| 4 4 |  | 
| 5 5 | 
             
            describe "Integration", skip: ENV['TRAVIS'] do
         | 
| 6 | 
            -
              let(:queue_table) { 'queue_test' }
         | 
| 7 6 |  | 
| 8 7 | 
             
              before do
         | 
| 9 8 | 
             
                Shinq.configuration = {
         | 
| @@ -13,28 +12,97 @@ describe "Integration", skip: ENV['TRAVIS'] do | |
| 13 12 | 
             
              end
         | 
| 14 13 |  | 
| 15 14 | 
             
              after do
         | 
| 16 | 
            -
                Shinq. | 
| 15 | 
            +
                Shinq.clear_all_connections! # Return from owner mode
         | 
| 16 | 
            +
                tables = Shinq.connection.query('show tables').flat_map(&:values)
         | 
| 17 | 
            +
                tables.each do |table|
         | 
| 18 | 
            +
                  Shinq.connection.query("delete from #{table}")
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
                Shinq.clear_all_connections!
         | 
| 17 21 | 
             
              end
         | 
| 18 22 |  | 
| 19 23 | 
             
              describe "Shinq::Client.enqueue,dequeue" do
         | 
| 20 | 
            -
                 | 
| 21 | 
            -
                   | 
| 24 | 
            +
                before do
         | 
| 25 | 
            +
                  Timecop.freeze
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
                after do
         | 
| 28 | 
            +
                  Timecop.return
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                context 'with scheduled_at on table' do
         | 
| 32 | 
            +
                  let(:queue_table) { 'queue_test' }
         | 
| 33 | 
            +
                  let(:job_id) { SecureRandom.uuid }
         | 
| 22 34 |  | 
| 23 35 | 
             
                  before do
         | 
| 24 36 | 
             
                    Shinq::Client.enqueue(
         | 
| 25 37 | 
             
                      table_name: queue_table,
         | 
| 26 | 
            -
                      job_id:  | 
| 27 | 
            -
                      args:  | 
| 38 | 
            +
                      job_id: job_id,
         | 
| 39 | 
            +
                      args: { title: :foo },
         | 
| 40 | 
            +
                      scheduled_at: scheduled_at
         | 
| 28 41 | 
             
                    )
         | 
| 42 | 
            +
                  end
         | 
| 29 43 |  | 
| 30 | 
            -
             | 
| 31 | 
            -
                     | 
| 44 | 
            +
                  context 'when scheduled_at is not specified' do
         | 
| 45 | 
            +
                    let(:scheduled_at) { nil }
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    it 'can dequeue immediately' do
         | 
| 48 | 
            +
                      expect(Shinq::Client.dequeue(table_name: queue_table)[:job_id]).to eq job_id
         | 
| 49 | 
            +
                    end
         | 
| 32 50 | 
             
                  end
         | 
| 33 51 |  | 
| 34 | 
            -
                   | 
| 52 | 
            +
                  context 'when scheduled_at is specified' do
         | 
| 53 | 
            +
                    let(:scheduled_at) { 1.minute.since }
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                    it 'can not dequeue job immediately' do
         | 
| 56 | 
            +
                      expect(Shinq::Client.dequeue(table_name: queue_table)).to be nil
         | 
| 57 | 
            +
                    end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    context 'when specified time elapsed' do
         | 
| 60 | 
            +
                      before do
         | 
| 61 | 
            +
                        Timecop.travel(scheduled_at)
         | 
| 62 | 
            +
                      end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                      it 'can dequeue job' do
         | 
| 65 | 
            +
                        expect(Shinq::Client.dequeue(table_name: queue_table)[:job_id]).to eq job_id
         | 
| 66 | 
            +
                      end
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
                  end
         | 
| 35 69 | 
             
                end
         | 
| 36 70 |  | 
| 37 | 
            -
                context  | 
| 71 | 
            +
                context 'without scheduled_at on table' do
         | 
| 72 | 
            +
                  let(:job_id) { SecureRandom.uuid }
         | 
| 73 | 
            +
                  let(:unschedulable_queue_table) { 'queue_test_without_scheduled_at' }
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  context 'when scheduled_at is not specified' do
         | 
| 76 | 
            +
                    before do
         | 
| 77 | 
            +
                      Shinq::Client.enqueue(
         | 
| 78 | 
            +
                        table_name: unschedulable_queue_table,
         | 
| 79 | 
            +
                        job_id: job_id,
         | 
| 80 | 
            +
                        args: { title: :foo },
         | 
| 81 | 
            +
                      )
         | 
| 82 | 
            +
                    end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                    it 'can dequeue job' do
         | 
| 85 | 
            +
                      expect(Shinq::Client.dequeue(table_name: unschedulable_queue_table)[:job_id]).to eq job_id
         | 
| 86 | 
            +
                    end
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                  context 'when scheduled_at is specified' do
         | 
| 90 | 
            +
                    it 'cannot enqueue job' do
         | 
| 91 | 
            +
                      expect {
         | 
| 92 | 
            +
                        Shinq::Client.enqueue(
         | 
| 93 | 
            +
                          table_name: unschedulable_queue_table,
         | 
| 94 | 
            +
                          job_id: job_id,
         | 
| 95 | 
            +
                          args: { title: :foo },
         | 
| 96 | 
            +
                          scheduled_at: 1.minute.since,
         | 
| 97 | 
            +
                        )
         | 
| 98 | 
            +
                      }.to raise_error ArgumentError
         | 
| 99 | 
            +
                    end
         | 
| 100 | 
            +
                  end
         | 
| 101 | 
            +
                end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
             | 
| 104 | 
            +
                context "with invalid args" do
         | 
| 105 | 
            +
                  let(:queue_table) { 'queue_test' }
         | 
| 38 106 | 
             
                  it {
         | 
| 39 107 | 
             
                    expect {
         | 
| 40 108 | 
             
                      Shinq::Client.enqueue(
         | 
| @@ -48,6 +116,8 @@ describe "Integration", skip: ENV['TRAVIS'] do | |
| 48 116 | 
             
              end
         | 
| 49 117 |  | 
| 50 118 | 
             
              describe "Shinq::Client.abort" do
         | 
| 119 | 
            +
                let(:queue_table) { 'queue_test' }
         | 
| 120 | 
            +
             | 
| 51 121 | 
             
                context "When client has a queue" do
         | 
| 52 122 | 
             
                  before do
         | 
| 53 123 | 
             
                    Shinq::Client.enqueue(
         | 
| @@ -77,6 +147,8 @@ describe "Integration", skip: ENV['TRAVIS'] do | |
| 77 147 | 
             
              end
         | 
| 78 148 |  | 
| 79 149 | 
             
              describe "Shinq::Client.queue_stats" do
         | 
| 150 | 
            +
                let(:queue_table) { 'queue_test' }
         | 
| 151 | 
            +
             | 
| 80 152 | 
             
                subject(:stats) {
         | 
| 81 153 | 
             
                  Shinq::Client.queue_stats(table_name: queue_table)
         | 
| 82 154 | 
             
                }
         | 
| @@ -0,0 +1,38 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'shinq/cli'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe Shinq::CLI do
         | 
| 5 | 
            +
              after do
         | 
| 6 | 
            +
                Shinq.clear_all_connections!
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              describe '.new' do
         | 
| 10 | 
            +
                context 'when there are require statement' do
         | 
| 11 | 
            +
                  it 'requires and run the code' do
         | 
| 12 | 
            +
                    # NOTE: As CLI alters global process irreversibly, we only check the result
         | 
| 13 | 
            +
                    Shinq::CLI.new(%W[
         | 
| 14 | 
            +
                      --require my_worker
         | 
| 15 | 
            +
                      --db-config #{File.expand_path('../config/database.yml', __dir__)}
         | 
| 16 | 
            +
                      --worker my_worker
         | 
| 17 | 
            +
                    ])
         | 
| 18 | 
            +
                    expect(defined? MyWorker).to eq 'constant'
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              describe '#run' do
         | 
| 24 | 
            +
                before do
         | 
| 25 | 
            +
                  allow_any_instance_of(ServerEngine::Daemon).to receive(:run).and_return(nil)
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                it 'launches Shinq::Launcher backended by ServerEngine' do
         | 
| 29 | 
            +
                  expect {
         | 
| 30 | 
            +
                    Shinq::CLI.new(%W[
         | 
| 31 | 
            +
                      --require my_worker
         | 
| 32 | 
            +
                      --db-config #{File.expand_path('../config/database.yml', __dir__)}
         | 
| 33 | 
            +
                      --worker my_worker
         | 
| 34 | 
            +
                    ]).run
         | 
| 35 | 
            +
                  }.not_to raise_error
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
            end
         | 
| @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'shinq'
         | 
| 3 | 
            +
            require 'shinq/client'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            describe Shinq::Client do
         | 
| 6 | 
            +
              subject(:shinq_client) do
         | 
| 7 | 
            +
                Shinq::Client.dup.tap do |client|
         | 
| 8 | 
            +
                  client.instance_variables.each do |variable|
         | 
| 9 | 
            +
                    client.remove_instance_variable(variable)
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              before do
         | 
| 15 | 
            +
                Shinq.configuration = {
         | 
| 16 | 
            +
                  default_db: :test,
         | 
| 17 | 
            +
                  db_config: load_database_config
         | 
| 18 | 
            +
                }
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              after do
         | 
| 22 | 
            +
                Shinq.clear_all_connections!
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              describe '.schedulable?' do
         | 
| 26 | 
            +
                context 'when target table have scheduled_at' do
         | 
| 27 | 
            +
                  it { expect(shinq_client.schedulable?(table_name: :queue_test)).to be true }
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                context 'when target table does NOT have scheduled_at' do
         | 
| 31 | 
            +
                  it { expect(shinq_client.schedulable?(table_name: :queue_test_without_scheduled_at)).to be false }
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              describe '.column_names' do
         | 
| 36 | 
            +
                it 'fetches column_names' do
         | 
| 37 | 
            +
                  expect(shinq_client.column_names(table_name: :queue_test)).to eq(['job_id', 'title', 'scheduled_at', 'enqueued_at'])
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              describe 'fetch_column_names' do
         | 
| 42 | 
            +
                it 'fetches column_names' do
         | 
| 43 | 
            +
                  expect(shinq_client.fetch_column_names(table_name: :queue_test)).to eq(['job_id', 'title', 'scheduled_at', 'enqueued_at'])
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
            end
         | 
| @@ -33,6 +33,21 @@ describe Shinq::Configuration do | |
| 33 33 | 
             
                end
         | 
| 34 34 | 
             
              end
         | 
| 35 35 |  | 
| 36 | 
            +
              describe '#worker_class' do
         | 
| 37 | 
            +
                context 'when worker_name is valid' do
         | 
| 38 | 
            +
                  let(:configuration) { Shinq::Configuration.new(worker_name: 'shinq') }
         | 
| 39 | 
            +
                  it 'constantizes worker_name to corresponding constant' do
         | 
| 40 | 
            +
                    expect(configuration.worker_class).to eq Shinq
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                context 'when worker_name is invalid' do
         | 
| 45 | 
            +
                  let(:configuration) { Shinq::Configuration.new(worker_name: 'invalid_shinq') }
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  it {expect { configuration.worker_class }.to raise_error(Shinq::ConfigurationError)}
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
             | 
| 36 51 | 
             
              describe "#default_db_config" do
         | 
| 37 52 | 
             
                context "when default_db is present" do
         | 
| 38 53 | 
             
                  let(:configuration) { Shinq::Configuration.new({}) }
         | 
    
        data/spec/shinq_spec.rb
    CHANGED
    
    | @@ -3,29 +3,32 @@ require 'shinq' | |
| 3 3 | 
             
            require 'shinq/configuration'
         | 
| 4 4 | 
             
            require 'logger'
         | 
| 5 5 |  | 
| 6 | 
            -
            def shinq_class
         | 
| 7 | 
            -
              Shinq.dup
         | 
| 8 | 
            -
            end
         | 
| 9 | 
            -
             | 
| 10 6 | 
             
            describe Shinq do
         | 
| 11 | 
            -
               | 
| 7 | 
            +
              # remove instance variable deliberately or indeliberately defined by other specs
         | 
| 8 | 
            +
              subject(:shinq) do
         | 
| 9 | 
            +
                Shinq.dup.tap do |shinq|
         | 
| 10 | 
            +
                  shinq.instance_variables.each do |variable|
         | 
| 11 | 
            +
                    shinq.remove_instance_variable(variable)
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              after do
         | 
| 17 | 
            +
                shinq.clear_all_connections!
         | 
| 18 | 
            +
              end
         | 
| 12 19 |  | 
| 13 20 | 
             
              it { is_expected.to respond_to(:configuration) }
         | 
| 14 21 | 
             
              it { is_expected.to respond_to(:configuration=) }
         | 
| 15 22 |  | 
| 16 23 | 
             
              describe ".configuration" do
         | 
| 17 24 | 
             
                context "when configuration is not present" do
         | 
| 18 | 
            -
                  let(:shinq) { shinq_class }
         | 
| 19 | 
            -
             | 
| 20 25 | 
             
                  it { expect(shinq.configuration).to be_a_kind_of(Shinq::Configuration) }
         | 
| 21 26 | 
             
                end
         | 
| 22 27 |  | 
| 23 28 | 
             
                context "when configuration is present" do
         | 
| 24 | 
            -
                   | 
| 25 | 
            -
                     | 
| 26 | 
            -
             | 
| 27 | 
            -
                    }
         | 
| 28 | 
            -
                  }
         | 
| 29 | 
            +
                  before do
         | 
| 30 | 
            +
                    shinq.configuration = Hash.new
         | 
| 31 | 
            +
                  end
         | 
| 29 32 |  | 
| 30 33 | 
             
                  it { expect(shinq.configuration).to be_a_kind_of(Shinq::Configuration) }
         | 
| 31 34 | 
             
                end
         | 
| @@ -33,7 +36,6 @@ describe Shinq do | |
| 33 36 |  | 
| 34 37 | 
             
              describe ".configuration=" do
         | 
| 35 38 | 
             
                context "when specify args is Hash" do
         | 
| 36 | 
            -
                  let(:shinq) { shinq_class }
         | 
| 37 39 | 
             
                  let(:args) { Hash.new }
         | 
| 38 40 |  | 
| 39 41 | 
             
                  it 'is expect to return specified args' do
         | 
| @@ -42,7 +44,6 @@ describe Shinq do | |
| 42 44 | 
             
                end
         | 
| 43 45 |  | 
| 44 46 | 
             
                context "when specify args is Shinq::Configuration" do
         | 
| 45 | 
            -
                  let(:shinq) { shinq_class }
         | 
| 46 47 | 
             
                  let(:args) { Shinq::Configuration.new({}) }
         | 
| 47 48 |  | 
| 48 49 | 
             
                  it 'is expect to return specified args' do
         | 
| @@ -52,39 +53,56 @@ describe Shinq do | |
| 52 53 | 
             
              end
         | 
| 53 54 |  | 
| 54 55 | 
             
              describe ".connection" do
         | 
| 56 | 
            +
                context "when db_config is not present" do
         | 
| 57 | 
            +
                  it { expect{ shinq.connection(db_name: :unknown) }.to raise_error(Shinq::ConfigurationError) }
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 55 60 | 
             
                context "when db_config is present" do
         | 
| 56 | 
            -
                   | 
| 61 | 
            +
                  before do
         | 
| 62 | 
            +
                    shinq.configuration = { db_config: load_database_config, default_db: :test }
         | 
| 63 | 
            +
                  end
         | 
| 57 64 |  | 
| 58 | 
            -
                  it  | 
| 65 | 
            +
                  it do
         | 
| 66 | 
            +
                    shinq.connection(db_name: :test)
         | 
| 67 | 
            +
                    expect(shinq.connection(db_name: :test)).to be_a_kind_of(Mysql2::Client)
         | 
| 68 | 
            +
                  end
         | 
| 59 69 | 
             
                end
         | 
| 70 | 
            +
              end
         | 
| 60 71 |  | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
                   | 
| 72 | 
            +
              describe '.clear_all_connections!' do
         | 
| 73 | 
            +
                before do
         | 
| 74 | 
            +
                  shinq.configuration = { db_config: load_database_config, default_db: :test }
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                context 'when there are no connections' do
         | 
| 78 | 
            +
                  it { expect { shinq.clear_all_connections! }.not_to raise_error }
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                context 'when there is a connection' do
         | 
| 82 | 
            +
                  let!(:connection) { shinq.connection(db_name: :test) }
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  it 'closes connection' do
         | 
| 85 | 
            +
                    shinq.clear_all_connections!
         | 
| 86 | 
            +
                    expect(connection.ping).to be false
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                  it 'clears connection cache' do
         | 
| 90 | 
            +
                    shinq.clear_all_connections!
         | 
| 91 | 
            +
                    expect(shinq.connection(db_name: :test)).not_to eq connection
         | 
| 92 | 
            +
                  end
         | 
| 72 93 | 
             
                end
         | 
| 73 94 | 
             
              end
         | 
| 74 95 |  | 
| 75 96 | 
             
              describe ".logger" do
         | 
| 76 | 
            -
                context "when logger is present" do
         | 
| 77 | 
            -
                  let(:shinq) { shinq_class }
         | 
| 97 | 
            +
                context "when logger is not present" do
         | 
| 78 98 | 
             
                  it { expect(shinq.logger).to be nil }
         | 
| 79 99 | 
             
                end
         | 
| 80 100 |  | 
| 81 101 | 
             
                context "when logger is present" do
         | 
| 82 102 | 
             
                  let(:logger) { Logger.new(STDOUT) }
         | 
| 83 | 
            -
                   | 
| 84 | 
            -
                     | 
| 85 | 
            -
             | 
| 86 | 
            -
                    }
         | 
| 87 | 
            -
                  }
         | 
| 103 | 
            +
                  before do
         | 
| 104 | 
            +
                    shinq.logger = logger
         | 
| 105 | 
            +
                  end
         | 
| 88 106 |  | 
| 89 107 | 
             
                  it { expect(shinq.logger).to be logger }
         | 
| 90 108 | 
             
                end
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -1,7 +1,13 @@ | |
| 1 | 
            +
            ENV['RAILS_ENV'] ||= 'test'
         | 
| 2 | 
            +
            $LOAD_PATH << File.expand_path('../helpers', __FILE__)
         | 
| 3 | 
            +
             | 
| 1 4 | 
             
            require 'rspec/mocks/standalone'
         | 
| 2 5 | 
             
            require 'simplecov'
         | 
| 6 | 
            +
            require 'erb'
         | 
| 3 7 | 
             
            require 'yaml'
         | 
| 4 8 | 
             
            require 'active_support/core_ext/hash'
         | 
| 9 | 
            +
            require 'mysql2'
         | 
| 10 | 
            +
            require 'timecop'
         | 
| 5 11 |  | 
| 6 12 | 
             
            def load_database_config
         | 
| 7 13 | 
             
              db_config = YAML.load_file(File.expand_path('./config/database.yml', __dir__)).symbolize_keys
         | 
| @@ -25,8 +31,19 @@ RSpec.configure do |config| | |
| 25 31 | 
             
              end
         | 
| 26 32 |  | 
| 27 33 | 
             
              config.before(:suite) do
         | 
| 34 | 
            +
                # MySQL on Travis does not have Q4M plugins.
         | 
| 35 | 
            +
                # We use QUEUE engine and run Q4M specific spec (integration_spec) only when ENV['TRAVIS'] is nil.
         | 
| 36 | 
            +
                engine = ENV['TRAVIS'] ? 'InnoDB' : 'QUEUE' # Travis MySQL does not have Q4M plugins.
         | 
| 37 | 
            +
                sql = ERB.new(File.read(File.expand_path('./db/structure.sql.erb', __dir__))).result(binding)
         | 
| 38 | 
            +
             | 
| 28 39 | 
             
                connection = Mysql2::Client.new(load_database_config[:test].merge(flags: Mysql2::Client::MULTI_STATEMENTS))
         | 
| 29 | 
            -
                connection.query( | 
| 40 | 
            +
                result = connection.query(sql)
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                while connection.next_result
         | 
| 43 | 
            +
                  connection.store_result
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                connection.close
         | 
| 30 47 | 
             
              end
         | 
| 31 48 |  | 
| 32 49 | 
             
              config.order = :random
         | 
    
        metadata
    CHANGED
    
    | @@ -1,29 +1,29 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: shinq
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 1.0.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Ryoichi SEKIGUCHI
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2020-10-09 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| 15 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 16 | 
             
                requirements:
         | 
| 17 | 
            -
                - - " | 
| 17 | 
            +
                - - ">="
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: ' | 
| 19 | 
            +
                    version: '0'
         | 
| 20 20 | 
             
              type: :development
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 | 
            -
                - - " | 
| 24 | 
            +
                - - ">="
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: ' | 
| 26 | 
            +
                    version: '0'
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: rake
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -108,6 +108,20 @@ dependencies: | |
| 108 108 | 
             
                - - ">="
         | 
| 109 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 110 | 
             
                    version: '0'
         | 
| 111 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 112 | 
            +
              name: timecop
         | 
| 113 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 114 | 
            +
                requirements:
         | 
| 115 | 
            +
                - - ">="
         | 
| 116 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 117 | 
            +
                    version: '0'
         | 
| 118 | 
            +
              type: :development
         | 
| 119 | 
            +
              prerelease: false
         | 
| 120 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 121 | 
            +
                requirements:
         | 
| 122 | 
            +
                - - ">="
         | 
| 123 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 124 | 
            +
                    version: '0'
         | 
| 111 125 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 112 126 | 
             
              name: mysql2
         | 
| 113 127 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -117,7 +131,7 @@ dependencies: | |
| 117 131 | 
             
                    version: 0.3.16
         | 
| 118 132 | 
             
                - - "<"
         | 
| 119 133 | 
             
                  - !ruby/object:Gem::Version
         | 
| 120 | 
            -
                    version: '0. | 
| 134 | 
            +
                    version: '0.6'
         | 
| 121 135 | 
             
              type: :runtime
         | 
| 122 136 | 
             
              prerelease: false
         | 
| 123 137 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| @@ -127,7 +141,7 @@ dependencies: | |
| 127 141 | 
             
                    version: 0.3.16
         | 
| 128 142 | 
             
                - - "<"
         | 
| 129 143 | 
             
                  - !ruby/object:Gem::Version
         | 
| 130 | 
            -
                    version: '0. | 
| 144 | 
            +
                    version: '0.6'
         | 
| 131 145 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 132 146 | 
             
              name: sql-maker
         | 
| 133 147 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -146,30 +160,42 @@ dependencies: | |
| 146 160 | 
             
              name: activesupport
         | 
| 147 161 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 148 162 | 
             
                requirements:
         | 
| 149 | 
            -
                - - " | 
| 163 | 
            +
                - - ">="
         | 
| 150 164 | 
             
                  - !ruby/object:Gem::Version
         | 
| 151 165 | 
             
                    version: 4.2.0
         | 
| 166 | 
            +
                - - "<"
         | 
| 167 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 168 | 
            +
                    version: '6'
         | 
| 152 169 | 
             
              type: :runtime
         | 
| 153 170 | 
             
              prerelease: false
         | 
| 154 171 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 155 172 | 
             
                requirements:
         | 
| 156 | 
            -
                - - " | 
| 173 | 
            +
                - - ">="
         | 
| 157 174 | 
             
                  - !ruby/object:Gem::Version
         | 
| 158 175 | 
             
                    version: 4.2.0
         | 
| 176 | 
            +
                - - "<"
         | 
| 177 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 178 | 
            +
                    version: '6'
         | 
| 159 179 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 160 180 | 
             
              name: activejob
         | 
| 161 181 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 162 182 | 
             
                requirements:
         | 
| 163 | 
            -
                - - " | 
| 183 | 
            +
                - - ">="
         | 
| 164 184 | 
             
                  - !ruby/object:Gem::Version
         | 
| 165 185 | 
             
                    version: 4.2.0
         | 
| 186 | 
            +
                - - "<"
         | 
| 187 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 188 | 
            +
                    version: '6'
         | 
| 166 189 | 
             
              type: :runtime
         | 
| 167 190 | 
             
              prerelease: false
         | 
| 168 191 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 169 192 | 
             
                requirements:
         | 
| 170 | 
            -
                - - " | 
| 193 | 
            +
                - - ">="
         | 
| 171 194 | 
             
                  - !ruby/object:Gem::Version
         | 
| 172 195 | 
             
                    version: 4.2.0
         | 
| 196 | 
            +
                - - "<"
         | 
| 197 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 198 | 
            +
                    version: '6'
         | 
| 173 199 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 174 200 | 
             
              name: serverengine
         | 
| 175 201 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -214,8 +240,11 @@ files: | |
| 214 240 | 
             
            - lib/shinq/statistics.rb
         | 
| 215 241 | 
             
            - shinq.gemspec
         | 
| 216 242 | 
             
            - spec/config/database.yml
         | 
| 217 | 
            -
            - spec/db/structure.sql
         | 
| 243 | 
            +
            - spec/db/structure.sql.erb
         | 
| 244 | 
            +
            - spec/helpers/my_worker.rb
         | 
| 218 245 | 
             
            - spec/integration_spec.rb
         | 
| 246 | 
            +
            - spec/shinq/cli_spec.rb
         | 
| 247 | 
            +
            - spec/shinq/client_spec.rb
         | 
| 219 248 | 
             
            - spec/shinq/configuration_spec.rb
         | 
| 220 249 | 
             
            - spec/shinq_spec.rb
         | 
| 221 250 | 
             
            - spec/spec_helper.rb
         | 
| @@ -238,15 +267,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 238 267 | 
             
                - !ruby/object:Gem::Version
         | 
| 239 268 | 
             
                  version: '0'
         | 
| 240 269 | 
             
            requirements: []
         | 
| 241 | 
            -
             | 
| 242 | 
            -
            rubygems_version: 2.6.8
         | 
| 270 | 
            +
            rubygems_version: 3.0.3
         | 
| 243 271 | 
             
            signing_key: 
         | 
| 244 272 | 
             
            specification_version: 4
         | 
| 245 273 | 
             
            summary: Worker and enqueuer for Q4M using the interface of ActiveJob.
         | 
| 246 274 | 
             
            test_files:
         | 
| 247 275 | 
             
            - spec/config/database.yml
         | 
| 248 | 
            -
            - spec/db/structure.sql
         | 
| 276 | 
            +
            - spec/db/structure.sql.erb
         | 
| 277 | 
            +
            - spec/helpers/my_worker.rb
         | 
| 249 278 | 
             
            - spec/integration_spec.rb
         | 
| 279 | 
            +
            - spec/shinq/cli_spec.rb
         | 
| 280 | 
            +
            - spec/shinq/client_spec.rb
         | 
| 250 281 | 
             
            - spec/shinq/configuration_spec.rb
         | 
| 251 282 | 
             
            - spec/shinq_spec.rb
         | 
| 252 283 | 
             
            - spec/spec_helper.rb
         |