ruby_rabbitmq_janus 2.1.1 → 2.2.0.pre.42

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.md +3 -4
  3. data/config/default.yml +7 -6
  4. data/lib/generators/ruby_rabbitmq_janus/templates/migration.rb +1 -0
  5. data/lib/rrj/errors/error.rb +16 -4
  6. data/lib/rrj/errors/janus/janus.rb +0 -1
  7. data/lib/rrj/errors/janus/processus/keepalive.rb +5 -17
  8. data/lib/rrj/errors/janus/processus/keepalive/initializer.rb +61 -0
  9. data/lib/rrj/errors/janus/processus/keepalive/thread.rb +16 -0
  10. data/lib/rrj/errors/janus/processus/keepalive/timer.rb +16 -0
  11. data/lib/rrj/errors/rabbit/connect.rb +12 -12
  12. data/lib/rrj/errors/tools/gem/cluster.rb +7 -7
  13. data/lib/rrj/errors/tools/gem/config.rb +0 -14
  14. data/lib/rrj/errors/tools/gem/option.rb +7 -0
  15. data/lib/rrj/info.rb +1 -1
  16. data/lib/rrj/init.rb +0 -11
  17. data/lib/rrj/janus/processus/concurrency.rb +8 -5
  18. data/lib/rrj/janus/processus/event.rb +8 -5
  19. data/lib/rrj/janus/processus/keepalive/keepalive_initializer.rb +74 -0
  20. data/lib/rrj/janus/processus/keepalive/keepalive_message.rb +52 -0
  21. data/lib/rrj/janus/processus/keepalive/keepalive_thread.rb +71 -0
  22. data/lib/rrj/janus/processus/keepalive/keepalive_timer.rb +64 -0
  23. data/lib/rrj/janus/responses/response.rb +8 -1
  24. data/lib/rrj/janus/transactions/transaction.rb +1 -1
  25. data/lib/rrj/models/active_record.rb +6 -2
  26. data/lib/rrj/models/concerns/janus_instance_callbacks.rb +69 -0
  27. data/lib/rrj/models/concerns/{janus_instance_concern.rb → janus_instance_methods.rb} +7 -10
  28. data/lib/rrj/models/concerns/janus_instance_validations.rb +20 -0
  29. data/lib/rrj/models/mongoid.rb +7 -2
  30. data/lib/rrj/rabbit/connect.rb +14 -12
  31. data/lib/rrj/rabbit/publish/keepalive.rb +33 -0
  32. data/lib/rrj/rabbit/publish/publisher.rb +1 -0
  33. data/lib/rrj/tools/gem/cluster.rb +15 -25
  34. data/lib/rrj/tools/gem/config.rb +1 -8
  35. data/lib/rrj/tools/gem/option.rb +16 -9
  36. data/spec/rrj/tools/gem/rrj_cluster_spec.rb +2 -6
  37. data/spec/rrj/tools/gem/rrj_config_spec.rb +1 -6
  38. data/spec/support/schemas/config/config.json +13 -5
  39. metadata +30 -7
  40. data/lib/rrj/janus/processus/keepalive.rb +0 -79
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rrj/janus/processus/keepalive/keepalive_timer'
4
+ require 'rrj/janus/processus/keepalive/keepalive_message'
5
+ require 'rrj/janus/processus/keepalive/keepalive_thread'
6
+
7
+ module RubyRabbitmqJanus
8
+ module Janus
9
+ module Concurrencies
10
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
11
+ #
12
+ # # Manage keepalive message
13
+ #
14
+ # Create a thread for sending a message with type keepalive to session
15
+ # created by this instanciate gem
16
+ class KeepaliveInitializer < Concurrency
17
+ # Initialize a singleton object for sending keepalive to janus
18
+ def initialize(instance)
19
+ super()
20
+ @thread = KeepaliveThread.new(instance, rabbit) { initialize_thread }
21
+ rescue
22
+ raise Errors::Janus::KeepaliveInitializer::Initializer
23
+ end
24
+
25
+ # Get thread with Ruby ID
26
+ def self.thread(thread)
27
+ ObjectSpace._id2ref(thread)
28
+ rescue RangeError
29
+ puts "No thread with ID : #{thread}"
30
+ end
31
+
32
+ # Give a session Integer his gem is instantiate.
33
+ # Is waiting a thread return a response to message created sending.
34
+ #
35
+ # @example Ask session
36
+ # KeepaliveInitializer.new(123).session
37
+ # => 852803383803249
38
+ #
39
+ # @return [Fixnum] Identifier to session created by Janus
40
+ def session
41
+ @thread.timer.session do
42
+ lock.synchronize do
43
+ condition.wait(lock)
44
+ @thread.session
45
+ end
46
+ end
47
+ rescue
48
+ raise Errors::Janus::KeepaliveInitializer::Session
49
+ end
50
+
51
+ # Ask Object ID to thread managing keepalive message
52
+ #
53
+ # @example Ask ID
54
+ # KeepaliveInitializer.new(123).thread
55
+ # => 70233080652140
56
+ #
57
+ # @return [Integer] Identifier to thread in Ruby
58
+ def thread_id
59
+ @thread.__id__
60
+ rescue
61
+ raise Errors::Janus::KeepaliveInitializer::Thread
62
+ end
63
+
64
+ private
65
+
66
+ def transaction_running
67
+ @thread.initialize_janus_session
68
+ lock.synchronize { condition.signal }
69
+ @thread.start
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :reek:UtilityFunction
4
+
5
+ module RubyRabbitmqJanus
6
+ module Janus
7
+ module Concurrencies
8
+ # Manage message used for keepalive thread
9
+ class KeepaliveMessage
10
+ def initialize(instance)
11
+ @instance = instance
12
+ end
13
+
14
+ def session
15
+ Janus::Messages::Standard.new('base::create', param_instance)
16
+ end
17
+
18
+ def response_session(message)
19
+ RubyRabbitmqJanus::Janus::Responses::Standard.new(message).session
20
+ end
21
+
22
+ def keepalive(session)
23
+ parameter = param_session(session)
24
+ Janus::Messages::Standard.new('base::keepalive', parameter)
25
+ end
26
+
27
+ def response_acknowledgement(message)
28
+ RubyRabbitmqJanus::Janus::Responses::Standard.new(message).error?
29
+ end
30
+
31
+ def destroy(session)
32
+ parameter = param_session(session)
33
+ Janus::Messages::Standard.new('base::destroy', parameter)
34
+ end
35
+
36
+ def response_destroy(message)
37
+ RubyRabbitmqJanus::Janus::Responses::Standard.new(message)
38
+ end
39
+
40
+ private
41
+
42
+ def param_instance
43
+ { 'instance' => @instance }
44
+ end
45
+
46
+ def param_session(session)
47
+ { 'session_id' => session }.merge(param_instance)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :reek:TooManyInstanceVariables
4
+
5
+ module RubyRabbitmqJanus
6
+ module Janus
7
+ module Concurrencies
8
+ # Object thread
9
+ class KeepaliveThread < Thread
10
+ attr_reader :timer, :instance, :session
11
+
12
+ def initialize(instance, rabbit, &block)
13
+ @publisher = @session = nil
14
+ @rabbit = rabbit
15
+ @timer = KeepaliveTimer.new
16
+ @message = KeepaliveMessage.new(instance)
17
+ super(&block)
18
+ end
19
+
20
+ # Initialize a transaction with Janus Instance.
21
+ # Create a session and save response
22
+ def initialize_janus_session
23
+ @publisher = publisher
24
+ @session = response_session
25
+ end
26
+
27
+ def start
28
+ @timer.loop_keepalive { response_keepalive }
29
+ end
30
+
31
+ def kill
32
+ response_destroy
33
+ super
34
+ end
35
+
36
+ def instance_is_down
37
+ janus = Models::JanusInstance.find_by_session(@session)
38
+ janus.set(enable: false)
39
+
40
+ Tools::Log.instance.fatal \
41
+ "Janus Instance [#{janus.instance}] is down, kill thread."
42
+ Thread.instance_method(:kill).bind(self).call
43
+ end
44
+
45
+ private
46
+
47
+ def publisher
48
+ Rabbit::Publisher::PublishKeepalive.new(@rabbit.channel)
49
+ end
50
+
51
+ def response_session
52
+ @message.response_session(publish(@message.session))
53
+ end
54
+
55
+ def response_keepalive
56
+ keepalive = @message.keepalive(@session)
57
+ @message.response_acknowledgement(publish(keepalive))
58
+ end
59
+
60
+ def response_destroy
61
+ destroy = @message.destroy(@session)
62
+ @message.response_destroy(publish(destroy))
63
+ end
64
+
65
+ def publish(message)
66
+ @publisher.publish(message)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'timeout'
4
+ require 'timers'
5
+
6
+ module RubyRabbitmqJanus
7
+ module Janus
8
+ module Concurrencies
9
+ # @author VAILLANT Jeremy <jeremy.vaillant@dazzl.tv>
10
+ #
11
+ # # Manage time for thread
12
+ #
13
+ # Configure all timer used in keepalive class
14
+ class KeepaliveTimer
15
+ # Initialize timer to keeaplive thread.
16
+ # Configure timer with :
17
+ # - interval for each keepalive message
18
+ # - timeout for session response
19
+ # - timeout for publish message
20
+ def initialize
21
+ @time_to_live = Tools::Config.instance.ttl
22
+ @time_publish = @time_to_live + 5
23
+ @timer = Timers::Group.new
24
+ end
25
+
26
+ # Execute a loop with timer for sending keepalive message
27
+ # to Janus Instance
28
+ def loop_keepalive(&block)
29
+ @timer.now_and_every(@time_to_live) { prepare_loop(&block) }
30
+ loop { @timer.wait }
31
+ end
32
+
33
+ # Test if session is present/exist in Janus Instance
34
+ def session(&block)
35
+ Timeout.timeout(@time_publish) { yield }
36
+ rescue Timeout::Error
37
+ stop_timer
38
+ block.binding.receiver.instance_is_down
39
+ end
40
+
41
+ # Stop timer to keepalive thread
42
+ def stop_timer
43
+ @timer.pause
44
+ end
45
+
46
+ # Start timer to keepalive thread
47
+ def start_timer
48
+ @timer.resume
49
+ end
50
+
51
+ private
52
+
53
+ def prepare_loop(&block)
54
+ Timeout.timeout(@time_publish) do
55
+ yield
56
+ end
57
+ rescue Timeout::Error
58
+ stop_timer
59
+ block.binding.receiver.instance_is_down
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -11,7 +11,7 @@ module RubyRabbitmqJanus
11
11
  # Read a message in rabbitmq queue. This message is formatted to JSON
12
12
  # or Hash format. For developpment it's possible to used a `nice` JSON.
13
13
  class Response
14
- # Instanciate a response
14
+ # Instantiate a response
15
15
  #
16
16
  # @param [Hash] response_janus
17
17
  # Request parsing after Janus/RabbitMQ receive a response to request
@@ -49,6 +49,13 @@ module RubyRabbitmqJanus
49
49
  raise Errors::Janus::Response::ToHash
50
50
  end
51
51
 
52
+ # Test if response it's an error
53
+ #
54
+ # @return [Boolean]
55
+ def error?
56
+ @request['janus'].match?('error')
57
+ end
58
+
52
59
  private
53
60
 
54
61
  attr_accessor :request
@@ -15,7 +15,7 @@ module RubyRabbitmqJanus
15
15
  # @param [Fixnum] session
16
16
  # Use a session identifier for created message
17
17
  def initialize(session)
18
- @rabbit = Rabbit::Connect.new
18
+ @rabbit = RubyRabbitmqJanus::Rabbit::Connect.new
19
19
  @session = session
20
20
  @publisher = @exclusive = nil
21
21
  rescue
@@ -6,9 +6,13 @@ module RubyRabbitmqJanus
6
6
  #
7
7
  # Store instance information for MongoID database
8
8
  class JanusInstance < ::ActiveRecord::Base
