sequence-sdk 2.1 → 2.2.rc.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da2edb02eda3ac971bd102181b56b78339a16a30d12c7c06c123569a09180584
4
- data.tar.gz: a8e9ffb7f528e3679f817ab2b06e1399ed90013d474601dcbb01f8e92e2a5cd1
3
+ metadata.gz: 6246691bbc9fe8915c626d2013e33c0dbb4950606d3a56a505365889e26c1660
4
+ data.tar.gz: 18be34a81476f9cb75855aef2126f68e2fa36f8849ea727e1bef278b40a442c3
5
5
  SHA512:
6
- metadata.gz: 807d33a14ca05d631003907294f6e2ca6f0618838615907853feb071f661a98268b26b5f70216670a8d36ac2c2ae32540cacd02ffba18461655c8729bf784df7
7
- data.tar.gz: ea5d6ec64d2809b8a744efdf178b5ffde5721499f706652427c2dbe0e5ff556493b1fa327f09835d0150917e8bb1198950997f0c07b132002cb9b1df008257ab
6
+ metadata.gz: 88bbd9ececed4673dd0dc2547ca3e1feb1a02bcb5e23366dbe906f5106832f6da18c2c0114e2cd3de15bb50911569b929df56c75de597db773e39c329090a821
7
+ data.tar.gz: b4a4340dd743d635d52a17c6977e5ed589ed38b344026054337273fdb2d00f2d21aeeb7a0217aff0b12deedc10ef1e8f4c62fad5f69c55e4e0c4ff9b0d263e32
@@ -87,6 +87,17 @@ module Sequence
87
87
  ListQuery.new(client, filter: filter, filter_params: filter_params)
88
88
  end
89
89
 
90
+ # Update an action's tags.
91
+ # @param id [String]
92
+ # The ID of the action.
93
+ # @param tags [Hash]
94
+ # A new set of tags, which will replace the existing tags.
95
+ # @return [void]
96
+ def update_tags(id:, tags: nil)
97
+ raise ArgumentError, ':id cannot be blank' if id == ''
98
+ client.session.request('update-action-tags', id: id, tags: tags)
99
+ end
100
+
90
101
  # Execute a query, returning an enumerable over sums of actions.
91
102
  # @param filter [String]
92
103
  # A filter expression.
@@ -6,6 +6,7 @@ require_relative './dev_utils'
6
6
  require_relative './feed'
7
7
  require_relative './flavor'
8
8
  require_relative './http_wrapper'
9
+ require_relative './index'
9
10
  require_relative './key'
10
11
  require_relative './stats'
11
12
  require_relative './token'
@@ -28,14 +29,11 @@ module Sequence
28
29
  raise ArgumentError, ':credential cannot be blank'
29
30
  end
30
31
 
31
- addr = ENV['SEQADDR'] || 'api.seq.com'
32
- api = HttpWrapper.new('https://' + addr, credential)
33
32
  @opts = {
34
- addr: addr,
35
33
  credential: credential,
36
34
  ledger_name: ledger_name,
37
- team_name: team_name(api),
38
35
  }
36
+ @session = Session.new(@opts)
39
37
  end
40
38
 
41
39
  # @private
@@ -45,23 +43,31 @@ module Sequence
45
43
 
46
44
  # @private
47
45
  # @return [Session]
48
- def session
49
- @session ||= Session.new(@opts)
50
- end
46
+ attr_reader :session
51
47
 
52
48
  # @return [Account::ClientModule]
53
49
  def accounts
54
50
  @accounts ||= Account::ClientModule.new(self)
55
51
  end
56
52
 
53
+ # @return [Action::ClientModule]
54
+ def actions
55
+ @actions ||= Action::ClientModule.new(self)
56
+ end
57
+
58
+ # @return [Feed::ClientModule]
59
+ def feeds
60
+ @feeds ||= Feed::ClientModule.new(self)
61
+ end
62
+
57
63
  # @return [Flavor::ClientModule]
58
64
  def flavors
59
65
  @flavors ||= Flavor::ClientModule.new(self)
60
66
  end
61
67
 
62
- # @return [Action::ClientModule]
63
- def actions
64
- @actions ||= Action::ClientModule.new(self)
68
+ # @return [Index::ClientModule]
69
+ def indexes
70
+ @indexes ||= Index::ClientModule.new(self)
65
71
  end
66
72
 
