logux_rails 0.1.0 → 0.2.0

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/Appraisals +4 -0
  4. data/CHANGELOG.md +13 -0
  5. data/Gemfile +3 -0
  6. data/README.md +7 -2
  7. data/app/helpers/logux_helper.rb +1 -2
  8. data/config/routes.rb +1 -1
  9. data/lib/logux/{actions.rb → action.rb} +1 -1
  10. data/lib/logux/model/proxy.rb +1 -1
  11. data/lib/logux/model/updates_deprecator.rb +12 -8
  12. data/lib/logux/version.rb +1 -1
  13. data/lib/logux_rails.rb +22 -1
  14. data/lib/tasks/logux_tasks.rake +10 -37
  15. data/logux_rails.gemspec +3 -6
  16. metadata +14 -77
  17. data/app/controllers/logux_controller.rb +0 -41
  18. data/lib/logux.rb +0 -107
  19. data/lib/logux/action_caller.rb +0 -42
  20. data/lib/logux/action_controller.rb +0 -6
  21. data/lib/logux/add.rb +0 -37
  22. data/lib/logux/auth.rb +0 -6
  23. data/lib/logux/base_controller.rb +0 -37
  24. data/lib/logux/channel_controller.rb +0 -24
  25. data/lib/logux/class_finder.rb +0 -61
  26. data/lib/logux/client.rb +0 -21
  27. data/lib/logux/error_renderer.rb +0 -40
  28. data/lib/logux/meta.rb +0 -36
  29. data/lib/logux/node.rb +0 -37
  30. data/lib/logux/policy.rb +0 -14
  31. data/lib/logux/policy_caller.rb +0 -34
  32. data/lib/logux/process.rb +0 -9
  33. data/lib/logux/process/action.rb +0 -60
  34. data/lib/logux/process/auth.rb +0 -27
  35. data/lib/logux/process/batch.rb +0 -59
  36. data/lib/logux/response.rb +0 -18
  37. data/lib/logux/stream.rb +0 -25
  38. data/lib/logux/test.rb +0 -35
  39. data/lib/logux/test/helpers.rb +0 -75
  40. data/lib/logux/test/matchers.rb +0 -10
  41. data/lib/logux/test/matchers/base.rb +0 -25
  42. data/lib/logux/test/matchers/response_chunks.rb +0 -48
  43. data/lib/logux/test/matchers/send_to_logux.rb +0 -51
  44. data/lib/logux/test/store.rb +0 -21
