Skip to content

Commit

Permalink
Merge pull request #11 from centosadmin/develop
Browse files Browse the repository at this point in the history
Release 1.0.0
  • Loading branch information
vladislav-yashin committed May 27, 2018
2 parents e533d71 + ebae800 commit 29faf58
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 39 deletions.
5 changes: 5 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
### 1.0.0 / 2018-05-27

* Return promises from TD::Client#broadcast
* Add #fetch as alias to #broadcast_and_receive

### 0.9.4 / 2018-05-16

* Fix recursive locking in nested handlers
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ end
p @me
```

## TD::Client#broadcast

From version 1.0 TD::Client##broadcast returns [Concurrent::Promise](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Promise.html) object.

```ruby
me = client.broadcast('@type' => 'getMe').then { |result| puts result }.rescue { |error| puts error }.value
```

## Configuration

```ruby
Expand Down
56 changes: 28 additions & 28 deletions lib/tdlib/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
#
# p @me
class TD::Client
include Concurrent

TIMEOUT = 20

def initialize(td_client = TD::Api.client_create,
Expand All @@ -74,49 +76,47 @@ def initialize(td_client = TD::Api.client_create,
@update_manager.run
end

# Sends asynchronous request to the TDLib client
# Sends asynchronous request to the TDLib client and returns Promise object
# @see https://www.rubydoc.info/github/ruby-concurrency/concurrent-ruby/Concurrent/Promise)
# @example
# client.broadcast(some_query).then { |result| puts result }.rescue
# @param [Hash] query
# @yield [update] yields update to the block as soon as it's received
def broadcast(query)
if block_given?
# @param [Numeric] timeout
# @return [Concurrent::Promise]
def broadcast(query, timeout: TIMEOUT)
Promise.execute do
condition = ConditionVariable.new
extra = TD::Utils.generate_extra(query)
result = nil
mutex = Mutex.new
handler = ->(update) do
return unless update['@extra'] == extra
yield update
@update_manager.remove_handler(handler)
mutex.synchronize do
result = update
@update_manager.remove_handler(handler)
condition.signal
end
end
@update_manager.add_handler(handler)
query['@extra'] = extra
mutex.synchronize do
TD::Api.client_send(@td_client, query)
condition.wait(mutex, timeout)
raise TD::TimeoutError if result.nil?
result
end
end
TD::Api.client_send(@td_client, query)
end

# Sends asynchronous request to the TDLib client and returns received update synchronously
# @param [Hash] query
# @return [Hash]
def broadcast_and_receive(query, timeout: TIMEOUT)
condition = ConditionVariable.new
extra = TD::Utils.generate_extra(query)
result = nil
mutex = Mutex.new
handler = ->(update) do
return unless update['@extra'] == extra
mutex.synchronize do
result = update
@update_manager.remove_handler(handler)
condition.signal
end
end
@update_manager.add_handler(handler)
query['@extra'] = extra
mutex.synchronize do
TD::Api.client_send(@td_client, query)
condition.wait(mutex, timeout)
raise TD::TimeoutError if result.nil?
result
end
def fetch(query, timeout: TIMEOUT)
broadcast(query, timeout: timeout).value
end

alias broadcast_and_receive fetch

# Synchronously executes TDLib request
# Only a few requests can be executed synchronously
# @param [Hash] query
Expand Down
2 changes: 1 addition & 1 deletion lib/tdlib/version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module TD
# tdlib-ruby version
VERSION = "0.9.4"
VERSION = "1.0.0"
end
13 changes: 3 additions & 10 deletions spec/integration/tdlib_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,9 @@
subject { client.on_ready { client.broadcast(payload) } }

it { expect { subject }.not_to raise_error(Exception) }
end

context 'when block given' do
subject { client.on_ready { client.broadcast(payload) { |update| @result = update } } }

it 'runs block on update' do
subject
sleep 1
expect(@result).to include('@type', 'entities')
end
it { is_expected.to satisfy { |result| result.state == :pending } }
it { is_expected.to satisfy { |result| sleep 1; result.state == :fulfilled } }
it { is_expected.to satisfy { |result| sleep 1; result.value['@type'] == 'textEntities' } }
end
end

Expand Down
1 change: 1 addition & 0 deletions tdlib-ruby.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Gem::Specification.new do |gem|
gem.require_paths = ['lib']

gem.add_runtime_dependency 'dry-configurable', '~> 0.7'
gem.add_runtime_dependency 'concurrent-ruby', '~> 1.0'

gem.add_development_dependency 'bundler', '~> 1.10'
gem.add_development_dependency 'rake', '12.3.1'
Expand Down

0 comments on commit 29faf58

Please sign in to comment.