Class: TD::Client

Inherits:
Object
  • Object
show all
Includes:
Concurrent, ClientMethods
Defined in:
lib/tdlib/client.rb

Overview

Simple client for TDLib.

Constant Summary collapse

TIMEOUT =
20

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(td_client = TD::Api.client_create, update_manager = TD::UpdateManager.new(td_client), timeout: TIMEOUT, **extra_config) ⇒ Client

Returns a new instance of Client.

Parameters:

  • td_client (FFI::Pointer) (defaults to: TD::Api.client_create)
  • update_manager (TD::UpdateManager) (defaults to: TD::UpdateManager.new(td_client))
  • timeout (Numeric) (defaults to: TIMEOUT)
  • extra_config (Hash)

    optional configuration hash that will be merged into tdlib client configuration



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/tdlib/client.rb', line 18

def initialize(td_client = TD::Api.client_create,
               update_manager = TD::UpdateManager.new(td_client),
               timeout: TIMEOUT,
               **extra_config)
  @td_client = td_client
  @ready = false
  @alive = true
  @update_manager = update_manager
  @timeout = timeout
  @config = TD.config.client.to_h.merge(extra_config)
  @ready_condition_mutex = Mutex.new
  @ready_condition = ConditionVariable.new
end

Class Method Details

.ready(*args) ⇒ Object



10
11
12
# File 'lib/tdlib/client.rb', line 10

def self.ready(*args)
  new(*args).connect
end

Instance Method Details

#alive?Boolean

Returns:

  • (Boolean)


155
156
157
# File 'lib/tdlib/client.rb', line 155

def alive?
  @alive
end

#broadcast(query) ⇒ Concurrent::Promises::Future

Sends asynchronous request to the TDLib client and returns Promise object

Examples:

client.broadcast(some_query).then { |result| puts result }.rescue { |error| puts [error.code, error.message] }

Parameters:

  • query (Hash)

Returns:

  • (Concurrent::Promises::Future)

See Also:



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/tdlib/client.rb', line 64

def broadcast(query)
  return dead_client_promise if dead?

  Promises.future do
    condition = ConditionVariable.new
    extra = SecureRandom.uuid
    result = nil
    mutex = Mutex.new

    @update_manager << TD::UpdateHandler.new(TD::Types::Base, extra, disposable: true) do |update|
      mutex.synchronize do
        result = update
        condition.signal
      end
    end

    query['@extra'] = extra

    mutex.synchronize do
      send_to_td_client(query)
      condition.wait(mutex, @timeout)
      error = nil
      error = result if result.is_a?(TD::Types::Error)
      error = timeout_error if result.nil?
      raise TD::Error.new(error) if error
      result
    end
  end
end

#connectConcurrent::Promises::Future

Adds initial authorization state handler and runs update manager Returns future that will be fulfilled when client is ready

Returns:

  • (Concurrent::Promises::Future)


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/tdlib/client.rb', line 35

def connect
  on TD::Types::Update::AuthorizationState do |update|
    case update.authorization_state
    when TD::Types::AuthorizationState::WaitTdlibParameters
      set_tdlib_parameters(parameters: TD::Types::TdlibParameters.new(**@config))
    when TD::Types::AuthorizationState::WaitEncryptionKey
      check_database_encryption_key(encryption_key: TD.config.encryption_key).then do
        @ready_condition_mutex.synchronize do
          @ready = true
          @ready_condition.broadcast
        end
      end
    else
      # do nothing
    end
  end

  @update_manager.run(callback: method(:handle_update))
  ready
end

#dead?Boolean

Returns:

  • (Boolean)


159
160
161
# File 'lib/tdlib/client.rb', line 159

def dead?
  !alive?
end

#disposeObject

Stops update manager and destroys TDLib client



150
151
152
153
# File 'lib/tdlib/client.rb', line 150

def dispose
  return if dead?
  close.then { get_authorization_state }
end

#execute(query) ⇒ Object

Synchronously executes TDLib request Only a few requests can be executed synchronously

Parameters:

  • query (Hash)


106
107
108
109
# File 'lib/tdlib/client.rb', line 106

def execute(query)
  return dead_client_error if dead?
  TD::Api.client_execute(@td_client, query)
end

#fetch(query) ⇒ Hash Also known as: broadcast_and_receive

Sends asynchronous request to the TDLib client and returns received update synchronously

Parameters:

  • query (Hash)

Returns:

  • (Hash)


97
98
99
# File 'lib/tdlib/client.rb', line 97

def fetch(query)
  broadcast(query).value!
end

#on(update_type) {|update| ... } ⇒ Object

Binds passed block as a handler for updates with type of update_type

Parameters:

  • update_type (String, Class)

Yields:

  • (update)

    yields update to the block as soon as it's received



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/tdlib/client.rb', line 114

def on(update_type, &action)
  if update_type.is_a?(String)
    if (type_const = TD::Types::LOOKUP_TABLE[update_type])
      update_type = TD::Types.const_get("TD::Types::#{type_const}")
    else
      raise ArgumentError.new("Can't find class for #{update_type}")
    end
  end

  unless update_type < TD::Types::Base
    raise ArgumentError.new("Wrong type specified (#{update_type}). Should be of kind TD::Types::Base")
  end

  @update_manager << TD::UpdateHandler.new(update_type, &action)
end

#on_ready(&action) ⇒ Object

Deprecated.


145
146
147
# File 'lib/tdlib/client.rb', line 145

def on_ready(&action)
  ready.then(&action).value!
end

#readyConcurrent::Promises::Future

returns future that will be fulfilled when client is ready

Returns:

  • (Concurrent::Promises::Future)


132
133
134
135
136
137
138
139
140
141
142
# File 'lib/tdlib/client.rb', line 132

def ready
  return dead_client_promise if dead?
  return Promises.fulfilled_future(self) if ready?

  Promises.future do
    @ready_condition_mutex.synchronize do
      next self if @ready || (@ready_condition.wait(@ready_condition_mutex, @timeout) && @ready)
      raise TD::Error.new(timeout_error)
    end
  end
end

#ready?Boolean

Returns:

  • (Boolean)


163
164
165
# File 'lib/tdlib/client.rb', line 163

def ready?
  @ready
end