67
73
  # @return [Key::ClientModule]
@@ -69,6 +75,12 @@ module Sequence
69
75
  @keys ||= Key::ClientModule.new(self)
70
76
  end
71
77
 
78
+ # @private
79
+ # @return [Stats::ClientModule]
80
+ def stats
81
+ @stats ||= Stats::ClientModule.new(self)
82
+ end
83
+
72
84
  # @return [Token::ClientModule]
73
85
  def tokens
74
86
  @tokens ||= Token::ClientModule.new(self)
@@ -79,26 +91,9 @@ module Sequence
79
91
  @transactions ||= Transaction::ClientModule.new(self)
80
92
  end
81
93
 
82
- # @return [Feed::ClientModule]
83
- def feeds
84
- @feeds ||= Feed::ClientModule.new(self)
85
- end
86
-
87
- # @private
88
- # @return [Stats::ClientModule]
89
- def stats
90
- @stats ||= Stats::ClientModule.new(self)
91
- end
92
-
93
94
  # @return [DevUtils::ClientModule]
94
95
  def dev_utils
95
96
  @dev_utils ||= DevUtils::ClientModule.new(self)
96
97
  end
97
-
98
- private
99
-
100
- def team_name(api)
101
- api.post(SecureRandom.hex(10), '/hello', {})[:parsed_body]['team_name']
102
- end
103
98
  end
104
99
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sequence
4
+ # @private
5
+ class Hello
6
+ def initialize(api)
7
+ @api = api
8
+ end
9
+
10
+ def call
11
+ b = @api.post(SecureRandom.hex(10), '/hello', {})[:parsed_body]
12
+ [b['team_name'], b['addr'], b['addr_ttl_seconds'].to_i]
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './client_module'
4
+ require_relative './session'
5
+ require_relative './query'
6
+ require_relative './response_object'
7
+
8
+ module Sequence
9
+ # Indexes are used to precompute queries that could
10
+ # potentially be slow. When an application submits a
11
+ # query where the filter and group-by params match
12
+ # one of the defined indexes, the results can be
13
+ # returned from quickly from precomputed storage.
14
+ class Index < ResponseObject
15
+ # @!attribute [r] id
16
+ # Unique identifier of the index
17
+ # @return [String]
18
+ attrib :id
19
+
20
+ # @!attribute [r] type
21
+ # Type of index, "action" or "token".
22
+ # @return [String]
23
+ attrib :type
24
+
25
+ # @!attribute [r] filter
26
+ # The query filter used to select matching items.
27
+ # @return [String]
28
+ attrib :filter
29
+
30
+ # @!attribute [r] group_by
31
+ # Token/Action object fields to group by.
32
+ # @return [String]
33
+ attrib :group_by
34
+
35
+ class ClientModule < Sequence::ClientModule
36
+ # Create an index.
37
+ # @param id [String]
38
+ # Unique identifier. Auto-generated if not specified.
39
+ # @return [Index]
40
+ def create(id: nil, type:, filter:, group_by: [])
41
+ Index.new(client.session.request(
42
+ 'create-index',
43
+ id: id,
44
+ type: type,
45
+ filter: filter,
46
+ group_by: group_by,
47
+ ))
48
+ end
49
+
50
+ # Delete index by id.
51
+ # @option id [String] The unique ID of an index.
52
+ # @return [void]
53
+ def delete(id:)
54
+ client.session.request('delete-index', id: id)
55
+ nil
56
+ end
57
+
58
+ # List all indexes.
59
+ # Executes a query, returning an enumerable over individual indexes.
60
+ # @return [Query]
61
+ def list
62
+ Query.new(client)
63
+ end
64
+ end
65
+
66
+ class Query < Sequence::Query
67
+ def fetch(query)
68
+ client.session.request('list-indexes', query)
69
+ end
70
+
71
+ def translate(obj)
72
+ Index.new(obj)
73
+ end
74
+ end
75
+ end
76
+ end
@@ -5,6 +5,7 @@ require 'json'
5
5
  require_relative './http_wrapper'
6
6
  require_relative './errors'
7
7
  require_relative './version'
8
+ require_relative './hello'
8
9
 
9
10
  module Sequence
10
11
  # @private
@@ -19,11 +20,11 @@ module Sequence
19
20
  ArgumentError,
20
21
  'missing credential',
21
22
  )
