activecrew 0.1.4 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a45d0ac6c7ba04c2eee3d07464b4a33eb8929527
4
- data.tar.gz: d451a7a7ada0b52d1cab74db53f5545f0b48f1bc
2
+ SHA256:
3
+ metadata.gz: abcdf07af76ef64766aba9c33476f500568662cd82129c47a988c1973de50b40
4
+ data.tar.gz: d0a818a0e3e4f6bb77f22dd23ea1b2c406f34b6f67568db5c445c9085e5db537
5
5
  SHA512:
6
- metadata.gz: fdea905f162d86ff05391ed80582cbfaa5c092f2a2741847a65f0dc73273d63bfb61f987f614cba8b43d0466374ec0ebbffe09ea56d0939723a29669bcf51af7
7
- data.tar.gz: 487f78c9e5cc76199a3f0841ad956f4c38aaa7170cc2a6cda9aed1e0dc6ccbd656e66dcd437afe897ab71201fa3e1b45c7f57c6f4c215ab9c8dedf983ffac01c
6
+ metadata.gz: 04c5f0e527ccb5d71d81a72b4a81a13ee3c8c35e655205a1970cac1da344426aa499d9d1c6569ab01acac388f92f889732c0824cdcd5f1144c4c7cc406a5bc33
7
+ data.tar.gz: 8589ad620868591ea5298eaa15ac9f0f50a1040096a729804c9d41eccccbe020930e1549dd75e31b2381188147177259ad07d8b49938cd08d5d835a63f29e0ab
data/activecrew.gemspec CHANGED
@@ -17,10 +17,10 @@ Gem::Specification.new do |spec|
17
17
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
18
18
  spec.require_paths = ['lib']
19
19
 
20
- spec.add_development_dependency 'bundler', '~> 1.10'
21
- spec.add_development_dependency 'rake', '~> 10.0'
20
+ spec.add_development_dependency 'bundler', '>= 1.10'
21
+ spec.add_development_dependency 'rake', '>= 10.0'
22
22
  spec.add_development_dependency 'rspec'
23
- spec.add_development_dependency 'actionpack', '~> 4.0'
23
+ spec.add_development_dependency 'actionpack', '>= 4.0'
24
24
 
25
- spec.add_dependency 'activesupport', '~> 4.0'
25
+ spec.add_dependency 'activesupport', '>= 4.0'
26
26
  end
@@ -5,14 +5,26 @@ module ActiveCrew
5
5
  def size
6
6
  0
7
7
  end
8
- end
9
8
 
10
- def self.enqueue(*args)
11
- ActiveCrew::Backends.dequeue *args
9
+ def method_missing(method, *args, &block)
10
+ return unless respond_to? method
11
+
12
+ super method, *args, &block
13
+ end
12
14
  end
13
15
 
14
- def self.queue(command_name)
15
- Queue.new
16
+ class << self
17
+ def enqueue(*args)
18
+ ActiveCrew::Backends.dequeue *args
19
+ end
20
+
21
+ def queue(command_name)
22
+ Queue.new
23
+ end
24
+
25
+ def context
26
+ {}
27
+ end
16
28
  end
17
29
  end
18
30
  end
@@ -4,10 +4,10 @@ module ActiveCrew
4
4
  include Sidekiq::Worker
5
5
 
6
6
  class << self
7
- def enqueue(*args)
7
+ def enqueue(name, invoker, context)
8
8
  Sidekiq::Client.push 'class' => self,
9
- 'queue' => queue_name(args.first),
10
- 'args' => args
9
+ 'queue' => queue_name(name),
10
+ 'args' => [YAML.dump([name, invoker, normalize(context)])]
11
11
  end
12
12
 
13
13
  def queue_name(command_name)
@@ -17,10 +17,20 @@ module ActiveCrew
17
17
  def queue(command_name)
18
18
  Sidekiq::Queue.new queue_name command_name
19
19
  end
20
+
21
+ def context
22
+ Sidekiq::Processor::WORKER_STATE.dup[Sidekiq::Logging.tid]
23
+ end
24
+
25
+ private
26
+
27
+ def normalize(context)
28
+ context.merge(options: context.fetch(:options, {}).to_hash).to_hash
29
+ end
20
30
  end
21
31
 
22
- def perform(*args)
23
- ActiveCrew::Backends.dequeue *args
32
+ def perform(context)
33
+ ActiveCrew::Backends.dequeue *YAML.load(context)
24
34
  end
25
35
  end
26
36
  end
@@ -17,8 +17,15 @@ module ActiveCrew
17
17
  end
18
18
 
19
19
  def dequeue(name, invoker, *args)
20
- command = create_command name, deserialize(invoker), *args
21
- command.execute if command.can_execute?
20
+ invoker = deserialize invoker
21
+ return if invoker.blank?
22
+
23
+ command name, invoker, *args
24
+ end
25
+
26
+ def command(name, invoker, *args)
27
+ command = create_command name, invoker, *args
28
+ command.execute if command && command.can_execute?
22
29
  end
23
30
 
24
31
  private
@@ -38,7 +45,7 @@ module ActiveCrew
38
45
  def create_command(name, invoker, *args)
39
46
  "#{name.classify}Command".constantize.new invoker, *args
40
47
  rescue NameError
41
- raise ArgumentError, "Unsupported command #{name} for active command."
48
+ raise ArgumentError, "Unsupported command #{name} for active command." unless ActiveCrew.configuration.silent
42
49
  end
43
50
  end
44
51
  end
@@ -24,6 +24,7 @@ module ActiveCrew
24
24
  prepend Measurable
25
25
  prepend Respondable
26
26
  prepend Authorizable
27
+ prepend Lockable
27
28
 
28
29
  include Commandable
29
30
 
@@ -1,17 +1,9 @@
1
1
  module ActiveCrew
2
- class AuthorizationError < Exception; end
3
-
4
2
  module Authorizable
5
3
  extend ActiveSupport::Concern
6
4
 
7
- def execute
8
- raise AuthorizationError unless can_execute?
9
-
10
- super
11
- end
12
-
13
5
  def can_execute?
14
- invoker.can? name, options
6
+ invoker.can? name, self
15
7
  end
16
8
  end
17
9
  end
@@ -0,0 +1,40 @@
1
+ module ActiveCrew
2
+ module Lockable
3
+ def execute
4
+ super unless locked?
5
+ end
6
+
7
+ def locked?
8
+ options = context.delete :locker
9
+ return false if options.blank?
10
+
11
+ model = deserialize_locker options
12
+ return true if model.blank?
13
+
14
+ model.locker != options[:value]
15
+ end
16
+
17
+ def lock(model)
18
+ return unless model
19
+
20
+ locker_was = context[:locker]
21
+ context[:locker] = serialize_locker model
22
+
23
+ yield
24
+
25
+ context[:locker] = locker_was
26
+ end
27
+
28
+ protected
29
+
30
+ def serialize_locker(model)
31
+ { class: model.class.to_s,
32
+ id: model.id.to_s,
33
+ value: model.lock }
34
+ end
35
+
36
+ def deserialize_locker(options)
37
+ options[:class].safe_constantize&.find options[:id]
38
+ end
39
+ end
40
+ end
@@ -2,8 +2,9 @@ module ActiveCrew
2
2
  class CommandError < Exception; end
3
3
 
4
4
  module Respondable
5
- def respond_with(model)
6
- Responders.respond_with name, invoker, context, model
5
+ def respond_with(model, options = {})
6
+ name = options.delete(:name) || self.name
7
+ Responders.respond_with name, invoker, context.merge(options), model
7
8
  end
8
9
 
9
10
  def respond_fail(*args)
@@ -12,8 +13,6 @@ module ActiveCrew
12
13
 
13
14
  def execute
14
15
  super
15
- rescue Interrupt
16
- raise
17
16
  rescue CommandError
18
17
  respond_with $ERROR_INFO
19
18
  end
@@ -1,10 +1,11 @@
1
1
  module ActiveCrew
2
2
  class Configuration
3
- attr_accessor :responder, :backend, :measurer
3
+ attr_accessor :responder, :backend, :measurer, :silent
4
4
 
5
5
  def initialize
6
6
  @responder = :inline
7
7
  @backend = :inline
8
+ @silent = false
8
9
  end
9
10
  end
10
11
  end
@@ -1,10 +1,14 @@
1
1
  module ActiveCrew
2
2
  module Extender
3
- def command(name, options)
3
+ def command_context
4
+ @command_context ||= {}
5
+ end
6
+
7
+ def command(name, options = {})
4
8
  context = { options: options }
9
+ context[:session] = request.headers['x-session-token'] if respond_to? :request
5
10
 
6
- ActiveCrew::Responders.init context, request
7
- ActiveCrew::Backends.enqueue name, current_user, context
11
+ ActiveCrew::Backends.enqueue name, current_user, context.merge(command_context)
8
12
  end
9
13
  end
10
14
  end
@@ -1,25 +1,20 @@
1
1
  module ActiveCrew
2
2
  module Responders
3
- # FayeResponderError class.
4
- class FayeResponderError < Exception; end
5
-
6
- # FayeConnectionError class.
7
- class FayeConnectionError < Exception; end
8
-
9
3
  # ActiveCrew Faye responder.
10
4
  module FayeResponder
5
+
6
+ # FayeResponderError class.
7
+ class FayeResponderError < Exception; end
8
+
11
9
  module_function
12
10
 
13
11
  MAX_RETRIES = 5
14
12
 
15
- def init(context, request)
16
- context[:session] = request.headers['x-session-token']
17
- end
18
-
19
13
  # Respond with faye
20
- def respond(name, invoker, context, model)
21
- request channel: channel(invoker),
22
- data: payload(name, invoker, context, model),
14
+ # Respond with faye
15
+ def respond(name, invoker, options, model)
16
+ request channel: channel(invoker, options),
17
+ data: payload(name, invoker, options, model),
23
18
  ext: { publish_key: config[:publish_key] }
24
19
  end
25
20
 
@@ -30,27 +25,28 @@ module ActiveCrew
30
25
  validate RestClient.post url, message.to_json, header
31
26
  rescue FayeResponderError
32
27
  retries += 1
33
- raise FayeConnectionError $ERROR_INFO unless retries < MAX_RETRIES
34
28
 
35
- retry
36
- rescue FayeConnectionError
37
- Rails.logger.fatal $ERROR_INFO.message
29
+ retry if retries < MAX_RETRIES
30
+
31
+ Rails.logger.fatal "[#{self}] #{$ERROR_INFO.message}"
32
+ rescue Exception
33
+ Rails.logger.fatal "[#{self}] #{$ERROR_INFO.message}"
38
34
  end
39
35
  end
40
36
 
41
37
  # @return Invoker channel name
42
- def channel(invoker)
43
- "/#{invoker.class.to_s.underscore}/#{invoker.id}"
38
+ def channel(invoker, options)
39
+ options[:channel] || "/#{invoker.class.to_s.underscore}/#{invoker.id}"
44
40
  end
45
41
 
46
42
  # @return Faye request payload
47
- def payload(name, invoker, context, model)
43
+ def payload(name, invoker, options, model)
48
44
  {
49
45
  invoker: serialize_invoker(invoker),
50
- session: context[:session],
46
+ session: options[:session],
51
47
  command: name,
52
48
  status: status(model),
53
- response: serialize(model)
49
+ response: serialize(model, options)
54
50
  }
55
51
  end
56
52
 
@@ -62,15 +58,18 @@ module ActiveCrew
62
58
  def serialize(model, options = {})
63
59
  return { base: model.message } if model.is_a? CommandError
64
60
 
