crono_trigger 0.6.1 → 0.6.4
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 +4 -4
 - data/.github/workflows/rspec.yml +27 -0
 - data/README.md +8 -1
 - data/lib/crono_trigger/cli.rb +2 -2
 - data/lib/crono_trigger/polling_thread.rb +16 -30
 - data/lib/crono_trigger/schedulable.rb +4 -3
 - data/lib/crono_trigger/version.rb +1 -1
 - data/lib/crono_trigger/worker.rb +1 -0
 - metadata +7 -6
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: abf6e6cece7b22f0d5aad026d0d08bb4d8e8f9cb711616e8adcd14e0437995e0
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 56f7d508538e8349ee212b280d5828142934d88d16edd8d730d62909fd80780e
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: e738ec527622411944b8582ad9210b2a093bb71b55c9c6cb1a7a3005416bca62b388e5350f43656e9c69ab1bf8642a7d1e55f09999ef8c42341e4253bfbb0b59
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: ce2badf5898fe3457145f89465b22158d6955e0d808eb3556f551f8f37b62922ddd13fa918f9c40ce4ecfd82204b66d50909a38c1a582b0b9ccd51469a185642
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            name: RSpec
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            on:
         
     | 
| 
      
 4 
     | 
    
         
            +
              push:
         
     | 
| 
      
 5 
     | 
    
         
            +
                branches: [ master ]
         
     | 
| 
      
 6 
     | 
    
         
            +
              pull_request:
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            jobs:
         
     | 
| 
      
 9 
     | 
    
         
            +
              test:
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                runs-on: ubuntu-latest
         
     | 
| 
      
 12 
     | 
    
         
            +
                strategy:
         
     | 
| 
      
 13 
     | 
    
         
            +
                  matrix:
         
     | 
| 
      
 14 
     | 
    
         
            +
                    ruby-version: ['2.7', '3.0', '3.1']
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                steps:
         
     | 
| 
      
 17 
     | 
    
         
            +
                - uses: actions/checkout@v2
         
     | 
| 
      
 18 
     | 
    
         
            +
                - name: Set up Ruby
         
     | 
| 
      
 19 
     | 
    
         
            +
                # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
         
     | 
| 
      
 20 
     | 
    
         
            +
                # change this to (see https://github.com/ruby/setup-ruby#versioning):
         
     | 
| 
      
 21 
     | 
    
         
            +
                # uses: ruby/setup-ruby@v1
         
     | 
| 
      
 22 
     | 
    
         
            +
                  uses: ruby/setup-ruby@v1
         
     | 
| 
      
 23 
     | 
    
         
            +
                  with:
         
     | 
| 
      
 24 
     | 
    
         
            +
                    ruby-version: ${{ matrix.ruby-version }}
         
     | 
| 
      
 25 
     | 
    
         
            +
                    bundler-cache: true # runs 'bundle install' and caches installed gems automatically
         
     | 
| 
      
 26 
     | 
    
         
            +
                - name: Run tests
         
     | 
| 
      
 27 
     | 
    
         
            +
                  run: bundle exec rake
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # CronoTrigger
         
     | 
| 
       2 