22
- @team_name = @opts[:team_name] || raise(
23
- ArgumentError,
24
- 'missing team_name',
25
- )
26
- @ledger_api = HttpWrapper.new('https://' + @opts[:addr], @credential, @opts)
23
+
24
+ @lock = Mutex.new # protects the following instance variables
25
+ @team_name, @addr, ttl_seconds = hello.call
26
+ @api = api(@addr)
27
+ @deadline = now + ttl_seconds
27
28
  end
28
29
 
29
30
  def dup
@@ -36,7 +37,20 @@ module Sequence
36
37
 
37
38
  def request_full_resp(id, path, body = {})
38
39
  id ||= SecureRandom.hex(10)
39
- @ledger_api.post(id, ledger_url(path), body) do |response|
40
+ deadline = nil
41
+ api = nil
42
+
43
+ @lock.synchronize do
44
+ deadline = @deadline
45
+ api = @api
46
+ path = "/#{@team_name}/#{@ledger}/#{path}".gsub('//', '/')
47
+ end
48
+
49
+ if now >= deadline
50
+ refresh
51
+ end
52
+
53
+ api.post(id, path, body) do |response|
40
54
  # require that the response contains the Chain-Request-ID
41
55
  # http header. Since the Sequence API will always set this
42
56
  # header, its absence indicates that the request stopped at
@@ -52,9 +66,44 @@ module Sequence
52
66
 
53
67
  private
54
68
 
55
- def ledger_url(path)
56
- path = path[1..-1] if path.start_with?('/')
57
- "/#{@team_name}/#{@ledger}/#{path}"
69
+ def refresh
70
+ Thread.new do
71
+ # extend the deadline long enough to get a fresh addr
72
+ @lock.synchronize do
73
+ @deadline = now + HttpWrapper::RETRY_TIMEOUT_SECS
74
+ end
75
+
76
+ begin
77
+ new_team_name, new_addr, ttl_seconds = hello.call
78
+ rescue StandardError # rubocop:disable Lint/HandleExceptions
79
+ # use existing values while trying for a successful /hello
80
+ else
81
+ @lock.synchronize do
82
+ @deadline = now + ttl_seconds
83
+
84
+ # unless addr changed, use existing API client
85
+ # in order to re-use the TLS connection
86
+ if @addr != new_addr
87
+ @addr = new_addr
88
+ @api = api(new_addr)
89
+ end
90
+
91
+ @team_name = new_team_name
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ def now
98
+ Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i
99
+ end
100
+
101
+ def hello
102
+ Sequence::Hello.new(api(ENV['SEQADDR'] || 'api.seq.com'))
103
+ end
104
+
105
+ def api(addr)
106
+ HttpWrapper.new('https://' + addr, @credential, @opts)
58
107
  end
59
108
  end
60
109
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sequence
4
- VERSION = '2.1'
4
+ VERSION = '2.2.rc.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequence-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: '2.1'
4
+ version: 2.2.rc.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chain Engineering
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-16 00:00:00.000000000 Z
11
+ date: 2018-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -86,20 +86,6 @@ dependencies:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
88
  version: 0.14.1
89
- - !ruby/object:Gem::Dependency
90
- name: webmock
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "~>"
94
- - !ruby/object:Gem::Version
95
- version: 2.3.2
96
- type: :development
97
- prerelease: false
98
- version_requirements: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: 2.3.2
103
89
  - !ruby/object:Gem::Dependency
104
90
  name: yard
105
91
  requirement: !ruby/object:Gem::Requirement
@@ -137,7 +123,9 @@ files:
137
123
  - lib/sequence/errors.rb
138
124
  - lib/sequence/feed.rb
139
125
  - lib/sequence/flavor.rb
126
+ - lib/sequence/hello.rb
140
127
  - lib/sequence/http_wrapper.rb
128
+ - lib/sequence/index.rb
141
129
  - lib/sequence/key.rb
142
130
  - lib/sequence/page.rb
143
131
  - lib/sequence/query.rb
@@ -162,9 +150,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
162
150
  version: '2.3'
163
151
  required_rubygems_version: !ruby/object:Gem::Requirement
164
152
  requirements:
165
- - - ">="
153
+ - - ">"
166
154
  - !ruby/object:Gem::Version
167
- version: '0'
155
+ version: 1.3.1
168
156
  requirements: []
169
157
  rubyforge_project:
170
158
  rubygems_version: 2.7.6