services 7.2.0 → 8.0.0

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: 7aedebb8369e465e6bc0dbde201a6f2e353ef4fb50b9c7e1568914a6aa5c6bdd
4
- data.tar.gz: b9fcc3a9b6a1d38de2257bdab6145c68db707e0665d5538430e3db2ac46bef2e
3
+ metadata.gz: 968f73b837027e7a1fd1d445b18073fec9e4fa449c5975086551c51c58dccf8b
4
+ data.tar.gz: 92f3ada6ce7a8617e8a50ddf4a5f11827722845dd952c244547f93e76853c283
5
5
  SHA512:
6
- metadata.gz: '08637ac5fe53454bd404fd069f00179a010cfb0f32295948b403796b7d24ec106b9485a732f2c37d05e9983bc8188ae5e76152c871c77a9fa1f6008ae3e4dfbb'
7
- data.tar.gz: f494e1694f08b16debb2d21d6d82a2473b46822e5ca433d64e5c74b28d85b074937bd94b440c277593253bd5e67b2c1a2b2aaf0058d1155b92ba7880dbf4e772
6
+ metadata.gz: 6d8931cc9b545291cd231cdec1ede213e0838261d3fdcfe19dfd3f71b70c0f83dbf11798573ead47238041bb889e9943abed244cc78661febee80c5ddac9b2ed
7
+ data.tar.gz: 3438431663f57852b0167a85ad4dd9f895198f7854090b4d06e8844c2eba01089d3c0a743a4ff37adf8abe9b4cb02395d9bde6fb8bc17923f95a71b9d5007086
data/Appraisals CHANGED
@@ -1,11 +1,11 @@
1
- appraise 'rails_4.2' do
2
- gem 'rails', '~> 4.2.0'
1
+ appraise 'rails_5.2' do
2
+ gem 'rails', '~> 5.2.0'
3
3
  end
4
4
 
5
- appraise 'rails_5.0' do
6
- gem 'rails', '~> 5.0.0'
5
+ appraise 'rails_6.0' do
6
+ gem 'rails', '~> 6.0.0'
7
7
  end
8
8
 