65
- if model.is_a?(Array) || model.errors.empty?
66
- ActiveModelSerializers::SerializableResource.new(model, options).serializable_hash
61
+ if model.is_a?(Array) || !model.respond_to?(:errors) || model.errors.empty?
62
+ # SerializableResource need only symbolize options
63
+ options = options.slice(:serializer, :each_serializer).symbolize_keys
64
+ resource = ActiveModelSerializers::SerializableResource.new model, options
65
+ resource.adapter.respond_to?(:serializable_hash) ? resource.serializable_hash : model
67
66
  else
68
- ActiveModelSerializers::SerializableResource.new(model.errors, options.merge(root: 'errors')).serializable_hash[:errors]
67
+ ActiveModelSerializers::SerializableResource.new(model.errors, root: 'errors').serializable_hash[:errors]
69
68
  end
70
69
  end
71
70
 
72
71
  def status(model)
73
- model.is_a?(Array) || !model.is_a?(CommandError) && model.valid? ? :success : :failure
72
+ !model.is_a?(CommandError) && (!model.respond_to?(:errors) || model.errors.empty?) ? :success : :failure
74
73
  end
75
74
 
76
75
  # @return Faye request header
@@ -91,7 +90,7 @@ module ActiveCrew
91
90
  end
92
91
 
93
92
  def url
94
- "http://#{config[:host]}/faye"
93
+ "#{config[:ssl] ? 'https' : 'http'}://#{config[:host]}/faye"
95
94
  end
96
95
 
97
96
  def config
@@ -12,10 +12,6 @@ module ActiveCrew
12
12
  raise ArgumentError, "Unsupported responder #{responder} for active command."
13
13
  end
14
14
 
15
- def init(context, request)
16
- default.init(context, request) if default.respond_to? :init
17
- end
18
-
19
15
  def respond_with(name, invoker, context, model)
20
16
  default.respond name, invoker, context, model
21
17
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveCrew
2
- VERSION = '0.1.4'
2
+ VERSION = '0.1.5'
3
3
  end
data/lib/active_crew.rb CHANGED
@@ -7,6 +7,7 @@ require 'active_crew/concerns/authorizable'
7
7
  require 'active_crew/concerns/chainable'
8
8
  require 'active_crew/concerns/commandable'
9
9
  require 'active_crew/concerns/combinable'
10
+ require 'active_crew/concerns/lockable'
10
11
  require 'active_crew/concerns/respondable'
11
12
  require 'active_crew/concerns/measurable'
12
13
  require 'active_crew/concerns/validatable'
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activecrew
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max Kazarin
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-17 00:00:00.000000000 Z
11
+ date: 2022-06-30 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
19
  version: '1.10'
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
26
  version: '1.10'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
@@ -56,28 +56,28 @@ dependencies:
56
56
  name: actionpack
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '4.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '4.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: activesupport
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '4.0'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '4.0'
83
83
  description: Steroid command pattern.
@@ -105,6 +105,7 @@ files:
105
105
  - lib/active_crew/concerns/chainable.rb
106
106
  - lib/active_crew/concerns/combinable.rb
107
107
  - lib/active_crew/concerns/commandable.rb
108
+ - lib/active_crew/concerns/lockable.rb
108
109
  - lib/active_crew/concerns/measurable.rb
109
110
  - lib/active_crew/concerns/respondable.rb
110
111
  - lib/active_crew/concerns/validatable.rb
@@ -119,7 +120,7 @@ homepage: https://github.com/maxkazar/activecrew
119
120
  licenses:
120
121
  - MIT
121
122
  metadata: {}
122
- post_install_message:
123
+ post_install_message:
123
124
  rdoc_options: []
124
125
  require_paths:
125
126
  - lib
@@ -134,9 +135,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
135
  - !ruby/object:Gem::Version
135
136
  version: '0'
136
137
  requirements: []
137
- rubyforge_project:
138
- rubygems_version: 2.6.7
139
- signing_key:
138
+ rubygems_version: 3.3.16
139
+ signing_key:
140
140
  specification_version: 4
141
141
  summary: Steroid command pattern.
142
142
  test_files: []