9
- include RubyRabbitmqJanus::Models::JanusInstanceConcern
9
+ include RubyRabbitmqJanus::Models::JanusInstanceCallbacks
10
+ include RubyRabbitmqJanus::Models::JanusInstanceMethods
11
+ include RubyRabbitmqJanus::Models::JanusInstanceValidations
10
12
 
11
- before_destroy { destroy_before_action }
13
+ after_create { callback_after_after }
14
+ after_update { callback_update_after }
15
+ after_destroy { callback_destroy_after }
12
16
  end
13
17
  end
14
18
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyRabbitmqJanus
4
+ # Contains all model for this gem
5
+ module Models
6
+ # Configure callback for Janus Instance models
7
+ module JanusInstanceCallbacks
8
+ extend ActiveSupport::Concern
9
+
10
+ # Create a session in Janus Instance
11
+ def callback_create_after
12
+ Tools::Log.instance.debug 'Callback AFTER_VALIDATION'
13
+ create_a_session_in_janus_instance if enable
14
+ end
15
+
16
+ # Update a keepalive transaction in Janus Instance
17
+ # Enable or Disable transaction
18
+ def callback_update_after
19
+ Tools::Log.instance.debug 'Callback AFTER_UPDATE'
20
+ if enable && enable_changed?
21
+ create_a_session_in_janus_instance
22
+ elsif !enable && enable_changed?
23
+ disable_a_session_in_janus_instance
24
+ end
25
+ end
26
+
27
+ # Destroy a session in Janus Instance
28
+ def callback_destroy_after
29
+ Tools::Log.instance.debug 'Callback AFTER_DESTROY'
30
+ destroy_a_session_in_janus_instance if enable && session? && thread?
31
+ end
32
+
33
+ private
34
+
35
+ def create_a_session_in_janus_instance
36
+ info_instance('Create session')
37
+ janus_instance = keepalive_object_new
38
+ set(session: janus_instance.session, thread: janus_instance.thread_id)
39
+ end
40
+
41
+ def disable_a_session_in_janus_instance
42
+ info_instance('Destroy session')
43
+ keepalive_object_thread.kill
44
+ unset(%I[thread session])
45
+ end
46
+
47
+ def destroy_a_session_in_janus_instance
48
+ info_instance('Destroy session')
49
+ keepalive_object_thread.kill
50
+ end
51
+
52
+ def keepalive_object
53
+ RubyRabbitmqJanus::Janus::Concurrencies::KeepaliveInitializer
54
+ end
55
+
56
+ def keepalive_object_new
57
+ keepalive_object.new(instance)
58
+ end
59
+
60
+ def keepalive_object_thread
61
+ keepalive_object.thread(thread)
62
+ end
63
+
64
+ def info_instance(text)
65
+ Tools::Log.instance.debug "#{text} in Janus Instance [##{instance}]"
66
+ end
67
+ end
68
+ end
69
+ end
@@ -5,17 +5,9 @@
5
5
  module RubyRabbitmqJanus