9
- appraise 'rails_5.1' do
10
- gem 'rails', '~> 5.1.0'
9
+ appraise 'rails_6.1' do
10
+ gem 'rails', '~> 6.1.0'
11
11
  end
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Services
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/services.png)](http://badge.fury.io/rb/services)
4
- [![Build Status](https://secure.travis-ci.org/krautcomputing/services.png)](http://travis-ci.org/krautcomputing/services)
5
- [![Code Climate](https://codeclimate.com/github/krautcomputing/services.png)](https://codeclimate.com/github/krautcomputing/services)
4
+ [![Build Status](https://secure.travis-ci.org/manuelmeurer/services.png)](http://travis-ci.org/manuelmeurer/services)
5
+ [![Code Climate](https://codeclimate.com/github/manuelmeurer/services.png)](https://codeclimate.com/github/manuelmeurer/services)
6
6
 
7
7
  Services is a collection of modules and base classes that let you simply add a service layer to your Rails app.
8
8
 
@@ -20,7 +20,7 @@ For disambiguation: in this README, when you read "Services" with a uppercase "S
20
20
 
21
21
  #### Ruby >= 2.2.5
22
22
 
23
- #### Rails >= 4.2
23
+ #### Rails >= 5.2
24
24
 
25
25
  #### Redis >= 3.0
26
26
 
@@ -28,7 +28,7 @@ Redis is used at several points, e.g. to store information about the currently r
28
28
 
29
29
  #### Postgres (optional)
30
30
 
31
- The SQL that `Services::Query` (discussed further down) generates is optimized for Postgres. It might work with other databases but it's not guaranteed. If you're not using Postgres, you can still use all other parts of Services, just don't use `Services::Query` or, even better, submit a [pull request](https://github.com/krautcomputing/services/issues) that fixes it to work with your database!
31
+ The SQL that `Services::Query` (discussed further down) generates is optimized for Postgres. It might work with other databases but it's not guaranteed. If you're not using Postgres, you can still use all other parts of Services, just don't use `Services::Query` or, even better, submit a [pull request](https://github.com/manuelmeurer/services/issues) that fixes it to work with your database!
32
32
 
33
33
  #### Sidekiq (optional)
34
34
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 4.2.0"
5
+ gem "rails", "~> 5.2.0"
6
6
 
7
7
  gemspec path: "../"
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 5.0.0"
5
+ gem "rails", "~> 6.0.0"
6
6
 
7
7
  gemspec path: "../"
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 5.1.0"
5
+ gem "rails", "~> 6.1.0"
6
6
 
7
7
  gemspec path: "../"
data/lib/services.rb CHANGED
@@ -5,8 +5,8 @@ require_relative 'services/logger/null'
5
5
  module Services
6
6
  include GemConfig::Base
7
7
 
8
- BackgroundProcessorNotFound = Class.new(StandardError)
9
- RedisNotFound = Class.new(StandardError)
8
+ NoBackgroundProcessorFound = Class.new(StandardError)
9
+ RedisNotFound = Class.new(StandardError)
10
10
 
11
11
  with_configuration do
12
12
  has :logger, default: Services::Logger::Null.new
@@ -18,18 +18,15 @@ module Services
18
18
  @redis ||= self.configuration.redis || (defined?(Redis.current) && Redis.current) or fail RedisNotFound, 'Redis not configured.'
19
19
  end
20
20
 
21
- def self.allow_class_method_in_queries(klass, method)
22
- (configuration.allowed_class_methods_in_queries[klass.to_s] ||= Set.new) << method.to_sym
21
+ def self.allow_class_method_in_queries(klass, method, arity = nil)
22
+ (configuration.allowed_class_methods_in_queries[klass.to_s] ||= {})[method.to_sym] = arity
23
23
  end
24
24
  end
25
25
 
26
26
  require_relative 'services/version'
27
27
  require_relative 'services/logger/file'
28
28
  require_relative 'services/logger/redis'
29
- begin
30
- require_relative 'services/asyncable'
31
- rescue Services::BackgroundProcessorNotFound
32
- end
29
+ require_relative 'services/asyncable'
33
30
  require_relative 'services/modules/call_logger'
34
31
  require_relative 'services/modules/exception_wrapper'
35
32
  require_relative 'services/modules/object_class'
@@ -1,13 +1,6 @@
1
1
  require 'active_support/concern'
2
2
  require 'global_id'
3
3
 
4
- begin
5
- require 'sidekiq'
6
- require 'sidekiq/api'
7
- rescue LoadError
8
- raise Services::BackgroundProcessorNotFound
9
- end
10
-
11
4
  module Services
12
5
  module Asyncable
13
6
  extend ActiveSupport::Concern
@@ -15,7 +8,26 @@ module Services
15
8
  ASYNC_METHOD_SUFFIXES = %i(async in at).freeze
16
9
 
17
10
  included do
18
- include Sidekiq::Worker
11
+ sidekiq_loaded = false
12
+
13
+ begin
14
+ require 'sidekiq'
15
+ require 'sidekiq/api'
16
+ rescue LoadError
17
+ else
18
+ include Sidekiq::Worker
19
+ sidekiq_loaded = true
20
+ end
21
+
22
+ unless sidekiq_loaded
23
+ begin
24
+ require 'sucker_punch'
25
+ rescue LoadError
26
+ raise Services::NoBackgroundProcessorFound
27
+ else
28
+ include SuckerPunch::Job
29
+ end
30
+ end
19
31
  end
20
32
 
21
33
  module ClassMethods
@@ -33,19 +45,22 @@ module Services
33
45
  args = args.map do |arg|
34
46
  GlobalID::Locator.locate(arg) || arg
35
47
  end
36
- # If the `call` method takes any kwargs and the last argument is a hash, symbolize the hash keys,
37
- # otherwise they won't be recognized as kwards when splatted.
38
- # Since the arguments to `perform` are serialized to the database before Sidekiq picks them up,
39
- # symbol keys are converted to strings.
48
+
40
49
  call_method = method(:call)
50
+
41
51
  # Find the first class that inherits from `Services::Base`.
42
52
  while !(call_method.owner < Services::Base)
43
53
  call_method = call_method.super_method
44
54
  end
45
- if call_method.parameters.map(&:first).grep(/\Akey/).any? && args.last.is_a?(Hash)
46
- args.last.symbolize_keys!
55
+
56
+ # If the `call` method takes any kwargs and the last argument is a hash, pass them to the method as kwargs.
57
+ kwargs = if call_method.parameters.map(&:first).grep(/\Akey/).any? && args.last.is_a?(Hash)
58
+ args.pop.symbolize_keys
59
+ else
60
+ {}
47
61
  end
48
- call *args
62
+
63
+ call *args, **kwargs
49
64
  end
50
65
  end
51
66
  end
data/lib/services/base.rb CHANGED
@@ -11,7 +11,10 @@ module Services
11
11
  def inherited(subclass)
12
12
  subclass.const_set :Error, Class.new(StandardError)
13
13
  subclass.public_send :include, Rails.application.routes.url_helpers if defined?(Rails)
14
- subclass.public_send :include, Asyncable if defined?(Asyncable)
14
+ begin
15
+ subclass.public_send :include, Asyncable
16
+ rescue Services::NoBackgroundProcessorFound
17
+ end
15
18
  subclass.public_send :prepend, CallLogger, ExceptionWrapper, UniquenessChecker
16
19
  end
17
20
 
@@ -22,7 +25,7 @@ module Services
22
25
  @id = SecureRandom.hex(6)
23
26
  end
24
27
 
25
- def call(*args)
28
+ def call(*args, **kwargs)
26
29
  raise NotImplementedError
27
30
  end
28
31
 
@@ -27,9 +27,9 @@ module Services
27
27
  end
28
28
  end
29
29
 
30
- def call(*args)
30
+ def call(*args, **kwargs)
31
31
  unless self.class.call_logging_disabled
32
- log "START with args: #{args}", caller: caller
32
+ log "START with args: #{args}, kwargs: #{kwargs}", caller: caller
33
33
  start = Time.now
34
34
  end
35
35
  begin
@@ -1,7 +1,7 @@
1
1
  module Services
2
2
  class Base
3
3
  module ExceptionWrapper
4
- def call(*args)
4
+ def call(*args, **kwargs)
5
5
  super
6
6
  rescue StandardError => e
7
7
  if e.class <= self.class::Error
@@ -14,7 +14,7 @@ module Services
14
14
  ).freeze
15
15
 
16
16
  MAX_RETRIES = 10.freeze
17
- ONE_DAY = (60 * 60 * 24).freeze
17
+ THIRTY_DAYS = (60 * 60 * 24 * 30).freeze
18
18
 
19
19
  def self.prepended(mod)
20
20
  mod.const_set :NotUniqueError, Class.new(mod::Error)
@@ -37,12 +37,12 @@ module Services
37
37
  else
38
38
  @_uniqueness_keys ||= []
39
39
  @_uniqueness_keys << new_uniqueness_key
40
- Services.redis.setex new_uniqueness_key, ONE_DAY, @id
40
+ Services.redis.setex new_uniqueness_key, THIRTY_DAYS, @id
41
41
  true
42
42
  end
43
43
  end
44
44
 
45
- def call(*args)
45
+ def call(*args, **kwargs)
46
46
  @_service_args = args
47
47
  super
48
48
  rescue self.class::NotUniqueError => e
@@ -103,7 +103,7 @@ module Services
103
103
  end
104
104
 
105
105
  def increase_error_count
106
- Services.redis.setex error_count_key, retry_delay + ONE_DAY, error_count + 1
106
+ Services.redis.setex error_count_key, retry_delay + THIRTY_DAYS, error_count + 1
107
107
  end
108
108
 
109
109
  def uniqueness_key(args)
@@ -71,8 +71,10 @@ module Services
71
71
  end
72
72
 
73
73
  conditions.each do |k, v|
74
- if (Services.configuration.allowed_class_methods_in_queries[object_class.to_s] || []).include?(k)
75
- case object_class.method(k).arity
74
+ allowed_class_methods = Services.configuration.allowed_class_methods_in_queries[object_class.to_s]
75
+ if allowed_class_methods&.key?(k)
76
+ arity = allowed_class_methods[k] || object_class.method(k).arity
77
+ case arity
76
78
  when 0
77
79
  unless v == true
78
80
  raise ArgumentError, "Method #{k} of class #{self} takes no arguments, so `true` must be passed as the value for this param, not #{v} (#{v.class})."
@@ -1,3 +1,3 @@
1
1
  module Services
2
- VERSION = '7.2.0'.freeze
2
+ VERSION = '8.0.0'.freeze
3
3
  end
data/services.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |gem|
11
11
  gem.email = 'manuel@krautcomputing.com'
12
12
  gem.summary = 'A nifty service layer for your Rails app'
13
13
  gem.description = 'A nifty service layer for your Rails app'
14
- gem.homepage = 'http://krautcomputing.github.io/services'
14
+ gem.homepage = 'http://manuelmeurer.github.io/services'
15
15
  gem.license = 'MIT'
16
16
  gem.required_ruby_version = '>= 2.2.5'
17
17
  gem.files = `git ls-files`.split($/)
@@ -81,14 +81,14 @@ module Services
81
81
  end
82
82
 
83
83
  class EmptyService < Services::Base
84
- def call(*args)
84
+ def call(*args, **kwargs)
85
85
  end
86
86
  end
87
87
 
88
88
  class EmptyServiceWithoutCallLogging < Services::Base
89
89
  disable_call_logging
90
90
 
91
- def call(*args)
91
+ def call(*args, **kwargs)
92
92
  end
93
93
  end
94
94
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: services
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.2.0
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manuel Meurer
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-21 00:00:00.000000000 Z
11
+ date: 2021-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -193,9 +193,9 @@ files:
193
193
  - LICENSE.txt
194
194
  - README.md
195
195
  - Rakefile
196
- - gemfiles/rails_4.2.gemfile
197
- - gemfiles/rails_5.0.gemfile
198
- - gemfiles/rails_5.1.gemfile
196
+ - gemfiles/rails_5.2.gemfile
197
+ - gemfiles/rails_6.0.gemfile
198
+ - gemfiles/rails_6.1.gemfile
199
199
  - lib/services.rb
200
200
  - lib/services/asyncable.rb
201
201
  - lib/services/base.rb
@@ -227,11 +227,11 @@ files:
227
227
  - spec/support/redis-server
228
228
  - spec/support/shared.rb
229
229
  - spec/support/test_services.rb
230
- homepage: http://krautcomputing.github.io/services
230
+ homepage: http://manuelmeurer.github.io/services
231
231
  licenses:
232
232
  - MIT
233
233
  metadata: {}
234
- post_install_message:
234
+ post_install_message:
235
235
  rdoc_options: []
236
236
  require_paths:
237
237
  - lib
@@ -246,8 +246,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
246
246
  - !ruby/object:Gem::Version
247
247
  version: '0'
248
248
  requirements: []
249
- rubygems_version: 3.0.4
250
- signing_key:
249
+ rubygems_version: 3.2.11
250
+ signing_key:
251
251
  specification_version: 4
252
252
  summary: A nifty service layer for your Rails app
253
253
  test_files: