copy_tuner_client 0.20.1 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.vscode/settings.json +4 -0
- data/lib/copy_tuner_client/cache.rb +15 -8
- data/lib/copy_tuner_client/client.rb +29 -5
- data/lib/copy_tuner_client/configuration.rb +6 -1
- data/lib/copy_tuner_client/rails.rb +3 -2
- data/lib/copy_tuner_client/version.rb +1 -1
- data/spec/copy_tuner_client/cache_spec.rb +6 -28
- data/spec/copy_tuner_client/client_spec.rb +7 -0
- data/spec/support/fake_client.rb +1 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a06b43d1cbb58dfca8f7e340a52e0533cb1398b20e966702822ee90f3253515c
|
4
|
+
data.tar.gz: a751f0743edb5dc80802d08647c3ebeca82809f5034b6b14177d607f57c247bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f9de9656e80ff2ee79385663e60deecb0df8b3f0f5aa9f5a226dd60b1e1bc92dc287b522e04fcd8ced28fa5e37e98de112e0688ed3bbcdc0719bde21a554bc0
|
7
|
+
data.tar.gz: ff0f9f4f2fc05b37fcfe5395db70615fc4c8c019db48858c8e1c799faa907e35916e636a4fda0f6a91410d1db3b6a9b3f1e44ca731ca81faf3a491ef64cba4a6
|
data/.vscode/settings.json
CHANGED
@@ -8,6 +8,10 @@ module CopyTunerClient
|
|
8
8
|
#
|
9
9
|
# Responsible for locking down access to data used by both threads.
|
10
10
|
class Cache
|
11
|
+
STATUS_NOT_READY = :not_ready
|
12
|
+
STATUS_PENDING = :pending
|
13
|
+
STATUS_READY = :ready
|
14
|
+
|
11
15
|
# Usually instantiated when {Configuration#apply} is invoked.
|
12
16
|
# @param client [Client] the client used to fetch and upload data
|
13
17
|
# @param options [Hash]
|
@@ -25,8 +29,7 @@ module CopyTunerClient
|
|
25
29
|
@blurbs = {}
|
26
30
|
@blank_keys = Set.new
|
27
31
|
@queued = {}
|
28
|
-
@
|
29
|
-
@downloaded = false
|
32
|
+
@status = STATUS_NOT_READY
|
30
33
|
end
|
31
34
|
|
32
35
|
# Returns content for the given blurb.
|
@@ -97,23 +100,23 @@ module CopyTunerClient
|
|
97
100
|
end
|
98
101
|
|
99
102
|
def download
|
100
|
-
@
|
103
|
+
@status = STATUS_PENDING unless ready?
|
101
104
|
|
102
|
-
res = client.download do |downloaded_blurbs|
|
105
|
+
res = client.download(cache_fallback: pending?) do |downloaded_blurbs|
|
103
106
|
blank_blurbs, blurbs = downloaded_blurbs.partition { |_key, value| value == '' }
|
104
107
|
lock do
|
105
|
-
@blank_keys = Set.new(blank_blurbs.
|
108
|
+
@blank_keys = Set.new(blank_blurbs.map(&:first))
|
106
109
|
@blurbs = blurbs.to_h
|
107
110
|
end
|
108
111
|
end
|
109
112
|
|
110
113
|
@last_downloaded_at = Time.now.utc
|
114
|
+
@status = STATUS_READY unless ready?
|
111
115
|
|
112
116
|
res
|
113
117
|
rescue ConnectionError => e
|
114
118
|
logger.error e.message
|
115
|
-
|
116
|
-
@downloaded = true
|
119
|
+
raise e unless ready?
|
117
120
|
end
|
118
121
|
|
119
122
|
# Downloads and then flushes
|
@@ -129,7 +132,11 @@ module CopyTunerClient
|
|
129
132
|
end
|
130
133
|
|
131
134
|
def pending?
|
132
|
-
@
|
135
|
+
@status == STATUS_PENDING
|
136
|
+
end
|
137
|
+
|
138
|
+
def ready?
|
139
|
+
@status == STATUS_READY
|
133
140
|
end
|
134
141
|
|
135
142
|
private
|
@@ -29,10 +29,16 @@ module CopyTunerClient
|
|
29
29
|
# @option options [Logger] :logger where to log transactions
|
30
30
|
# @option options [String] :ca_file path to root certificate file for ssl verification
|
31
31
|
def initialize(options)
|
32
|
+
@etag = nil
|
33
|
+
@downloaded_blurbs = {}
|
34
|
+
|
32
35
|
[:api_key, :host, :port, :public, :http_read_timeout,
|
33
|
-
:http_open_timeout, :secure, :logger, :ca_file, :s3_host].each do |option|
|
36
|
+
:http_open_timeout, :secure, :logger, :ca_file, :s3_host, :download_cache_dir].each do |option|
|
34
37
|
instance_variable_set "@#{option}", options[option]
|
35
38
|
end
|
39
|
+
|
40
|
+
@download_cache_dir.mkpath
|
41
|
+
load_cachedata(last_download_path)
|
36
42
|
end
|
37
43
|
|
38
44
|
# Downloads all blurbs for the given api_key.
|
@@ -45,7 +51,7 @@ module CopyTunerClient
|
|
45
51
|
#
|
46
52
|
# @yield [Hash] downloaded blurbs
|
47
53
|
# @raise [ConnectionError] if the connection fails
|
48
|
-
def download
|
54
|
+
def download(cache_fallback: false)
|
49
55
|
connect(s3_host) do |http|
|
50
56
|
request = Net::HTTP::Get.new(uri(download_resource))
|
51
57
|
request['If-None-Match'] = @etag
|
@@ -53,15 +59,18 @@ module CopyTunerClient
|
|
53
59
|
t = Time.now
|
54
60
|
response = http.request(request)
|
55
61
|
t_ms = ((Time.now - t) * 1000).to_i
|
56
|
-
|
62
|
+
downloaded = check(response)
|
63
|
+
if downloaded
|
57
64
|
# NOTE: Net::HTTPではgzipが透過的に扱われるため正確なファイルサイズや速度をログに出すのは難しい
|
58
65
|
log "Downloaded translations (#{t_ms}ms)"
|
59
|
-
|
66
|
+
@downloaded_blurbs = JSON.parse(response.body)
|
67
|
+
@etag = response['ETag']
|
68
|
+
last_download_path.write(JSON.pretty_generate(etag: @etag, downloaded_blurbs: @downloaded_blurbs))
|
60
69
|
else
|
61
70
|
log "No new translations (#{t_ms}ms)"
|
62
71
|
end
|
63
72
|
|
64
|
-
@
|
73
|
+
yield(@downloaded_blurbs) if downloaded || cache_fallback
|
65
74
|
end
|
66
75
|
end
|
67
76
|
|
@@ -107,6 +116,21 @@ module CopyTunerClient
|
|
107
116
|
end
|
108
117
|
end
|
109
118
|
|
119
|
+
def last_download_path
|
120
|
+
@download_cache_dir.join("last-download-#{download_resource}")
|
121
|
+
end
|
122
|
+
|
123
|
+
def load_cachedata(pathname)
|
124
|
+
return unless pathname.exist?
|
125
|
+
|
126
|
+
cache = JSON.parse(pathname.read.to_s).transform_keys(&:to_sym)
|
127
|
+
@etag = cache[:etag]
|
128
|
+
@downloaded_blurbs = cache[:downloaded_blurbs]
|
129
|
+
log "Loaded cache data from #{pathname}"
|
130
|
+
rescue JSON::JSONError, Errno::ENOENT, Errno::ENOTDIR
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
|
110
134
|
def connect(host)
|
111
135
|
http = Net::HTTP.new(host, port)
|
112
136
|
http.open_timeout = http_open_timeout
|
@@ -18,7 +18,8 @@ module CopyTunerClient
|
|
18
18
|
proxy_port proxy_user secure polling_delay sync_interval
|
19
19
|
sync_interval_staging sync_ignore_path_regex logger
|
20
20
|
framework middleware disable_middleware disable_test_translation
|
21
|
-
ca_file exclude_key_regexp s3_host locales ignored_keys ignored_key_handler
|
21
|
+
ca_file exclude_key_regexp s3_host locales ignored_keys ignored_key_handler
|
22
|
+
download_cache_dir].freeze
|
22
23
|
|
23
24
|
# @return [String] The API key for your project, found on the project edit form.
|
24
25
|
attr_accessor :api_key
|
@@ -139,6 +140,9 @@ module CopyTunerClient
|
|
139
140
|
# @return [Integer] The project id
|
140
141
|
attr_accessor :project_id
|
141
142
|
|
143
|
+
# @return [Pathname] The directory to cache downloaded files
|
144
|
+
attr_accessor :download_cache_dir
|
145
|
+
|
142
146
|
alias secure? secure
|
143
147
|
|
144
148
|
# Instantiated from {CopyTunerClient.configure}. Sets defaults.
|
@@ -164,6 +168,7 @@ module CopyTunerClient
|
|
164
168
|
self.ignored_keys = []
|
165
169
|
self.ignored_key_handler = ->(e) { raise e }
|
166
170
|
self.project_id = nil
|
171
|
+
self.download_cache_dir = Pathname.new(Dir.pwd).join('tmp', 'cache', 'copy_tuner_client')
|
167
172
|
|
168
173
|
@applied = false
|
169
174
|
end
|
@@ -13,8 +13,9 @@ module CopyTunerClient
|
|
13
13
|
else
|
14
14
|
::Rails.logger
|
15
15
|
end
|
16
|
-
config.framework
|
17
|
-
config.middleware
|
16
|
+
config.framework = "Rails: #{::Rails::VERSION::STRING}"
|
17
|
+
config.middleware = ::Rails.configuration.middleware
|
18
|
+
config.download_cache_dir = ::Rails.root.join('tmp', 'cache', 'copy_tuner_client')
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
@@ -3,10 +3,13 @@ require 'spec_helper'
|
|
3
3
|
describe CopyTunerClient::Cache do
|
4
4
|
let(:client) { FakeClient.new }
|
5
5
|
|
6
|
-
def build_cache(
|
6
|
+
def build_cache(ready: false, **config)
|
7
|
+
config[:client] ||= client
|
7
8
|
config[:logger] ||= FakeLogger.new
|
8
9
|
default_config = CopyTunerClient::Configuration.new.to_hash
|
9
|
-
CopyTunerClient::Cache.new(client, default_config.update(config))
|
10
|
+
cache = CopyTunerClient::Cache.new(client, default_config.update(config))
|
11
|
+
cache.instance_variable_set(:@status, CopyTunerClient::Cache::STATUS_READY) if ready
|
12
|
+
cache
|
10
13
|
end
|
11
14
|
|
12
15
|
it 'provides access to downloaded data' do
|
@@ -143,7 +146,7 @@ describe CopyTunerClient::Cache do
|
|
143
146
|
failure = 'server is napping'
|
144
147
|
logger = FakeLogger.new
|
145
148
|
expect(client).to receive(:download).and_raise(CopyTunerClient::ConnectionError.new(failure))
|
146
|
-
cache = build_cache(logger: logger)
|
149
|
+
cache = build_cache(logger: logger, ready: true)
|
147
150
|
|
148
151
|
cache.download
|
149
152
|
|
@@ -169,31 +172,6 @@ describe CopyTunerClient::Cache do
|
|
169
172
|
expect(t_wait.join(1)).not_to be_nil
|
170
173
|
end
|
171
174
|
|
172
|
-
it "doesn't block if the first download fails" do
|
173
|
-
client.delay = true
|
174
|
-
client.error = StandardError.new('Failure')
|
175
|
-
cache = build_cache
|
176
|
-
|
177
|
-
error = nil
|
178
|
-
t_download = Thread.new do
|
179
|
-
begin
|
180
|
-
cache.download
|
181
|
-
rescue StandardError => e
|
182
|
-
error = e
|
183
|
-
end
|
184
|
-
end
|
185
|
-
sleep 0.1 until cache.pending?
|
186
|
-
|
187
|
-
t_wait = Thread.new do
|
188
|
-
cache.wait_for_download
|
189
|
-
end
|
190
|
-
client.go
|
191
|
-
expect(t_download.join(1)).not_to be_nil
|
192
|
-
expect(error).to be_kind_of(StandardError)
|
193
|
-
expect(t_wait.join(1)).not_to be_nil
|
194
|
-
expect { cache.download }.to raise_error(StandardError, 'Failure')
|
195
|
-
end
|
196
|
-
|
197
175
|
it "doesn't block before downloading" do
|
198
176
|
logger = FakeLogger.new
|
199
177
|
cache = build_cache(logger: logger)
|
@@ -1,8 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CopyTunerClient do
|
4
|
+
let(:download_cache_dir) { Pathname.new(Dir.mktmpdir('copy_tuner_client')) }
|
5
|
+
|
6
|
+
after do
|
7
|
+
FileUtils.rm_rf(download_cache_dir)
|
8
|
+
end
|
9
|
+
|
4
10
|
def build_client(config = {})
|
5
11
|
config[:logger] ||= FakeLogger.new
|
12
|
+
config[:download_cache_dir] = download_cache_dir
|
6
13
|
default_config = CopyTunerClient::Configuration.new.to_hash
|
7
14
|
default_config[:s3_host] = 'copy-tuner.com'
|
8
15
|
client = CopyTunerClient::Client.new(default_config.update(config))
|
data/spec/support/fake_client.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: copy_tuner_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.21.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SonicGarden
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|