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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8c05601cd8f8684c1523aa4b92d87d10afad700c50d197e40b6886fd4bc9412
4
- data.tar.gz: ddc3d0616655b4bda4a40ecf1a96af9c17c5ef54d7c372a05bdf9eb29c2dcdee
3
+ metadata.gz: 9ac898ae13038db9d3426f367e3cba3b54c41e35797dfb56dd5da5595959e728
4
+ data.tar.gz: 2bf9f24929b226b8994b3f4648f67b5da59aa0b68687cb7f597f531ac2d7bb99
5
5
  SHA512:
6
- metadata.gz: 1bfb463dbed7826bf9cad245c53cca76b5ec0c0bc35ddeb42c24c0e9789e93d77adf45e12c772dfcb764e60ffbe3724ecbebb0106bbead653030db1a458df275
7
- data.tar.gz: aadd4c0108d6871683c90f4d0d8647f80f072a34e0d4597ec9d4fcb97a9e9494e085b6fe93481925d71a594e0a110ef6575d0499ede0e407d517727bdb0b9baf
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 during file exporting. 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
+ * `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',
@@ -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, :max_retries_export
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
- retries = 0
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
- opts = LokaliseRails.import_opts
34
-
35
- api_client.download_files project_id_with_branch, opts
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LokaliseRails
4
- VERSION = '2.0.0.rc1'
4
+ VERSION = '2.0.0'
5
5
  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(3).times
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.rc1
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-12 00:00:00.000000000 Z
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: 1.3.1
260
+ version: '0'
261
261
  requirements: []
262
262
  rubygems_version: 3.2.25
263
263
  signing_key: