activecrew 0.1.4 → 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
- 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: []