ferto 0.1.0 → 0.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c778310b7f3bba9e3d6984c185b7c61ed475e398a38924c34ccecbf490ddb8d
4
- data.tar.gz: 3f027ed81e81275682260282b1b72c09a0469ebb7d026864105a79e3bb0c6ad8
3
+ metadata.gz: c80bb0d54c8592f31f6ea01de91ea12d83f546ab8bf097b130a5a197161705d3
4
+ data.tar.gz: 169b822ff83c13a9be069436c3ae45a62af82eda65fdb7c8b57b3ecccc44ca62
5
5
  SHA512:
6
- metadata.gz: 2745ec8da102954efe1eb8e6682290ca56ab9970816f1411e5e01947d9d61b4fcd69efbc4d329af567dc7f04ff1d9d590a845c245b30bac67bb78633ebabc3bb
7
- data.tar.gz: e3d558ff92fd5bcd542f56a7a924b77119ddaae6bcb4887f966fe34c0c39b221a0d29bac848d16db1793005d90a92aff6b21afc50626e5693cbb7750dc63a0e3
6
+ metadata.gz: 0cd88c6be7c4bf31a98c9cf45b90271ad011411f4136940fd7011548e938e3be0919d12cddcd8389b401b95e26d63d631df9be7aea8f218c8f6a8ce29ef83cc3
7
+ data.tar.gz: 7a94067053ecebe87069bd3a63a5effc0a98748c030981f7d98edb1350fb0cb1310a737420c60900a949028c5517124c47bc96bd2c6ff9bbe90481d7b2857ce9
@@ -13,14 +13,16 @@ jobs:
13
13
  strategy:
14
14
  fail-fast: false
15
15
  matrix:
16
- ruby-version: ['2.7', '3.2']
16
+ ruby-version: ['2.7', '3.2', '3.4', '3.5']
17
17
 
18
18
  steps:
19
- - uses: actions/checkout@v3
19
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
20
20
  - name: Install dependencies
21
- run: sudo apt install -y libcurl4-openssl-dev
21
+ run: |
22
+ sudo apt update
23
+ sudo apt install -y libcurl4-openssl-dev
22
24
  - name: Set up Ruby ${{ matrix.ruby-version }}
23
- uses: ruby/setup-ruby@v1
25
+ uses: ruby/setup-ruby@d45b1a4e94b71acab930e56e79c6aa188764e7f9 # v1.316.0
24
26
  with:
25
27
  ruby-version: ${{ matrix.ruby-version }}
26
28
  - name: Install dependencies
data/CHANGELOG.md CHANGED
@@ -4,6 +4,27 @@ Breaking changes are prefixed with a "[BREAKING]" label.
4
4
 
5
5
  ## master (unreleased)
6
6
 
7
+ ## 0.1.1 (2026-07-11)
8
+
9
+ - Manage a per-thread `Curl::Easy` handle in `Client#download` instead of
10
+ relying on `Curl.post`, whose per-thread handle cache was removed in curb
11
+ 1.3.6. Restores keep-alive connection reuse towards the downloader and
12
+ prevents open-connection pile-up in long-lived workers.
13
+ Note: like every setup before curb 1.3.6, the long-lived cached handle is
14
+ only safe under GC compaction with curb >= 1.3.7 (or a build carrying the
15
+ `curl_easy_mark` pin fix). The gemspec intentionally leaves curb
16
+ unconstrained — the consuming app owns the curb version.
17
+ - [BREAKING] `Ferto::Response` is now a plain snapshot object instead of a
18
+ `SimpleDelegator` around the `Curl::Easy` handle: `response_code` and `body`
19
+ (aliased as `body_str`) are captured when the response is built, so a
20
+ response held across `download` calls keeps its own data instead of
21
+ exposing the reused handle's next request. Other `Curl::Easy` methods are
22
+ no longer forwarded.
23
+ - [BREAKING] `Ferto::ResponseError#response` now returns a `Ferto::Response`
24
+ snapshot instead of the live `Curl::Easy` handle, which a subsequent
25
+ `download` on the same thread would have reset.
26
+ - Add compatibility for Ruby 3.4 and 3.5
27
+
7
28
  ## 0.1.0 (2023-06-16)
8
29
 
9
30
  - Add compatibility for Ruby 3
data/ferto.gemspec CHANGED
@@ -30,4 +30,6 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency "webmock", "~> 3.5"
31
31
  spec.add_development_dependency "factory_bot", "~> 4.10"
32
32
  spec.add_development_dependency "faker"
33
+ spec.add_development_dependency "observer"
34
+ spec.add_development_dependency "ostruct"
33
35
  end
data/lib/ferto/client.rb CHANGED
@@ -109,26 +109,32 @@ module Ferto
109
109
  mime_type, extra, request_headers,
110
110
  s3_bucket, s3_region, subpath
111
111
  )
112
- # Curl.post reuses the same handler
113
112
  begin
114
- res = Curl.post(uri.to_s, body.to_json) do |handle|
115
- handle.headers = build_header(aggr_id)
116
- handle.connect_timeout = connect_timeout
117
- handle.timeout = timeout
118
- end
119
-
120
- case res.response_code
113
+ # Inlines what the Curl.post shortcut did internally (url, post_body,
114
+ # perform) plus the options previously passed in its block, on a
115
+ # handle we manage ourselves.
116
+ handle = curl_handle
117
+ handle.url = uri.to_s
118
+ handle.headers = build_header(aggr_id)
119
+ handle.connect_timeout = connect_timeout
120
+ handle.timeout = timeout
121
+ handle.post_body = body.to_json
122
+ handle.http(:POST)
123
+
124
+ response = Ferto::Response.new(handle)
125
+
126
+ case response.response_code
121
127
  when 400..599
122
128
  error_msg = ("An error occured during the download call. " \
123
- "Received a #{res.response_code} response code and body " \
124
- "#{res.body_str}")
125
- raise Ferto::ResponseError.new(error_msg, res)
129
+ "Received a #{response.response_code} response code and body " \
130
+ "#{response.body}")
131
+ raise Ferto::ResponseError.new(error_msg, response)
126
132
  end
127
133
  rescue Curl::Err::ConnectionFailedError => e
128
134
  raise Ferto::ConnectionError.new(e)
129
135
  end
130
136
 
131
- Ferto::Response.new res
137
+ response
132
138
  end
133
139
 
134
140
  private
@@ -140,6 +146,17 @@ module Ferto
140
146
  }
141
147
  end
142
148
 
149
+ # One handle per thread: curl_easy_reset keeps live connections, so the
150
+ # keep-alive connection to the downloader is reused across calls.
151
+ # Deliberately fiber-local (Thread.current[]): sharing a handle across
152
+ # fibers could let two fibers of one thread enter the same handle
153
+ # mid-transfer under a fiber scheduler; less reuse beats corruption.
154
+ def curl_handle
155
+ handle = Thread.current[:ferto_curl] ||= Curl::Easy.new
156
+ handle.reset
157
+ handle
158
+ end
159
+
143
160
  def build_body(aggr_id, aggr_limit, url, callback_url, callback_type,
144
161
  callback_dst, callback_error_type, callback_error_dst,
145
162
  aggr_proxy, download_timeout, user_agent,
@@ -1,5 +1,17 @@
1
1
  module Ferto
2
- class Response < SimpleDelegator
2
+ # A point-in-time snapshot of a download response. The underlying
3
+ # Curl::Easy handle is reused by the thread's next download, so every
4
+ # field is captured eagerly here and the handle is not retained.
5
+ class Response
6
+ attr_reader :response_code, :body
7
+
8
+ alias body_str body
9
+
10
+ def initialize(handle)
11
+ @response_code = handle.response_code
12
+ @body = handle.body
13
+ end
14
+
3
15
  def job_id
4
16
  @job_id ||= body.nil? ? nil : JSON.parse(body)['id']
5
17
  end
data/lib/ferto/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ferto
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/ferto.rb CHANGED
@@ -23,8 +23,8 @@ module Ferto
23
23
  # Initialize a Ferto::ResponseError
24
24
  #
25
25
  # @param [String] err A string describing the error occured
26
- # @param [Curl::Easy | nil] response a Curl::Easy object
27
- # that represents the response returned by the download method.
26
+ # @param [Ferto::Response | nil] response a snapshot of the
27
+ # response returned by the download method.
28
28
  # Default: nil
29
29
  def initialize(err, response=nil)
30
30
  super(err)
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ferto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aggelos Avgerinos
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2023-06-16 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: curb
@@ -94,6 +93,34 @@ dependencies:
94
93
  - - ">="
95
94
  - !ruby/object:Gem::Version
96
95
  version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: observer
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: ostruct
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ type: :development
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
97
124
  description: Ruby API client for Downloader service
98
125
  email:
99
126
  - avgerinos@skroutz.gr
@@ -121,7 +148,6 @@ homepage: https://github.com/skroutz/ferto
121
148
  licenses:
122
149
  - GPL-3.0
123
150
  metadata: {}
124
- post_install_message:
125
151
  rdoc_options: []
126
152
  require_paths:
127
153
  - lib
@@ -136,8 +162,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
162
  - !ruby/object:Gem::Version
137
163
  version: '0'
138
164
  requirements: []
139
- rubygems_version: 3.4.14
140
- signing_key:
165
+ rubygems_version: 4.0.3
141
166
  specification_version: 4
142
167
  summary: Ruby API client for Downloader
143
168
  test_files: []