lokalise_rails 2.0.0.rc1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +2 -1
- data/lib/generators/templates/lokalise_rails_config.rb +3 -0
- data/lib/lokalise_rails.rb +7 -1
- data/lib/lokalise_rails/task_definition/base.rb +16 -0
- data/lib/lokalise_rails/task_definition/exporter.rb +1 -8
- data/lib/lokalise_rails/task_definition/importer.rb +5 -4
- data/lib/lokalise_rails/version.rb +1 -1
- data/spec/lib/lokalise_rails/task_definition/exporter_spec.rb +1 -1
- data/spec/lib/lokalise_rails/task_definition/importer_spec.rb +17 -0
- data/spec/lib/lokalise_rails_spec.rb +5 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ac898ae13038db9d3426f367e3cba3b54c41e35797dfb56dd5da5595959e728
|
4
|
+
data.tar.gz: 2bf9f24929b226b8994b3f4648f67b5da59aa0b68687cb7f597f531ac2d7bb99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93be5d1f8379908fbf6e3ac7a1f44534373779d8aa3e375f456ef7a83454a07babe3971aa364afe374759e54571d036c60c68e16f14c81397128770573058a9a
|
7
|
+
data.tar.gz: 84c42e122da897f7103a16d11e9a5e066cee28c2b6413c44ec3e459868dfe89d8c5005f3fa644024bea7dfd7c49233de5fecc67746016485f467febe91b3fa52
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 2.0.0 (19-Aug-21)
|
4
|
+
|
5
|
+
* Add exponential backoff mechanism for file imports to comply with the upcoming API changes ("rate limiting"), see below for more details.
|
6
|
+
* Add `max_retries_import` option with a default value of `5`.
|
7
|
+
|
3
8
|
## 2.0.0.rc1 (12-Aug-21)
|
4
9
|
|
5
10
|
* **Lokalise is introducing API rate limiting.** Access to all endpoints will be limited to 6 requests per second from 14 September, 2021. This limit is applied per API token and per IP address. If you exceed the limit, a 429 HTTP status code will be returned and a `Lokalise::Error::TooManyRequests` exception will be raised. Therefore, to overcome this issue LokaliseRails is introducing an exponential backoff mechanism for file exports. Why? Because if you have, say, 10 translation files, we'll have to send 10 separate API requests which will probably mean exceeding the limit (this is not the case with importing as we're always receiving a single archive). Thus, if the HTTP status code 429 was received, we'll do the following:
|
data/README.md
CHANGED
@@ -113,6 +113,7 @@ Options are specified in the `config/lokalise_rails.rb` file.
|
|
113
113
|
|
114
114
|
Full list of available import options [can be found in the official API documentation](https://app.lokalise.com/api2docs/curl/#transition-download-files-post).
|
115
115
|
* `import_safe_mode` (`boolean`) - default to `false`. When this option is enabled, the import task will check whether the directory set with `locales_path` is empty or not. If it is not empty, you will be prompted to continue.
|
116
|
+
* `max_retries_import` (`integer`) - this option is introduced to properly handle Lokalise API rate limiting. If the HTTP status code 429 (too many requests) has been received, LokaliseRails will apply an exponential backoff mechanism with a very simple formula: `2 ** retries`. If the maximum number of retries has been reached, a `Lokalise::Error::TooManyRequests` exception will be raised and the export operation will be halted.
|
116
117
|
|
117
118
|
### Export settings
|
118
119
|
|
@@ -134,7 +135,7 @@ en_US:
|
|
134
135
|
c.skip_file_export = ->(file) { f.split[1].to_s.include?('fr') }
|
135
136
|
```
|
136
137
|
|
137
|
-
* `max_retries_export` (`integer`) - this option is introduced to properly handle Lokalise API rate limiting
|
138
|
+
* `max_retries_export` (`integer`) - this option is introduced to properly handle Lokalise API rate limiting. If the HTTP status code 429 (too many requests) has been received, LokaliseRails will apply an exponential backoff mechanism with a very simple formula: `2 ** retries` (initially `retries` is `0`). If the maximum number of retries has been reached, a `Lokalise::Error::TooManyRequests` exception will be raised and the export operation will be halted. By default, LokaliseRails will make up to `5` retries which potentially means `1 + 2 + 4 + 8 + 16 + 32 = 63` seconds of waiting time. If the `max_retries_export` is less than `1`, LokaliseRails will not perform any retries and give up immediately after receiving error 429.
|
138
139
|
|
139
140
|
### Settings to work with formats other than YAML
|
140
141
|
|
@@ -19,6 +19,9 @@ LokaliseRails.config do |c|
|
|
19
19
|
# Provide maximum number of retries for file exporting:
|
20
20
|
# c.max_retries_export = 5
|
21
21
|
|
22
|
+
# Provide maximum number of retries for file importing:
|
23
|
+
# c.max_retries_import = 5
|
24
|
+
|
22
25
|
# Import options have the following defaults:
|
23
26
|
# c.import_opts = {
|
24
27
|
# format: 'yaml',
|
data/lib/lokalise_rails.rb
CHANGED
@@ -10,7 +10,8 @@ module LokaliseRails
|
|
10
10
|
attr_accessor :api_token, :project_id
|
11
11
|
attr_writer :import_opts, :import_safe_mode, :export_opts, :locales_path,
|
12
12
|
:file_ext_regexp, :skip_file_export, :branch, :timeouts,
|
13
|
-
:translations_loader, :translations_converter, :lang_iso_inferer,
|
13
|
+
:translations_loader, :translations_converter, :lang_iso_inferer,
|
14
|
+
:max_retries_export, :max_retries_import
|
14
15
|
|
15
16
|
# Main interface to provide configuration options for rake tasks
|
16
17
|
def config
|
@@ -37,6 +38,11 @@ module LokaliseRails
|
|
37
38
|
@max_retries_export || 5
|
38
39
|
end
|
39
40
|
|
41
|
+
# Maximum number of retries for file importing
|
42
|
+
def max_retries_import
|
43
|
+
@max_retries_import || 5
|
44
|
+
end
|
45
|
+
|
40
46
|
# Regular expression used to select translation files with proper extensions
|
41
47
|
def file_ext_regexp
|
42
48
|
@file_ext_regexp || /\.ya?ml\z/i
|
@@ -58,6 +58,22 @@ module LokaliseRails
|
|
58
58
|
def project_id_with_branch
|
59
59
|
"#{LokaliseRails.project_id}:#{LokaliseRails.branch}"
|
60
60
|
end
|
61
|
+
|
62
|
+
# Sends request with exponential backoff mechanism
|
63
|
+
def with_exp_backoff(max_retries)
|
64
|
+
return unless block_given?
|
65
|
+
|
66
|
+
retries = 0
|
67
|
+
begin
|
68
|
+
yield
|
69
|
+
rescue Lokalise::Error::TooManyRequests => e
|
70
|
+
raise(e.class, "Gave up after #{retries} retries") if retries >= max_retries
|
71
|
+
|
72
|
+
sleep 2**retries
|
73
|
+
retries += 1
|
74
|
+
retry
|
75
|
+
end
|
76
|
+
end
|
61
77
|
end
|
62
78
|
end
|
63
79
|
end
|
@@ -27,15 +27,8 @@ module LokaliseRails
|
|
27
27
|
# Performs the actual file uploading to Lokalise. If the API rate limit is exceeed,
|
28
28
|
# applies exponential backoff
|
29
29
|
def do_upload(f_path, r_path)
|
30
|
-
|
31
|
-
begin
|
30
|
+
with_exp_backoff(LokaliseRails.max_retries_export) do
|
32
31
|
api_client.upload_file project_id_with_branch, opts(f_path, r_path)
|
33
|
-
rescue Lokalise::Error::TooManyRequests => e
|
34
|
-
raise(e.class, "Gave up after #{retries} retries") if retries >= LokaliseRails.max_retries_export
|
35
|
-
|
36
|
-
sleep 2**retries
|
37
|
-
retries += 1
|
38
|
-
retry
|
39
32
|
end
|
40
33
|
end
|
41
34
|
|
@@ -26,13 +26,14 @@ module LokaliseRails
|
|
26
26
|
true
|
27
27
|
end
|
28
28
|
|
29
|
-
# Downloads files from Lokalise using the specified options
|
29
|
+
# Downloads files from Lokalise using the specified options.
|
30
|
+
# Utilizes exponential backoff if "too many requests" error is received
|
30
31
|
#
|
31
32
|
# @return [Hash]
|
32
33
|
def download_files
|
33
|
-
|
34
|
-
|
35
|
-
|
34
|
+
with_exp_backoff(LokaliseRails.max_retries_import) do
|
35
|
+
api_client.download_files project_id_with_branch, LokaliseRails.import_opts
|
36
|
+
end
|
36
37
|
rescue StandardError => e
|
37
38
|
raise e.class, "There was an error when trying to download files: #{e.message}"
|
38
39
|
end
|
@@ -39,7 +39,7 @@ describe LokaliseRails::TaskDefinition::Exporter do
|
|
39
39
|
allow(fake_class).to receive(:api_client).and_return(fake_client)
|
40
40
|
|
41
41
|
expect(-> { fake_class.export! }).to raise_error(Lokalise::Error::TooManyRequests, /Gave up after 2 retries/i)
|
42
|
-
expect(LokaliseRails).to have_received(:max_retries_export).exactly(
|
42
|
+
expect(LokaliseRails).to have_received(:max_retries_export).exactly(1).times
|
43
43
|
expect(fake_class).to have_received(:api_client).exactly(3).times
|
44
44
|
expect(fake_client).to have_received(:upload_file).exactly(3).times
|
45
45
|
end
|
@@ -25,6 +25,7 @@ describe LokaliseRails::TaskDefinition::Importer do
|
|
25
25
|
expect(response['project_id']).to eq('672198945b7d72fc048021.15940510')
|
26
26
|
expect(response['bundle_url']).to include('s3-eu-west-1.amazonaws.com')
|
27
27
|
expect(described_class.api_client.enable_compression).to eq(true)
|
28
|
+
expect(LokaliseRails.max_retries_import).to eq(5)
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
@@ -38,6 +39,22 @@ describe LokaliseRails::TaskDefinition::Importer do
|
|
38
39
|
end
|
39
40
|
|
40
41
|
describe '.import!' do
|
42
|
+
let(:fake_class) { described_class }
|
43
|
+
|
44
|
+
it 'handles too many requests' do
|
45
|
+
allow_project_id '672198945b7d72fc048021.15940510'
|
46
|
+
allow(LokaliseRails).to receive(:max_retries_import).and_return(2)
|
47
|
+
|
48
|
+
fake_client = double
|
49
|
+
allow(fake_client).to receive(:download_files).and_raise(Lokalise::Error::TooManyRequests)
|
50
|
+
allow(fake_class).to receive(:api_client).and_return(fake_client)
|
51
|
+
|
52
|
+
expect(-> { fake_class.import! }).to raise_error(Lokalise::Error::TooManyRequests, /Gave up after 2 retries/i)
|
53
|
+
expect(LokaliseRails).to have_received(:max_retries_import).exactly(1).times
|
54
|
+
expect(fake_class).to have_received(:api_client).exactly(3).times
|
55
|
+
expect(fake_client).to have_received(:download_files).exactly(3).times
|
56
|
+
end
|
57
|
+
|
41
58
|
it 'halts when the API key is not set' do
|
42
59
|
allow(LokaliseRails).to receive(:api_token).and_return(nil)
|
43
60
|
expect(-> { described_class.import! }).to raise_error(LokaliseRails::Error, /API token is not set/i)
|
@@ -63,6 +63,11 @@ describe LokaliseRails do
|
|
63
63
|
fake_class.max_retries_export = 10
|
64
64
|
end
|
65
65
|
|
66
|
+
it 'is possible to set max_retries_import' do
|
67
|
+
allow(fake_class).to receive(:max_retries_import=).with(10)
|
68
|
+
fake_class.max_retries_import = 10
|
69
|
+
end
|
70
|
+
|
66
71
|
it 'is possible to set api_token' do
|
67
72
|
allow(fake_class).to receive(:api_token=).with('abc')
|
68
73
|
fake_class.api_token = 'abc'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lokalise_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ilya Bodrov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-08-
|
11
|
+
date: 2021-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-lokalise-api
|
@@ -255,9 +255,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
255
255
|
version: 2.5.0
|
256
256
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
257
257
|
requirements:
|
258
|
-
- - "
|
258
|
+
- - ">="
|
259
259
|
- !ruby/object:Gem::Version
|
260
|
-
version:
|
260
|
+
version: '0'
|
261
261
|
requirements: []
|
262
262
|
rubygems_version: 3.2.25
|
263
263
|
signing_key:
|