2 
     | 
    
         
             
            [](https://badge.fury.io/rb/crono_trigger)
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            
         
     | 
| 
       4 
4 
     | 
    
         
             
            [](https://codecov.io/gh/joker1007/crono_trigger)
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            Asynchronous Job Scheduler for Rails.
         
     | 
| 
         @@ -137,10 +137,17 @@ mail.next_execute_at # => next 13:00 with Asia/Japan 
     | 
|
| 
       137 
137 
     | 
    
         | 
| 
       138 
138 
     | 
    
         
             
            #### Run Worker
         
     | 
| 
       139 
139 
     | 
    
         | 
| 
      
 140 
     | 
    
         
            +
            ues `crono_trigger` command.
         
     | 
| 
      
 141 
     | 
    
         
            +
            `crono_trigger` command accepts model class names.
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
            For example,
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
       140 
145 
     | 
    
         
             
            ```
         
     | 
| 
       141 
146 
     | 
    
         
             
            $ crono_trigger MailNotification
         
     | 
| 
       142 
147 
     | 
    
         
             
            ```
         
     | 
| 
       143 
148 
     | 
    
         | 
| 
      
 149 
     | 
    
         
            +
            And other options is following.
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
       144 
151 
     | 
    
         
             
            ```
         
     | 
| 
       145 
152 
     | 
    
         
             
            $ crono_trigger --help
         
     | 
| 
       146 
153 
     | 
    
         
             
            Usage: crono_trigger [options] MODEL [MODEL..]
         
     | 
    
        data/lib/crono_trigger/cli.rb
    CHANGED
    
    | 
         @@ -31,7 +31,7 @@ opt_parser = OptionParser.new do |opts| 
     | 
|
| 
       31 
31 
     | 
    
         
             
              end
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
              opts.on("-c", "--concurrency=SIZE", Integer, "Execute thread size (Default: 25)") do |i|
         
     | 
| 
       34 
     | 
    
         
            -
                options[: 
     | 
| 
      
 34 
     | 
    
         
            +
                options[:executor_thread] = i
         
     | 
| 
       35 
35 
     | 
    
         
             
              end
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
              opts.on("-l", "--log=LOGFILE", "Set log output destination (Default: STDOUT or ./crono_trigger.log if daemonize is true)") do |log|
         
     | 
| 
         @@ -67,7 +67,7 @@ end 
     | 
|
| 
       67 
67 
     | 
    
         | 
| 
       68 
68 
     | 
    
         
             
            CronoTrigger.load_config(options[:config], options[:env]) if options[:config]
         
     | 
| 
       69 
69 
     | 
    
         | 
| 
       70 
     | 
    
         
            -
            %i(polling_thread polling_interval  
     | 
| 
      
 70 
     | 
    
         
            +
            %i(worker_id polling_thread polling_interval executor_thread).each do |name|
         
     | 
| 
       71 
71 
     | 
    
         
             
              CronoTrigger.config[name] = options[name] if options[name]
         
     | 
| 
       72 
72 
     | 
    
         
             
            end
         
     | 
| 
       73 
73 
     | 
    
         | 
| 
         @@ -5,6 +5,9 @@ module CronoTrigger 
     | 
|
| 
       5 
5 
     | 
    
         
             
                  @stop_flag = stop_flag
         
     | 
| 
       6 
6 
     | 
    
         
             
                  @logger = logger
         
     | 
| 
       7 
7 
     | 
    
         
             
                  @executor = executor
         
     | 
| 
      
 8 
     | 
    
         
            +
                  if @executor.fallback_policy != :caller_runs
         
     | 
| 
      
 9 
     | 
    
         
            +
                    raise ArgumentError, "executor's fallback policies except for :caller_runs are not supported"
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
       8 
11 
     | 
    
         
             
                  @execution_counter = execution_counter
         
     | 
| 
       9 
12 
     | 
    
         
             
                  @quiet = Concurrent::AtomicBoolean.new(false)
         
     | 
| 
       10 
13 
     | 
    
         
             
                end
         
     | 
| 
         @@ -50,34 +53,28 @@ module CronoTrigger 
     | 
|
| 
       50 
53 
     | 
    
         
             
                end
         
     | 
| 
       51 
54 
     | 
    
         | 
| 
       52 
55 
     | 
    
         
             
                def poll(model)
         
     | 
| 
       53 
     | 
    
         
            -
                  @logger. 
     | 
| 
       54 
     | 
    
         
            -
                  records = []
         
     | 
| 
       55 
     | 
    
         
            -
                  overflowed_record_ids = []
         
     | 
| 
      
 56 
     | 
    
         
            +
                  @logger.info "(polling-thread-#{Thread.current.object_id}) Poll #{model}"
         
     | 
| 
       56 
57 
     | 
    
         | 
| 
       57 
     | 
    
         
            -
                   
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
      
 58 
     | 
    
         
            +
                  maybe_has_next = true
         
     | 
| 
      
 59 
     | 
    
         
            +
                  while maybe_has_next && !@stop_flag.set?
         
     | 
| 
      
 60 
     | 
    
         
            +
                    records, maybe_has_next = model.connection_pool.with_connection do
         
     | 
| 
      
 61 
     | 
    
         
            +
                      model.executables_with_lock
         
     | 
| 
       60 
62 
     | 
    
         
             
                    end
         
     | 
| 
       61 
63 
     | 
    
         | 
| 
       62 
64 
     | 
    
         
             
                    records.each do |record|
         
     | 
| 
       63 
     | 
    
         
            -
                       
     | 
| 
       64 
     | 
    
         
            -
                        @ 
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                           
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
                           
     | 
| 
       69 
     | 
    
         
            -
                            @execution_counter.decrement
         
     | 
| 
       70 
     | 
    
         
            -
                          end
         
     | 
| 
      
 65 
     | 
    
         
            +
                      @executor.post do
         
     | 
| 
      
 66 
     | 
    
         
            +
                        @execution_counter.increment
         
     | 
| 
      
 67 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 68 
     | 
    
         
            +
                          process_record(record)
         
     | 
| 
      
 69 
     | 
    
         
            +
                        ensure
         
     | 
| 
      
 70 
     | 
    
         
            +
                          @execution_counter.decrement
         
     | 
| 
       71 
71 
     | 
    
         
             
                        end
         
     | 
| 
       72 
     | 
    
         
            -
                      rescue Concurrent::RejectedExecutionError
         
     | 
| 
       73 
     | 
    
         
            -
                        overflowed_record_ids << record.id
         
     | 
| 
       74 
72 
     | 
    
         
             
                      end
         
     | 
| 
       75 
73 
     | 
    
         
             
                    end
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
                  end while overflowed_record_ids.empty? && records.any?
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
       78 
75 
     | 
    
         
             
                end
         
     | 
| 
       79 
76 
     | 
    
         | 
| 
       80 
     | 
    
         
            -
                private 
     | 
| 
      
 77 
     | 
    
         
            +
                private
         
     | 
| 
       81 
78 
     | 
    
         | 
| 
       82 
79 
     | 
    
         
             
                def process_record(record)
         
     | 
| 
       83 
80 
     | 
    
         
             
                  record.class.connection_pool.with_connection do
         
     | 
| 
         @@ -88,16 +85,5 @@ module CronoTrigger 
     | 
|
| 
       88 
85 
     | 
    
         
             
                  @logger.error(ex)
         
     | 
| 
       89 
86 
     | 
    
         
             
                  CronoTrigger::GlobalExceptionHandler.handle_global_exception(ex)
         
     | 
| 
       90 
87 
     | 
    
         
             
                end
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
                def unlock_overflowed_records(model, overflowed_record_ids)
         
     | 
| 
       93 
     | 
    
         
            -
                  model.connection_pool.with_connection do
         
     | 
| 
       94 
     | 
    
         
            -
                    unless overflowed_record_ids.empty?
         
     | 
| 
       95 
     | 
    
         
            -
                      model.where(id: overflowed_record_ids).crono_trigger_unlock_all!
         
     | 
| 
       96 
     | 
    
         
            -
                    end
         
     | 
| 
       97 
     | 
    
         
            -
                  end
         
     | 
| 
       98 
     | 
    
         
            -
                rescue ActiveRecord::ConnectionNotEstablished, ActiveRecord::LockWaitTimeout, ActiveRecord::StatementTimeout, ActiveRecord::Deadlocked
         
     | 
| 
       99 
     | 
    
         
            -
                  sleep 1
         
     | 
| 
       100 
     | 
    
         
            -
                  retry
         
     | 
| 
       101 
     | 
    
         
            -
                end
         
     | 
| 
       102 
88 
     | 
    
         
             
              end
         
     | 
| 
       103 
89 
     | 
    
         
             
            end
         
     | 
| 
         @@ -34,7 +34,7 @@ module CronoTrigger 
     | 
|
| 
       34 
34 
     | 
    
         | 
| 
       35 
35 
     | 
    
         
             
                  define_model_callbacks :execute, :retry
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                  scope :executables, ->(from: Time.current, limit: CronoTrigger.config.executor_thread * 3 
     | 
| 
      
 37 
     | 
    
         
            +
                  scope :executables, ->(from: Time.current, limit: CronoTrigger.config.executor_thread * 3, including_locked: false) do
         
     | 
| 
       38 
38 
     | 
    
         
             
                    t = arel_table
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
                    rel = where(t[crono_trigger_column_name(:next_execute_at)].lteq(from))
         
     | 
| 
         @@ -63,8 +63,9 @@ module CronoTrigger 
     | 
|
| 
       63 
63 
     | 
    
         
             
                end
         
     | 
| 
       64 
64 
     | 
    
         | 
| 
       65 
65 
     | 
    
         
             
                module ClassMethods
         
     | 
| 
       66 
     | 
    
         
            -
                  def executables_with_lock(limit: CronoTrigger.config.executor_thread * 3 
     | 
| 
      
 66 
     | 
    
         
            +
                  def executables_with_lock(limit: CronoTrigger.config.executor_thread * 3)
         
     | 
| 
       67 
67 
     | 
    
         
             
                    ids = executables(limit: limit).pluck(:id)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    maybe_has_next = !ids.empty?
         
     | 
| 
       68 
69 
     | 
    
         
             
                    records = []
         
     | 
| 
       69 
70 
     | 
    
         
             
                    ids.each do |id|
         
     | 
| 
       70 
71 
     | 
    
         
             
                      transaction do
         
     | 
| 
         @@ -75,7 +76,7 @@ module CronoTrigger 
     | 
|
| 
       75 
76 
     | 
    
         
             
                        end
         
     | 
| 
       76 
77 
     | 
    
         
             
                      end
         
     | 
| 
       77 
78 
     | 
    
         
             
                    end
         
     | 
| 
       78 
     | 
    
         
            -
                    records
         
     | 
| 
      
 79 
     | 
    
         
            +
                    [records, maybe_has_next]
         
     | 
| 
       79 
80 
     | 
    
         
             
                  end
         
     | 
| 
       80 
81 
     | 
    
         | 
| 
       81 
82 
     | 
    
         
             
                  def crono_trigger_column_name(name)
         
     | 
    
        data/lib/crono_trigger/worker.rb
    CHANGED
    
    | 
         @@ -24,6 +24,7 @@ module CronoTrigger 
     | 
|
| 
       24 
24 
     | 
    
         
             
                    min_threads: 1,
         
     | 
| 
       25 
25 
     | 
    
         
             
                    max_threads: CronoTrigger.config.executor_thread,
         
     | 
| 
       26 
26 
     | 
    
         
             
                    max_queue: CronoTrigger.config.executor_thread * 2,
         
     | 
| 
      
 27 
     | 
    
         
            +
                    fallback_policy: :caller_runs,
         
     | 
| 
       27 
28 
     | 
    
         
             
                  )
         
     | 
| 
       28 
29 
     | 
    
         
             
                  @execution_counter = Concurrent::AtomicFixnum.new
         
     | 
| 
       29 
30 
     | 
    
         
             
                  @logger = Logger.new(STDOUT) unless @logger
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: crono_trigger
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.6. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.6.4
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - joker1007
         
     | 
| 
       8 
     | 
    
         
            -
            autorequire: 
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date:  
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2022-08-16 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: chrono
         
     | 
| 
         @@ -244,6 +244,7 @@ executables: 
     | 
|
| 
       244 
244 
     | 
    
         
             
            extensions: []
         
     | 
| 
       245 
245 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
       246 
246 
     | 
    
         
             
            files:
         
     | 
| 
      
 247 
     | 
    
         
            +
            - ".github/workflows/rspec.yml"
         
     | 
| 
       247 
248 
     | 
    
         
             
            - ".gitignore"
         
     | 
| 
       248 
249 
     | 
    
         
             
            - ".rspec"
         
     | 
| 
       249 
250 
     | 
    
         
             
            - ".travis.yml"
         
     | 
| 
         @@ -324,7 +325,7 @@ homepage: https://github.com/joker1007/crono_trigger 
     | 
|
| 
       324 
325 
     | 
    
         
             
            licenses:
         
     | 
| 
       325 
326 
     | 
    
         
             
            - MIT
         
     | 
| 
       326 
327 
     | 
    
         
             
            metadata: {}
         
     | 
| 
       327 
     | 
    
         
            -
            post_install_message: 
     | 
| 
      
 328 
     | 
    
         
            +
            post_install_message:
         
     | 
| 
       328 
329 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
       329 
330 
     | 
    
         
             
            require_paths:
         
     | 
| 
       330 
331 
     | 
    
         
             
            - lib
         
     | 
| 
         @@ -339,8 +340,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       339 
340 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       340 
341 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       341 
342 
     | 
    
         
             
            requirements: []
         
     | 
| 
       342 
     | 
    
         
            -
            rubygems_version: 3. 
     | 
| 
       343 
     | 
    
         
            -
            signing_key: 
     | 
| 
      
 343 
     | 
    
         
            +
            rubygems_version: 3.3.3
         
     | 
| 
      
 344 
     | 
    
         
            +
            signing_key:
         
     | 
| 
       344 
345 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       345 
346 
     | 
    
         
             
            summary: In Service Asynchronous Job Scheduler for Rails
         
     | 
| 
       346 
347 
     | 
    
         
             
            test_files: []
         
     |