nagare-redis 0.1.1 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce1c0837c43e0622c3472886a4e994ba6148dffe7d7d5db96dc0b63aff0db0bb
4
- data.tar.gz: b885c670da1a7c41e25cf92bfc3be24bdfde8cbac52d8c693dca48c76a6bdfd5
3
+ metadata.gz: f7c85971f2e4fda73c0c03700cc54c07e2b2b40dcf508b6f6f6f95f9e595aba4
4
+ data.tar.gz: d0b1617d063bd24878e6a59abac5d5a64f2e8a6311992844d01ec4646bc67adb
5
5
  SHA512:
6
- metadata.gz: a1c6b90dc57c92dc9f36fe64d84e14a7ada92becb47cec9359d004833a10377757f1de74ba88bd6b28cdce80891b0df9503ec1921631ab5cb8693b35b8c6df12
7
- data.tar.gz: 6434761604072b94a3f9d0634b03a4a68dc8e31b973bd46771c78fc8e918092b4cc9e3c56e2caa22b496439705c7ff63968f7907e9241a80045c74c8ce68dd88
6
+ metadata.gz: 37907d60c4a97ae9d16f2bc2aa5f4054b769fe33ce91145c63aba78b5d09d3c2efe21240154de6f69056667f11c0f9482c4fdc68df7dda1abeea1facaf3e5238
7
+ data.tar.gz: cfcace1bce2ab24afaad1568616b23ad91aac10e5780bd33f2c82d938844720234e4a31acb12d3f12f4fcc157c812f06ae99e31d6510b552fd85ff502f8a8d37
@@ -0,0 +1,43 @@
1
+ name: release
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ release-please:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: GoogleCloudPlatform/release-please-action@v2
13
+ id: release
14
+ with:
15
+ release-type: ruby
16
+ package-name: nagare-redis
17
+ bump-minor-pre-major: true
18
+ version-file: "lib/nagare/version.rb"
19
+ # Checkout code if release was created
20
+ - uses: actions/checkout@v2
21
+ if: ${{ steps.release.outputs.release_created }}
22
+ # Setup ruby if a release was created
23
+ - uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: 2.6.8
26
+ if: ${{ steps.release.outputs.release_created }}
27
+ # Bundle install
28
+ - run: bundle install
29
+ if: ${{ steps.release.outputs.release_created }}
30
+ # Publish
31
+ - name: publish gem
32
+ run: |
33
+ mkdir -p $HOME/.gem
34
+ touch $HOME/.gem/credentials
35
+ chmod 0600 $HOME/.gem/credentials
36
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
37
+ gem build *.gemspec
38
+ gem push *.gem
39
+ env:
40
+ # Make sure to update the secret name
41
+ # if yours isn't named RUBYGEMS_AUTH_TOKEN
42
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
43
+ if: ${{ steps.release.outputs.release_created }}
@@ -15,9 +15,9 @@ jobs:
15
15
  - uses: actions/checkout@v2
16
16
 
17
17
  - name: Set up Ruby 2.6
18
- uses: actions/setup-ruby@v1
18
+ uses: ruby/setup-ruby@v1
19
19
  with:
20
- ruby-version: 2.6.6
20
+ ruby-version: 2.6.8
21
21
 
22
22
  - uses: actions/cache@v1