@@ -1,107 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'configurations'
4
- require 'rest-client'
5
- require 'rails/engine'
6
- require 'active_support'
7
- require 'action_controller'
8
- require 'logux/engine'
9
- require 'nanoid'
10
- require 'colorize'
11
-
12
- module Logux
13
- extend ActiveSupport::Autoload
14
- include Configurations
15
-
16
- PROTOCOL_VERSION = 1
17
-
18
- class WithMetaError < StandardError
19
- attr_reader :meta
20
-
21
- def initialize(msg, meta: nil)
22
- @meta = meta
23
- super(msg)
24
- end
25
- end
26
-
27
- UnknownActionError = Class.new(WithMetaError)
28
- UnknownChannelError = Class.new(WithMetaError)
29
- UnauthorizedError = Class.new(StandardError)
30
-
31
- autoload :Client, 'logux/client'
32
- autoload :Meta, 'logux/meta'
33
- autoload :Actions, 'logux/actions'
34
- autoload :Auth, 'logux/auth'
35
- autoload :BaseController, 'logux/base_controller'
36
- autoload :ActionController, 'logux/action_controller'
37
- autoload :ChannelController, 'logux/channel_controller'
38
- autoload :ClassFinder, 'logux/class_finder'
39
- autoload :ActionCaller, 'logux/action_caller'
40
- autoload :PolicyCaller, 'logux/policy_caller'
41
- autoload :Policy, 'logux/policy'
42
- autoload :Add, 'logux/add'
43
- autoload :Node, 'logux/node'
44
- autoload :Response, 'logux/response'
45
- autoload :Stream, 'logux/stream'
46
- autoload :Process, 'logux/process'
47
- autoload :Logger, 'logux/logger'
48
- autoload :Version, 'logux/version'
49
- autoload :Test, 'logux/test'
50
- autoload :ErrorRenderer, 'logux/error_renderer'
51
- autoload :Model, 'logux/model'
52
-
53
- configurable :logux_host, :verify_authorized,
54
- :password, :logger,
55
- :on_error, :auth_rule,
56
- :render_backtrace_on_error
57
-
58
- configuration_defaults do |config|
59
- config.logux_host = 'localhost:1338'
60
- config.verify_authorized = true
61
- config.logger = ActiveSupport::Logger.new(STDOUT)
62
- if defined?(Rails) && Rails.respond_to?(:logger)
63
- config.logger = Rails.logger
64
- end
65
- config.on_error = proc {}
66
- config.auth_rule = proc { false }
67
- config.render_backtrace_on_error = true
68
- end
69
-
70
- def self.add(action, meta = Meta.new)
71
- Logux::Add.new.call([[action, meta]])
72
- end
73
-
74
- def self.add_batch(commands)
75
- Logux::Add.new.call(commands)
76
- end
77
-
78
- def self.undo(meta, reason: nil, data: {})
79
- add(
80
- data.merge(type: 'logux/undo', id: meta.id, reason: reason),
81
- Logux::Meta.new(clients: [meta.client_id])
82
- )
83
- end
84
-
85
- def self.verify_request_meta_data(meta_params)
86
- if Logux.configuration.password.nil?
87
- logger.warn(%(Please, add password for logux server:
88
- Logux.configure do |c|
89
- c.password = 'your-password'
90
- end))
91
- end
92
- auth = Logux.configuration.password == meta_params&.dig(:password)
93
- raise Logux::UnauthorizedError, 'Incorrect password' unless auth
94
- end
95
-
96
- def self.process_batch(stream:, batch:)
97
- Logux::Process::Batch.new(stream: stream, batch: batch).call
98
- end
99
-
100
- def self.generate_action_id
101
- Logux::Node.instance.generate_action_id
102
- end
103
-
104
- def self.logger
105
- configuration.logger
106
- end
107
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Logux
4
- class ActionCaller
5
- attr_reader :action, :meta
6
-
7
- delegate :logger, to: :Logux
8
-
9
- def initialize(action:, meta:)
10
- @action = action
11
- @meta = meta
12
- end
13
-
14
- def call!
15
- Logux::Model::UpdatesDeprecator.watch(level: :error) do
16
- logger.debug(
17
- "Searching action for Logux action: #{action}, meta: #{meta}"
18
- )
19
- format(action_controller.public_send(action.action_type))
20
- end
21
- rescue Logux::UnknownActionError, Logux::UnknownChannelError => e
22
- logger.warn(e)
23
- format(nil)
24
- end
25
-
26
- private
27
-
28
- def format(response)
29
- return response if response.is_a?(Logux::Response)
30
-
31
- Logux::Response.new(:processed, action: action, meta: meta)
32
- end
33
-
34
- def class_finder
35
- @class_finder ||= Logux::ClassFinder.new(action: action, meta: meta)
36
- end
37
-
38
- def action_controller
39
- class_finder.find_action_class.new(action: action, meta: meta)
40
- end
41
- end
42
- end
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Logux
4
- class ActionController < Logux::BaseController
5
- end
6
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Logux
4
- class Add
5
- attr_reader :client, :version, :password
6
-
7
- def initialize(client: Logux::Client.new,
8
- version: Logux::PROTOCOL_VERSION,
9
- password: Logux.configuration.password)
10
- @client = client
11
- @version = version
12
- @password = password
13
- end
14
-
15
- def call(commands)
16
- return if commands.empty?
17
-
18
- prepared_data = prepare_data(commands)
19
- Logux.logger.debug("Logux add: #{prepared_data}")
20
- client.post(prepared_data)
21
- end
22
-
23
- private
24
-
25
- def prepare_data(commands)
26
- {
27
- version: PROTOCOL_VERSION,
28
- password: password,
29
- commands: commands.map do |command|
30
- action = command.first
31
- meta = command[1]
32
- ['action', action, meta || Meta.new]
33
- end
34
- }
35
- end
36
- end
37
- end
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Logux
4
- class Auth < Hashie::Mash
5
- end
6
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Logux
4
- class BaseController
5
- class << self
6
- def verify_authorized!
7
- Logux.configuration.verify_authorized = true
8
- end
9
-
10
- def unverify_authorized!
11
- Logux.configuration.verify_authorized = false
12
- end
13
- end
14
-
15
- attr_reader :action, :meta
16
-
17
- def initialize(action:, meta: {})
18
- @action = action
19
- @meta = meta
20
- end
21
-
22
- def respond(status, action: @action, meta: @meta, custom_data: nil)
23
- Logux::Response.new(status,
24
- action: action,
25
- meta: meta,
26
- custom_data: custom_data)
27
- end
28
-
29
- def user_id
30
- @user_id ||= meta.user_id
31
- end
32
-
33
- def node_id
34
- @node_id ||= meta.node_id
35
- end
36
- end
37
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Logux
4
- class ChannelController < BaseController
5
- def subscribe
6
- Logux.add_batch(initial_data.map { |d| [d, initial_meta] })
7
- end
8
-
9
- def initial_data
10
- []
11
- end
12
-
13
- def initial_meta
14
- { clients: [meta.client_id] }
15
- end
16
-
17
- def since_time
18
- @since_time ||= begin
19
- since = action['since'].try(:[], 'time')
20
- Time.at(since).to_datetime if since
21
- end
22
- end
23
- end
24
- end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Logux
4
- class ClassFinder
5
- attr_reader :action, :meta
6
-
7
- def initialize(action:, meta:)
8
- @action = action
9
- @meta = meta
10
- end
11
-
12
- def find_action_class
13
- "#{class_namespace}::#{class_name}".constantize
14
- rescue NameError
15
- message =
16
- "Unable to find action #{class_name.camelize}.\n" \
17
- "Should be in app/logux/#{class_namespace.downcase}/#{class_path}.rb"
18
- raise_error_for_failed_find(message)
19
- end
20
-
21
- def find_policy_class
22
- "Policies::#{class_namespace}::#{class_name}".constantize
23
- rescue NameError
24
- message =
25
- "Unable to find action policy #{class_name.camelize}.\n" \
26
- "Should be in app/logux/#{class_namespace.downcase}/#{class_path}.rb"
27
- raise_error_for_failed_find(message)
28
- end
29
-
30
- def class_name
31
- if subscribe?
32
- action.channel_name.camelize
33
- else
34
- action.type.split('/')[0..-2].map(&:camelize).join('::')
35
- end
36
- end
37
-
38
- private
39
-
40
- def class_namespace
41
- subscribe? ? 'Channels' : 'Actions'
42
- end
43
-
44
- def subscribe?
45
- action.type == 'logux/subscribe'
46
- end
47
-
48
- def action?
49
- !subscribe?
50
- end
51
-
52
- def class_path
53
- "#{class_namespace}::#{class_name}".underscore
54
- end
55
-
56
- def raise_error_for_failed_find(message)
57
- exception_class = action? ? UnknownActionError : UnknownChannelError
58
- raise exception_class.new(message, meta: meta)
59
- end
60
- end
61
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Logux
4
- class Client
5
- attr_reader :logux_host
6
-
7
- def initialize(logux_host: Logux.configuration.logux_host)
8
- @logux_host = logux_host
9
- end
10
-
11
- def post(params)
12
- client.post(params.to_json,
13
- content_type: :json,
14
- accept: :json)
15
- end
16
-
17
- def client
18
- @client ||= RestClient::Resource.new(logux_host, verify_ssl: false)
19
- end
20
- end
21
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Logux
4
- class ErrorRenderer
5
- attr_reader :exception
6
-
7
- def initialize(exception)
8
- @exception = exception
9
- end
10
-
11
- def message
12
- case exception
13
- when Logux::WithMetaError
14
- build_message(exception, exception.meta.id)
15
- when Logux::UnauthorizedError
16
- build_message(exception, exception.message)
17
- when StandardError
18
- # some runtime error that should be fixed
19
- render_stardard_error(exception)
20
- end
21
- end
22
-
23
- private
24
-
25
- def render_stardard_error(exception)
26
- if Logux.configuration.render_backtrace_on_error
27
- ['error', exception.message + "\n" + exception.backtrace.join("\n")]
28
- else
29
- ['error', 'Please look server logs for more information']
30
- end
31
- end
32
-
33
- def build_message(exception, additional_info)
34
- [
35
- exception.class.name.demodulize.camelize(:lower).gsub(/Error/, ''),
36
- additional_info
37
- ]
38
- end
39
- end
40
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Logux
4
- class Meta < Hash
5
- def initialize(source_hash = {})
6
- merge!(source_hash.stringify_keys)
7
-
8
- self['id'] ||= Logux.generate_action_id
9
- self['time'] ||= self['id'].split(' ').first
10
- end
11
-
12
- def node_id
13
- id.split(' ').second
14
- end
15
-
16
- def user_id
17
- node_id.split(':').first
18
- end
19
-
20
- def client_id
21
- node_id.split(':')[0..1].join(':')
22
- end
23
-
24
- def logux_order
25
- time + ' ' + id.split(' ')[1..-1].join(' ')
26
- end
27
-
28
- def time
29
- fetch('time')
30
- end
31
-
32
- def id
33
- fetch('id')
34
- end
35
- end
36
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Logux
4
- class Node
5
- include Singleton
6
-
7
- attr_accessor :last_time, :sequence
8
- attr_writer :node_id
9
-
10
- def generate_action_id
11
- mutex.synchronize do
12
- if last_time && now_time <= last_time
13
- @sequence += 1
14
- else
15
- @sequence = 0
16
- @last_time = now_time
17
- end
18
-
19
- "#{last_time} #{node_id} #{sequence}"
20
- end
21
- end
22
-
23
- def node_id
24
- @node_id ||= "server:#{Nanoid.generate(size: 8)}"
25
- end
26
-
27
- private
28
-
29
- def now_time
30
- Time.now.to_datetime.strftime('%Q')
31
- end
32
-
33
- def mutex
34
- @mutex ||= Mutex.new
35
- end
36
- end
37
- end