6
6
  module Models
7
7
  # Add method for JanusInstance model
8
- module JanusInstanceConcern
8
+ module JanusInstanceMethods
9
9
  extend ActiveSupport::Concern
10
10
 
11
- # Send an action for destroying a session in Janus Gateway instance
12
- def destroy_before_action
13
- options = { 'session_id' => session, 'instance' => instance }
14
- search_initializer(options) do |transaction|
15
- transaction.publish_message('base::destroy', options)
16
- end
17
- end
18
-
19
11
  # Class methods for JanusInstance model
20
12
  module ClassMethods
21
13
  # Disable an instance
@@ -23,7 +15,7 @@ module RubyRabbitmqJanus
23
15
  JanusInstance.find_by(session: session_id).set(enable: false)
24
16
  end
25
17
 
26
- # Delete all instance disabled
18
+ # Clean all instance disabled
27
19
  def destroys
28
20
  JanusInstance.where(enable: false).delete_all
29
21
  end
@@ -41,6 +33,11 @@ module RubyRabbitmqJanus
41
33
  rescue
42
34
  nil
43
35
  end
36
+
37
+ # Get all instance active
38
+ def enabled
39
+ JanusInstance.where(enable: true)
40
+ end
44
41
  end
45
42
 
46
43
  private
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyRabbitmqJanus
4
+ module Models
5
+ # Configure validation for JanusInstance model
6
+ module JanusInstanceValidations
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ # Instance number it's mandatory, unique and with type Integer
11
+ validates :instance, presence: true,
12
+ numericality: { only_integer: true },
13
+ uniqueness: true
14
+ # This instance it's a state (enable or disable)
15
+ validates :enable, presence: true,
16
+ inclusion: { in: [true, false] }
17
+ end
18
+ end
19
+ end
20
+ end