lib/universa/client.rb in universa-0.1.8 vs lib/universa/client.rb in universa-0.1.9

- old
+ new

@@ -8,11 +8,14 @@ # Universa network client reads current network configuration and provides access to each node independently # and also implement newtor-wide procedures. class Client using Universa::Parallel + include Universa + attr :connection_key + # Create client # @param [PrivateKey] private_key to connect with. Generates new one if omitted. def initialize private_key = nil @connection_key = private_key scan_network() @@ -44,22 +47,24 @@ # # @param [Contract | HashId] obj to check # @return [ContractState] of some final node check It does not aggregates (yet) def get_state obj result = Concurrent::IVar.new - negative_votes = Concurrent::AtomicFixnum.new(@nodes.size * 20 / 100) + negative_votes = Concurrent::AtomicFixnum.new(@nodes.size * 11 / 100) positive_votes = Concurrent::AtomicFixnum.new(@nodes.size * 30 / 100) - random_connections(@nodes.size * 2 / 3).par.each {|conn| - if result.incomplete? - if (state = conn.get_state(obj)).approved? - result.try_set(state) if positive_votes.decrement < 0 - else - result.try_set(state) if negative_votes.decrement < 0 + retry_with_timeout(20, 3) { + random_connections(@nodes.size).par.each {|conn| + if result.incomplete? + if (state = conn.get_state(obj)).approved? + result.try_set(state) if positive_votes.decrement < 0 + else + result.try_set(state) if negative_votes.decrement < 0 + end end - end + } + result.value } - result.value end # @return [Array(Connection)] array of count randomly selected connections def random_connections count = 1 @nodes.sample(count) @@ -142,10 +147,12 @@ # Access to the single node using universa client protocol. # class Connection + include Universa + # create connection for a given clietn. Don't call it direcly, use # {Client.random_connection} or {Client.random_connections} instead. The client implements # lazy initialization so time-consuming actual connection will be postponed until # needed. # @@ -166,15 +173,17 @@ # on a single node. # # @param [Contract] contract, muts be sealed ({Contract#seal}) # @return [ContractState] of the result. Could contain errors. def register_single contract - result = ContractState.new(execute "approve", packedItem: contract.packed) - while result.is_pending - sleep(0.1) - result = get_state contract - end - result + retry_with_timeout(15, 3) { + result = ContractState.new(execute "approve", packedItem: contract.packed) + while result.is_pending + sleep(0.1) + result = get_state contract + end + result + } end # Get contract or hashId state from this single node # @param [Contract | HashId] x what to check # @return [ContractState]