ruby_rabbitmq_janus 2.1.1 → 2.2.0.pre.42
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 +4 -4
- data/config/default.md +3 -4
- data/config/default.yml +7 -6
- data/lib/generators/ruby_rabbitmq_janus/templates/migration.rb +1 -0
- data/lib/rrj/errors/error.rb +16 -4
- data/lib/rrj/errors/janus/janus.rb +0 -1
- data/lib/rrj/errors/janus/processus/keepalive.rb +5 -17
- data/lib/rrj/errors/janus/processus/keepalive/initializer.rb +61 -0
- data/lib/rrj/errors/janus/processus/keepalive/thread.rb +16 -0
- data/lib/rrj/errors/janus/processus/keepalive/timer.rb +16 -0
- data/lib/rrj/errors/rabbit/connect.rb +12 -12
- data/lib/rrj/errors/tools/gem/cluster.rb +7 -7
- data/lib/rrj/errors/tools/gem/config.rb +0 -14
- data/lib/rrj/errors/tools/gem/option.rb +7 -0
- data/lib/rrj/info.rb +1 -1
- data/lib/rrj/init.rb +0 -11
- data/lib/rrj/janus/processus/concurrency.rb +8 -5
- data/lib/rrj/janus/processus/event.rb +8 -5
- data/lib/rrj/janus/processus/keepalive/keepalive_initializer.rb +74 -0
- data/lib/rrj/janus/processus/keepalive/keepalive_message.rb +52 -0
- data/lib/rrj/janus/processus/keepalive/keepalive_thread.rb +71 -0
- data/lib/rrj/janus/processus/keepalive/keepalive_timer.rb +64 -0
- data/lib/rrj/janus/responses/response.rb +8 -1
- data/lib/rrj/janus/transactions/transaction.rb +1 -1
- data/lib/rrj/models/active_record.rb +6 -2
- data/lib/rrj/models/concerns/janus_instance_callbacks.rb +69 -0
- data/lib/rrj/models/concerns/{janus_instance_concern.rb → janus_instance_methods.rb} +7 -10
- data/lib/rrj/models/concerns/janus_instance_validations.rb +20 -0
- data/lib/rrj/models/mongoid.rb +7 -2
- data/lib/rrj/rabbit/connect.rb +14 -12
- data/lib/rrj/rabbit/publish/keepalive.rb +33 -0
- data/lib/rrj/rabbit/publish/publisher.rb +1 -0
- data/lib/rrj/tools/gem/cluster.rb +15 -25
- data/lib/rrj/tools/gem/config.rb +1 -8
- data/lib/rrj/tools/gem/option.rb +16 -9
- data/spec/rrj/tools/gem/rrj_cluster_spec.rb +2 -6
- data/spec/rrj/tools/gem/rrj_config_spec.rb +1 -6
- data/spec/support/schemas/config/config.json +13 -5
- metadata +30 -7
- 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
|
-
#
|
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::
|
9
|
+
include RubyRabbitmqJanus::Models::JanusInstanceCallbacks
|
10
|
+
include RubyRabbitmqJanus::Models::JanusInstanceMethods
|
11
|
+
include RubyRabbitmqJanus::Models::JanusInstanceValidations
|
10
12
|
|
11
|
-
|
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
|
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
|
-
#
|
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
|