23
23
  with:
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## [0.3.0](https://www.github.com/vavato-be/nagare/compare/v0.2.0...v0.3.0) (2021-07-13)
4
+
5
+
6
+ ### Features
7
+
8
+ * document release process ([eb973e5](https://www.github.com/vavato-be/nagare/commit/eb973e526156dfa89344671060044e6d8560e0e6))
9
+
10
+ ## [0.2.0](https://www.github.com/vavato-be/nagare/compare/v0.1.2...v0.2.0) (2021-07-13)
11
+
12
+
13
+ ### Features
14
+
15
+ * create PR for release after merge on main ([f562d62](https://www.github.com/vavato-be/nagare/commit/f562d6216e45b63d1594a425b04faca3acad8857))
data/Gemfile CHANGED
@@ -4,4 +4,5 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  gem 'rake', '~> 12.0'
7
+ gem 'redis', github: 'vavato-be/redis-rb'
7
8
  gem 'rspec', '~> 3.0'
data/Gemfile.lock CHANGED
@@ -1,22 +1,27 @@
1
+ GIT
2
+ remote: https://github.com/vavato-be/redis-rb.git
3
+ revision: 79f36a58e69beb72f3bcef2ae584b30324fa2f07
4
+ specs:
5
+ redis (6.2.0)
6
+
1
7
  PATH
2
8
  remote: .
3
9
  specs:
4
- nagare-redis (0.1.1)
5
- redis (~> 4.2, >= 4.1.0)
10
+ nagare-redis (0.1.5)
11
+ redis (~> 6.2, >= 6.2.0)
6
12
 
7
13
  GEM
8
14
  remote: https://rubygems.org/
9
15
  specs:
10
- ast (2.4.1)
16
+ ast (2.4.2)
11
17
  diff-lcs (1.3)
12
- parallel (1.19.2)
13
- parser (2.7.1.4)
18
+ parallel (1.20.1)
19
+ parser (3.0.2.0)
14
20
  ast (~> 2.4.1)
15
21
  rainbow (3.0.0)
16
22
  rake (12.3.2)
17
- redis (4.2.1)
18
- regexp_parser (1.7.1)
19
- rexml (3.2.4)
23
+ regexp_parser (2.1.1)
24
+ rexml (3.2.5)
20
25
  rspec (3.9.0)
21
26
  rspec-core (~> 3.9.0)
22
27
  rspec-expectations (~> 3.9.0)
@@ -30,21 +35,22 @@ GEM
30
35
  diff-lcs (>= 1.2.0, < 2.0)
31
36
  rspec-support (~> 3.9.0)
32
37
  rspec-support (3.9.3)
33
- rubocop (0.88.0)
38
+ rubocop (1.18.3)
34
39
  parallel (~> 1.10)
35
- parser (>= 2.7.1.1)
40
+ parser (>= 3.0.0.0)
36
41
  rainbow (>= 2.2.2, < 4.0)
37
- regexp_parser (>= 1.7)
42
+ regexp_parser (>= 1.8, < 3.0)
38
43
  rexml
39
- rubocop-ast (>= 0.1.0, < 1.0)
44
+ rubocop-ast (>= 1.7.0, < 2.0)
40
45
  ruby-progressbar (~> 1.7)
41
- unicode-display_width (>= 1.4.0, < 2.0)
42
- rubocop-ast (0.2.0)
43
- parser (>= 2.7.0.1)
44
- rubocop-rspec (1.42.0)
45
- rubocop (>= 0.87.0)
46
- ruby-progressbar (1.10.1)
47
- unicode-display_width (1.7.0)
46
+ unicode-display_width (>= 1.4.0, < 3.0)
47
+ rubocop-ast (1.7.0)
48
+ parser (>= 3.0.1.1)
49
+ rubocop-rspec (2.4.0)
50
+ rubocop (~> 1.0)
51
+ rubocop-ast (>= 1.1.0)
52
+ ruby-progressbar (1.11.0)
53
+ unicode-display_width (2.0.0)
48
54
 
49
55
  PLATFORMS
50
56
  ruby
@@ -52,9 +58,10 @@ PLATFORMS
52
58
  DEPENDENCIES
53
59
  nagare-redis!
54
60
  rake (~> 12.0)
61
+ redis!
55
62
  rspec (~> 3.0)
56
- rubocop (~> 0.88, >= 0.88)
57
- rubocop-rspec (~> 1.42, >= 1.42.0)
63
+ rubocop (~> 1.18.3, >= 1.18.3)
64
+ rubocop-rspec (~> 2.4.0, >= 2.4.0)
58
65
 
59
66
  BUNDLED WITH
60
67
  2.1.0
data/README.md CHANGED
@@ -25,7 +25,7 @@ information on how this works see
25
25
  Add this line to your application's Gemfile:
26
26
 
27
27
  ```ruby
28
- gem 'nagare'
28
+ gem 'nagare-redis'
29
29
  ```
30
30
 
31
31
  And then execute:
@@ -40,20 +40,25 @@ To use with rails, add nagare to the initializers:
40
40
  #### config/initializers/nagare.rb
41
41
  ```ruby
42
42
  Nagare.configure do |config|
43
- # After x seconds a consumer is considered dead and its messages
44
- # are assigned to a different consumer in the group. Configuring
43
+ # After x milisseconds a pending message is considered failed and
44
+ # gets retried by a different consumer in the group. Configuring
45
45
  # it too low might cause double processing of messages as a consumer
46
46
  # "steals" the load of another while the first one is still processing
47
47
  # it and hasn't had the chance to ACK, configuring it too high will
48
48
  # introduce latency in your processing.
49
- # Default: 300 (5 minutes)
50
- config.dead_consumer_timeout = 600
49
+ # Default: 600.000 (10 minutes)
50
+ config.min_idle_time = 600_0000
51
51
 
52
52
  # This is the consumer group name that will be used or created in
53
53
  # Redis. Use a different group for every microservice / application
54
54
  # Default: Rails.env
55
55
  config.group_name = :monolith
56
56
 
57
+ # A suffix is supported in order to separate different environments
58
+ # within the same redis database. Useful for development/test. This
59
+ # gets added automatically to stream names and consumer group names.
60
+ config.suffix = ''
61
+
57
62
  # URL to connect to redis. Defaults to redis://localhost:6379 uses
58
63
  # ENV['REDIS_URL'] if present.
59
64
  config.redis_url = 'redis://10.1.1.1:6379'
@@ -106,7 +111,7 @@ end
106
111
 
107
112
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
108
113
 
109
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
114
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). A merge to the `main` branch will automatically open a PR to release a new version of nagare. Merging that PR will release to rubygems.
110
115
 
111
116
  ## Contributing
112
117
 
data/exe/nagare CHANGED
@@ -2,8 +2,8 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  if File.exist?('config/environment.rb')
5
- # Load rails env if inside a rails appa
6
- require_relative '../config/environment'
5
+ # Load rails env if inside a rails app
6
+ require_relative File.join(Dir.pwd, 'config', 'environment')
7
7
  elsif File.exist?('Gemfile.lock')
8
8
  # Load bundler context if using bundler
9
9
  require 'bundler/setup'
data/lib/nagare.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'logger'
4
4
  require 'json'
5
+ require 'redis'
5
6
  require 'nagare/version'
6
7
  require 'nagare/config'
7
8
  require 'nagare/redis_streams'
data/lib/nagare/config.rb CHANGED
@@ -5,13 +5,13 @@ module Nagare
5
5
  # See the README for possible values and what they do
6
6
  class Config
7
7
  class << self
8
- attr_accessor :dead_consumer_timeout, :group_name, :redis_url, :threads,
9
- :suffix
8
+ attr_accessor :group_name, :redis_url, :threads, :suffix, :min_idle_time
10
9
 
11
10
  # Runs code in the block passed in to configure Nagare and sets defaults
12
11
  # when values are not set.
13
12
  #
14
- # returns Nagare::Config self
13
+ # returns [Nagare::Config] self
14
+ # rubocop:disable Metrics/CyclomaticComplexity
15
15
  def configure
16
16
  yield(self)
17
17
  @dead_consumer_timeout ||= 5000
@@ -19,8 +19,10 @@ module Nagare
19
19
  @redis_url = redis_url || ENV['REDIS_URL'] || 'redis://localhost:6379'
20
20
  @threads ||= 1
21
21
  @suffix ||= nil
22
+ @min_idle_time ||= 600_000
22
23
  self
23
24
  end
25
+ # rubocop:enable Metrics/CyclomaticComplexity
24
26
  end
25
27
  end
26
28
  end
@@ -43,6 +43,7 @@ module Nagare
43
43
  # The ClassMethods module is automatically loaded into child classes
44
44
  # effectively adding the `stream` class method to the child class.`
45
45
  def self.inherited(subclass)
46
+ super
46
47
  subclass.extend(ClassMethods)
47
48
  end
48
49
 
@@ -59,8 +59,13 @@ module Nagare
59
59
  private
60
60
 
61
61
  def poll_stream(stream, listeners)
62
- # TODO: Use thread pool
63
- messages = Nagare::RedisStreams.read_next_messages(stream, group)
62
+ return unless Nagare::RedisStreams.group_exists?(stream, group)
63
+
64
+ messages = Nagare::RedisStreams.claim_next_stuck_message(stream, group)
65
+
66
+ if messages.nil? || messages.empty?
67
+ messages = Nagare::RedisStreams.read_next_messages(stream, group)
68
+ end
64
69
  return unless messages.any?
65
70
 
66
71
  messages.each do |message|
@@ -68,13 +73,16 @@ module Nagare
68
73
  end
69
74
  end
70
75
 
76
+ def claim_pending_messages(stream)
77
+ return nil unless Nagare::RedisStreams.group_exists?(stream, group)
78
+ end
79
+
71
80
  def deliver_message(stream, message, listeners)
72
81
  listener_failed = false
73
82
 
74
83
  listeners.each do |listener|
75
84
  invoke_listener(stream, message, listener)
76
85
  rescue StandardError => e
77
- # TODO: Retry logic
78
86
  logger.error e.message
79
87
  logger.error e.backtrace.join("\n")
80
88
  listener_failed = true
@@ -30,7 +30,6 @@ module Nagare
30
30
  # @param group [String] name of the group
31
31
  #
32
32
  # @return [Boolean] true if the group exists, otherwise false
33
- # rubocop:disable Metrics/AbcSize
34
33
  def group_exists?(stream, group)
35
34
  stream = stream_name(stream)
36
35
  info = connection.xinfo(:groups, stream.to_s)
@@ -41,7 +40,6 @@ module Nagare
41
40
  logger.info e.backtrace.join("\n")
42
41
  false
43
42
  end
44
- # rubocop:enable Metrics/AbcSize
45
43
 
46
44
  ##
47
45
  # Creates a group in redis for the stream using xgroup
@@ -81,6 +79,25 @@ module Nagare
81
79
  connection.xadd(stream, { "#{event_name}": data })
82
80
  end
83
81
 
82
+ ##
83
+ # Claums the next message of the consumer group that is stuck
84
+ # (pending and past min_idle_time since being picked up)
85
+ #
86
+ # @param stream [String] name of the stream
87
+ # @param group [String] name of the consumer group
88
+ #
89
+ # @return [Array[Hash]] array containing the 1 message or empty
90
+ def claim_next_stuck_message(stream, group)
91
+ stream = stream_name(stream)
92
+ result = connection.xautoclaim(stream,
93
+ "#{stream}-#{group}",
94
+ "#{hostname}-#{thread_id}",
95
+ Nagare::Config.min_idle_time,
96
+ '0-0',
97
+ count: 1)
98
+ result['entries'] || []
99
+ end
100
+
84
101
  ##
85
102
  # Reads the next messages from the consumer group in redis.
86
103
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nagare
4
- VERSION = '0.1.1'
4
+ VERSION = '0.1.5'
5
5
  end
data/nagare.gemspec CHANGED
@@ -20,14 +20,16 @@ Gem::Specification.new do |spec|
20
20
  spec.metadata['source_code_uri'] = 'https://github.com/vavato-be/nagare.git'
21
21
  spec.metadata['changelog_uri'] = 'https://github.com/vavato-be/nagare/CHANGELOG.md'
22
22
 
23
- spec.add_dependency 'redis', '~> 4.2', '>= 4.1.0'
24
- spec.add_development_dependency 'rubocop', '~> 0.88', '>= 0.88'
25
- spec.add_development_dependency 'rubocop-rspec', '~> 1.42', '>= 1.42.0'
23
+ spec.add_dependency 'redis', '~> 6.2', '>= 6.2.0'
24
+ spec.add_development_dependency 'rubocop', '~> 1.18.3', '>= 1.18.3'
25
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.4.0', '>= 2.4.0'
26
26
 
27
27
  # Specify which files should be added to the gem when it is released.
28
28
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
29
29
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
30
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
30
+ `git ls-files -z`.split("\x0").reject do |f|
31
+ f.match(%r{^(test|spec|features)/})
32
+ end
31
33
  end
32
34
  spec.bindir = 'exe'
33
35
  spec.executables << 'nagare'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nagare-redis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Reis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-30 00:00:00.000000000 Z
11
+ date: 2021-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -16,60 +16,60 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 4.1.0
19
+ version: 6.2.0
20
20
  - - "~>"
21
21
  - !ruby/object:Gem::Version
22
- version: '4.2'
22
+ version: '6.2'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 4.1.0
29
+ version: 6.2.0
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: '4.2'
32
+ version: '6.2'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: rubocop
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '0.88'
39
+ version: 1.18.3
40
40
  - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: '0.88'
42
+ version: 1.18.3
43
43
  type: :development
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: '0.88'
49
+ version: 1.18.3
50
50
  - - "~>"
51
51
  - !ruby/object:Gem::Version
52
- version: '0.88'
52
+ version: 1.18.3
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: rubocop-rspec
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
- version: 1.42.0
59
+ version: 2.4.0
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '1.42'
62
+ version: 2.4.0
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: 1.42.0
69
+ version: 2.4.0
70
70
  - - "~>"
71
71
  - !ruby/object:Gem::Version
72
- version: '1.42'
72
+ version: 2.4.0
73
73
  description: Nagare is a wrapper around Redis Streams that enables event-driven architectures
74
74
  and pub/sub messaging withdurable subscribers
75
75
  email:
@@ -79,10 +79,12 @@ executables:
79
79
  extensions: []
80
80
  extra_rdoc_files: []
81
81
  files:
82
+ - ".github/workflows/release.yml"
82
83
  - ".github/workflows/run-tests.yml"
83
84
  - ".gitignore"
84
85
  - ".rspec"
85
86
  - ".rubocop.yml"
87
+ - CHANGELOG.md
86
88
  - CODE_OF_CONDUCT.md
87
89
  - Gemfile
88
90
  - Gemfile.lock
@@ -122,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
124
  - !ruby/object:Gem::Version
123
125
  version: '0'
124
126
  requirements: []
125
- rubygems_version: 3.0.3
127
+ rubygems_version: 3.0.3.1
126
128
  signing_key:
127
129
  specification_version: 4
128
130
  summary: Persistent and resilient pub/sub using Redis Streams