Class: Deluge::Rpc::Connection

Inherits:
Object
  • Object
show all
Defined in:
lib/deluge/rpc/connection.rb

Defined Under Namespace

Classes: ConnectionClosedError, InvokeTimeoutError, RPCError

Constant Summary collapse

DAEMON_LOGIN =
'daemon.login'
DAEMON_METHOD_LIST =
'daemon.get_method_list'
DAEMON_REGISTER_EVENT =
'daemon.set_event_interest'
DEFAULT_CALL_TIMEOUT =

seconds

5.0
DEFAULT_PORT =
58846
RPC_RESPONSE =
1
RPC_ERROR =
2
RPC_EVENT =
3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Connection

Returns a new instance of Connection.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/deluge/rpc/connection.rb', line 31

def initialize(options = {})
  @host = options.delete(:host) || 'localhost'
  @port = (options.delete(:port) || DEFAULT_PORT).to_i

  @call_timeout = options.delete(:call_timeout) || DEFAULT_CALL_TIMEOUT

  @request_id = Concurrent::AtomicFixnum.new
  @running = Concurrent::AtomicBoolean.new

  @messages = {}
  @events = {}

  @write_mutex = Mutex.new
end

Instance Attribute Details

#hostObject (readonly)

Returns the value of attribute host.



29
30
31
# File 'lib/deluge/rpc/connection.rb', line 29

def host
  @host
end

#portObject (readonly)

Returns the value of attribute port.



29
30
31
# File 'lib/deluge/rpc/connection.rb', line 29

def port
  @port
end

Instance Method Details

#authenticate(login, password) ⇒ Object



64
65
66
# File 'lib/deluge/rpc/connection.rb', line 64

def authenticate(, password)
  self.call(DAEMON_LOGIN, , password)
end

#call(method, *args) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/deluge/rpc/connection.rb', line 87

def call(method, *args)
  raise "Not connected!" unless @connection

  kwargs = {}
  kwargs = args.pop if args.size == 1 && args.last.is_a?(Hash)

  future = Concurrent::IVar.new

  request_id = @request_id.increment
  @messages[request_id] = future

  message = [[request_id, method, args, kwargs]]

  write_packet(message)

  result = future.value!(@call_timeout)

  if result.nil? && future.pending?
    raise InvokeTimeoutError.new("Failed to retreive response for '#{method}' in #{@call_timeout} seconds. Probably method not exists.")
  end

  result
end

#closeObject



83
84
85
# File 'lib/deluge/rpc/connection.rb', line 83

def close
  @running.make_false
end

#method_listObject



68
69
70
# File 'lib/deluge/rpc/connection.rb', line 68

def method_list
  self.call(DAEMON_METHOD_LIST)
end

#register_event(event_name, force = false, &block) ⇒ Object



72
73
74
75
76
77
78
79
80
81
# File 'lib/deluge/rpc/connection.rb', line 72

def register_event(event_name, force = false, &block)
  unless @events[event_name] # Register event only ONCE!
    self.call(DAEMON_REGISTER_EVENT, [event_name]) if @connection # Let events be initialized lazily
  end

  @events[event_name] ||= []
  @events[event_name] << block

  true
end

#startObject



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/deluge/rpc/connection.rb', line 46

def start
  raise 'Connection already opened' if @connection

  @connection = OpenSSL::SSL::SSLSocket.new(create_socket, ssl_context)

  @connection.connect

  @running.make_true

  @main_thread = Thread.current
  @thread = Thread.new(&self.method(:read_loop))

  # register present events
  recover_events! if @events.size > 0

  true
end