activecrew 0.1.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 +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +6 -0
- data/activecrew.gemspec +26 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/active_crew.rb +46 -0
- data/lib/active_crew/backends.rb +45 -0
- data/lib/active_crew/backends/inline_backend.rb +19 -0
- data/lib/active_crew/backends/sidekiq_backend.rb +27 -0
- data/lib/active_crew/base.rb +50 -0
- data/lib/active_crew/concerns/authorizable.rb +17 -0
- data/lib/active_crew/concerns/chainable.rb +35 -0
- data/lib/active_crew/concerns/combinable.rb +27 -0
- data/lib/active_crew/concerns/commandable.rb +11 -0
- data/lib/active_crew/concerns/measurable.rb +30 -0
- data/lib/active_crew/concerns/respondable.rb +21 -0
- data/lib/active_crew/concerns/validatable.rb +15 -0
- data/lib/active_crew/configuration.rb +10 -0
- data/lib/active_crew/extender.rb +12 -0
- data/lib/active_crew/responders.rb +30 -0
- data/lib/active_crew/responders/faye_responder.rb +109 -0
- data/lib/active_crew/responders/inline_responder.rb +9 -0
- data/lib/active_crew/version.rb +3 -0
- data/lib/activecrew.rb +1 -0
- metadata +142 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a45d0ac6c7ba04c2eee3d07464b4a33eb8929527
|
4
|
+
data.tar.gz: d451a7a7ada0b52d1cab74db53f5545f0b48f1bc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fdea905f162d86ff05391ed80582cbfaa5c092f2a2741847a65f0dc73273d63bfb61f987f614cba8b43d0466374ec0ebbffe09ea56d0939723a29669bcf51af7
|
7
|
+
data.tar.gz: 487f78c9e5cc76199a3f0841ad956f4c38aaa7170cc2a6cda9aed1e0dc6ccbd656e66dcd437afe897ab71201fa3e1b45c7f57c6f4c215ab9c8dedf983ffac01c
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Max Kazarin
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# ActiveCrew
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/activecrew)
|
4
|
+
[](https://codeclimate.com/github/maxkazar/activecrew)
|
5
|
+
[](https://travis-ci.org/maxkazar/activecrew)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'activecrew'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install activecrew
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
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.
|
30
|
+
|
31
|
+
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).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/maxkazar/activecrew.
|
36
|
+
|
37
|
+
|
38
|
+
## License
|
39
|
+
|
40
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
41
|
+
|
data/Rakefile
ADDED
data/activecrew.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'active_crew/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'activecrew'
|
8
|
+
spec.version = ActiveCrew::VERSION
|
9
|
+
spec.authors = ['Max Kazarin']
|
10
|
+
spec.email = ['maxkazargm@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = %q{Steroid command pattern.}
|
13
|
+
spec.description = %q{Steroid command pattern.}
|
14
|
+
spec.homepage = 'https://github.com/maxkazar/activecrew'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
21
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
22
|
+
spec.add_development_dependency 'rspec'
|
23
|
+
spec.add_development_dependency 'actionpack', '~> 4.0'
|
24
|
+
|
25
|
+
spec.add_dependency 'activesupport', '~> 4.0'
|
26
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "activecrew"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/lib/active_crew.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require 'active_support/all'
|
4
|
+
require 'active_crew/version'
|
5
|
+
require 'active_crew/configuration'
|
6
|
+
require 'active_crew/concerns/authorizable'
|
7
|
+
require 'active_crew/concerns/chainable'
|
8
|
+
require 'active_crew/concerns/commandable'
|
9
|
+
require 'active_crew/concerns/combinable'
|
10
|
+
require 'active_crew/concerns/respondable'
|
11
|
+
require 'active_crew/concerns/measurable'
|
12
|
+
require 'active_crew/concerns/validatable'
|
13
|
+
require 'active_crew/base'
|
14
|
+
require 'active_crew/backends'
|
15
|
+
require 'active_crew/responders'
|
16
|
+
|
17
|
+
require 'active_crew/extender' if defined? ActionController
|
18
|
+
|
19
|
+
module ActiveCrew
|
20
|
+
class << self
|
21
|
+
# Getter for shared global objects
|
22
|
+
attr_reader :configuration
|
23
|
+
|
24
|
+
# Returns the global [Configuration](ActiveCrew/Configuration) object.
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# ActiveCrew.configuration.responder = :pusher
|
28
|
+
def configuration
|
29
|
+
@configuration ||= ActiveCrew::Configuration.new
|
30
|
+
end
|
31
|
+
|
32
|
+
# Yields the global configuration to a block.
|
33
|
+
# @yield [Configuration] global configuration
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# ActiveCrew.configure do |config|
|
37
|
+
# config.responder = :fayer
|
38
|
+
# end
|
39
|
+
def configure
|
40
|
+
yield configuration if block_given?
|
41
|
+
|
42
|
+
Backends.create
|
43
|
+
Responders.create
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ActiveCrew
|
2
|
+
module Backends
|
3
|
+
autoload :InlineBackend, 'active_crew/backends/inline_backend'
|
4
|
+
autoload :SidekiqBackend, 'active_crew/backends/sidekiq_backend'
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_reader :default
|
8
|
+
|
9
|
+
def create
|
10
|
+
@default = "ActiveCrew::Backends::#{backend.to_s.classify}Backend".constantize
|
11
|
+
rescue NameError
|
12
|
+
raise ArgumentError, "Unsupported backend #{backend} for active command."
|
13
|
+
end
|
14
|
+
|
15
|
+
def enqueue(name, invoker, *args)
|
16
|
+
default.enqueue name, serialize(invoker), *args
|
17
|
+
end
|
18
|
+
|
19
|
+
def dequeue(name, invoker, *args)
|
20
|
+
command = create_command name, deserialize(invoker), *args
|
21
|
+
command.execute if command.can_execute?
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def backend
|
27
|
+
ActiveCrew.configuration.backend
|
28
|
+
end
|
29
|
+
|
30
|
+
def serialize(invoker)
|
31
|
+
[invoker.class.name, invoker.id.to_s]
|
32
|
+
end
|
33
|
+
|
34
|
+
def deserialize(invoker)
|
35
|
+
invoker[0].constantize.find invoker[1]
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_command(name, invoker, *args)
|
39
|
+
"#{name.classify}Command".constantize.new invoker, *args
|
40
|
+
rescue NameError
|
41
|
+
raise ArgumentError, "Unsupported command #{name} for active command."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveCrew
|
2
|
+
module Backends
|
3
|
+
class InlineBackend
|
4
|
+
class Queue
|
5
|
+
def size
|
6
|
+
0
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.enqueue(*args)
|
11
|
+
ActiveCrew::Backends.dequeue *args
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.queue(command_name)
|
15
|
+
Queue.new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ActiveCrew
|
2
|
+
module Backends
|
3
|
+
class SidekiqBackend
|
4
|
+
include Sidekiq::Worker
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def enqueue(*args)
|
8
|
+
Sidekiq::Client.push 'class' => self,
|
9
|
+
'queue' => queue_name(args.first),
|
10
|
+
'args' => args
|
11
|
+
end
|
12
|
+
|
13
|
+
def queue_name(command_name)
|
14
|
+
command_name[/^(.*)\/[^\/]*$/, 1].underscore.gsub(/\//, '_')
|
15
|
+
end
|
16
|
+
|
17
|
+
def queue(command_name)
|
18
|
+
Sidekiq::Queue.new queue_name command_name
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def perform(*args)
|
23
|
+
ActiveCrew::Backends.dequeue *args
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module ActiveCrew
|
2
|
+
|
3
|
+
# Sidekiq Command class. Implements command pattern for Sidekiq.
|
4
|
+
# Helps to deconstruct application into micro services with command interface.
|
5
|
+
#
|
6
|
+
# Command class file structure with two micro services (mailer and users):
|
7
|
+
#
|
8
|
+
# app
|
9
|
+
# commands
|
10
|
+
# mailer
|
11
|
+
# deliver_command.rb
|
12
|
+
# users
|
13
|
+
# create_command.rb
|
14
|
+
#
|
15
|
+
# Command queues will be the following:
|
16
|
+
#
|
17
|
+
# mailer
|
18
|
+
# users
|
19
|
+
#
|
20
|
+
class Base
|
21
|
+
prepend Chainable
|
22
|
+
prepend Combinable
|
23
|
+
prepend Validatable
|
24
|
+
prepend Measurable
|
25
|
+
prepend Respondable
|
26
|
+
prepend Authorizable
|
27
|
+
|
28
|
+
include Commandable
|
29
|
+
|
30
|
+
attr_reader :invoker, :options, :context
|
31
|
+
|
32
|
+
def initialize(invoker, context = {})
|
33
|
+
@invoker = invoker
|
34
|
+
# Should only symbolize key for
|
35
|
+
@context = ActiveSupport::HashWithIndifferentAccess.new context
|
36
|
+
@options = @context[:options] || {}
|
37
|
+
end
|
38
|
+
|
39
|
+
def name
|
40
|
+
@name ||= self.class.name.underscore.gsub(/_command/, '')
|
41
|
+
end
|
42
|
+
|
43
|
+
def execute
|
44
|
+
perform
|
45
|
+
end
|
46
|
+
|
47
|
+
def perform
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ActiveCrew
|
2
|
+
class AuthorizationError < Exception; end
|
3
|
+
|
4
|
+
module Authorizable
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
def execute
|
8
|
+
raise AuthorizationError unless can_execute?
|
9
|
+
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def can_execute?
|
14
|
+
invoker.can? name, options
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ActiveCrew
|
2
|
+
module Chainable
|
3
|
+
def chain
|
4
|
+
@chain ||= @context[:chain] || []
|
5
|
+
end
|
6
|
+
|
7
|
+
def commands(*args)
|
8
|
+
options = args.extract_options!
|
9
|
+
add_to_chain args
|
10
|
+
execute_chain options
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute
|
14
|
+
super
|
15
|
+
execute_chain
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def add_to_chain(commands)
|
21
|
+
chain.concat commands
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute_chain(options = nil)
|
25
|
+
return unless chain.present?
|
26
|
+
|
27
|
+
name = chain.shift
|
28
|
+
if name.is_a? Array
|
29
|
+
name.each { |name| command name, options }
|
30
|
+
else
|
31
|
+
command name, options, chain: chain
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ActiveCrew
|
2
|
+
# Combinable behavior helps to combine command executions into one command execution
|
3
|
+
module Combinable
|
4
|
+
def execute
|
5
|
+
super
|
6
|
+
execute_combine_commands
|
7
|
+
end
|
8
|
+
|
9
|
+
def combine_command(name, options = {})
|
10
|
+
combine_command_options = combine_commands[name] ||= {}
|
11
|
+
options.each do |key, value|
|
12
|
+
combine_command_value = combine_command_options[key] ||= []
|
13
|
+
combine_command_value << value unless combine_command_value.include? value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def combine_commands
|
18
|
+
@combine_commands ||= {}
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def execute_combine_commands
|
24
|
+
combine_commands.each { |name, options| command name, options }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ActiveCrew
|
2
|
+
class MeasurerError < Exception; end
|
3
|
+
|
4
|
+
module Measurable
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def execute
|
10
|
+
started_at = Time.current
|
11
|
+
|
12
|
+
super
|
13
|
+
|
14
|
+
measurer.measure self, Time.current - started_at if measurer
|
15
|
+
end
|
16
|
+
|
17
|
+
def has_measurer?
|
18
|
+
measurer.present?
|
19
|
+
end
|
20
|
+
|
21
|
+
def measurer
|
22
|
+
return @measurer if defined? @measurer
|
23
|
+
|
24
|
+
measurer_name = ActiveCrew.configuration.measurer
|
25
|
+
@measurer = measurer_name && measurer_name.to_s.classify.constantize
|
26
|
+
rescue NameError
|
27
|
+
raise MeasurerError, "Unsupported measurer #{measurer_name} for active command."
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActiveCrew
|
2
|
+
class CommandError < Exception; end
|
3
|
+
|
4
|
+
module Respondable
|
5
|
+
def respond_with(model)
|
6
|
+
Responders.respond_with name, invoker, context, model
|
7
|
+
end
|
8
|
+
|
9
|
+
def respond_fail(*args)
|
10
|
+
fail CommandError, I18n.t(*args)
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute
|
14
|
+
super
|
15
|
+
rescue Interrupt
|
16
|
+
raise
|
17
|
+
rescue CommandError
|
18
|
+
respond_with $ERROR_INFO
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ActiveCrew
|
2
|
+
module Extender
|
3
|
+
def command(name, options)
|
4
|
+
context = { options: options }
|
5
|
+
|
6
|
+
ActiveCrew::Responders.init context, request
|
7
|
+
ActiveCrew::Backends.enqueue name, current_user, context
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
ActionController::Base.include ActiveCrew::Extender
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ActiveCrew
|
2
|
+
module Responders
|
3
|
+
autoload :InlineResponder, 'active_crew/responders/inline_responder'
|
4
|
+
autoload :FayeResponder, 'active_crew/responders/faye_responder'
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_reader :default
|
8
|
+
|
9
|
+
def create
|
10
|
+
@default = "ActiveCrew::Responders::#{responder.to_s.classify}Responder".constantize
|
11
|
+
rescue NameError
|
12
|
+
raise ArgumentError, "Unsupported responder #{responder} for active command."
|
13
|
+
end
|
14
|
+
|
15
|
+
def init(context, request)
|
16
|
+
default.init(context, request) if default.respond_to? :init
|
17
|
+
end
|
18
|
+
|
19
|
+
def respond_with(name, invoker, context, model)
|
20
|
+
default.respond name, invoker, context, model
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def responder
|
26
|
+
ActiveCrew.configuration.responder
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module ActiveCrew
|
2
|
+
module Responders
|
3
|
+
# FayeResponderError class.
|
4
|
+
class FayeResponderError < Exception; end
|
5
|
+
|
6
|
+
# FayeConnectionError class.
|
7
|
+
class FayeConnectionError < Exception; end
|
8
|
+
|
9
|
+
# ActiveCrew Faye responder.
|
10
|
+
module FayeResponder
|
11
|
+
module_function
|
12
|
+
|
13
|
+
MAX_RETRIES = 5
|
14
|
+
|
15
|
+
def init(context, request)
|
16
|
+
context[:session] = request.headers['x-session-token']
|
17
|
+
end
|
18
|
+
|
19
|
+
# Respond with faye
|
20
|
+
def respond(name, invoker, context, model)
|
21
|
+
request channel: channel(invoker),
|
22
|
+
data: payload(name, invoker, context, model),
|
23
|
+
ext: { publish_key: config[:publish_key] }
|
24
|
+
end
|
25
|
+
|
26
|
+
def request(message)
|
27
|
+
retries = 0
|
28
|
+
|
29
|
+
begin
|
30
|
+
validate RestClient.post url, message.to_json, header
|
31
|
+
rescue FayeResponderError
|
32
|
+
retries += 1
|
33
|
+
raise FayeConnectionError $ERROR_INFO unless retries < MAX_RETRIES
|
34
|
+
|
35
|
+
retry
|
36
|
+
rescue FayeConnectionError
|
37
|
+
Rails.logger.fatal $ERROR_INFO.message
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return Invoker channel name
|
42
|
+
def channel(invoker)
|
43
|
+
"/#{invoker.class.to_s.underscore}/#{invoker.id}"
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return Faye request payload
|
47
|
+
def payload(name, invoker, context, model)
|
48
|
+
{
|
49
|
+
invoker: serialize_invoker(invoker),
|
50
|
+
session: context[:session],
|
51
|
+
command: name,
|
52
|
+
status: status(model),
|
53
|
+
response: serialize(model)
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def serialize_invoker(invoker)
|
58
|
+
serialize invoker, serializer: "#{invoker.class}::InvokerSerializer".constantize
|
59
|
+
end
|
60
|
+
|
61
|
+
# Serialize payload
|
62
|
+
def serialize(model, options = {})
|
63
|
+
return { base: model.message } if model.is_a? CommandError
|
64
|
+
|
65
|
+
if model.is_a?(Array) || model.errors.empty?
|
66
|
+
ActiveModelSerializers::SerializableResource.new(model, options).serializable_hash
|
67
|
+
else
|
68
|
+
ActiveModelSerializers::SerializableResource.new(model.errors, options.merge(root: 'errors')).serializable_hash[:errors]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def status(model)
|
73
|
+
model.is_a?(Array) || !model.is_a?(CommandError) && model.valid? ? :success : :failure
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return Faye request header
|
77
|
+
def header
|
78
|
+
{
|
79
|
+
'Content-Type' => 'application/json',
|
80
|
+
'Pragma' => 'no-cache',
|
81
|
+
'X-Requested-With' => 'XMLHttpRequest'
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
# Validate faye response
|
86
|
+
def validate(response)
|
87
|
+
fail FayeResponderError, response.code unless response.code == 200
|
88
|
+
|
89
|
+
response = JSON.parse(response)[0].symbolize_keys
|
90
|
+
fail FayeResponderError, response[:error] unless response[:successful]
|
91
|
+
end
|
92
|
+
|
93
|
+
def url
|
94
|
+
"http://#{config[:host]}/faye"
|
95
|
+
end
|
96
|
+
|
97
|
+
def config
|
98
|
+
return @config if defined? @config
|
99
|
+
|
100
|
+
@config = YAML.load(ERB.new(File.new(config_path).read).result)[Rails.env]
|
101
|
+
@config = (@config || {}).symbolize_keys
|
102
|
+
end
|
103
|
+
|
104
|
+
def config_path
|
105
|
+
File.join(Rails.root, 'config', 'faye.yml')
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/lib/activecrew.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'active_crew'
|
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: activecrew
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Max Kazarin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-11-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: actionpack
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activesupport
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4.0'
|
83
|
+
description: Steroid command pattern.
|
84
|
+
email:
|
85
|
+
- maxkazargm@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".travis.yml"
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- activecrew.gemspec
|
97
|
+
- bin/console
|
98
|
+
- bin/setup
|
99
|
+
- lib/active_crew.rb
|
100
|
+
- lib/active_crew/backends.rb
|
101
|
+
- lib/active_crew/backends/inline_backend.rb
|
102
|
+
- lib/active_crew/backends/sidekiq_backend.rb
|
103
|
+
- lib/active_crew/base.rb
|
104
|
+
- lib/active_crew/concerns/authorizable.rb
|
105
|
+
- lib/active_crew/concerns/chainable.rb
|
106
|
+
- lib/active_crew/concerns/combinable.rb
|
107
|
+
- lib/active_crew/concerns/commandable.rb
|
108
|
+
- lib/active_crew/concerns/measurable.rb
|
109
|
+
- lib/active_crew/concerns/respondable.rb
|
110
|
+
- lib/active_crew/concerns/validatable.rb
|
111
|
+
- lib/active_crew/configuration.rb
|
112
|
+
- lib/active_crew/extender.rb
|
113
|
+
- lib/active_crew/responders.rb
|
114
|
+
- lib/active_crew/responders/faye_responder.rb
|
115
|
+
- lib/active_crew/responders/inline_responder.rb
|
116
|
+
- lib/active_crew/version.rb
|
117
|
+
- lib/activecrew.rb
|
118
|
+
homepage: https://github.com/maxkazar/activecrew
|
119
|
+
licenses:
|
120
|
+
- MIT
|
121
|
+
metadata: {}
|
122
|
+
post_install_message:
|
123
|
+
rdoc_options: []
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project:
|
138
|
+
rubygems_version: 2.6.7
|
139
|
+
signing_key:
|
140
|
+
specification_version: 4
|
141
|
+
summary: Steroid command pattern.
|
142
|
+
test_files: []
|