microget 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de1316815435cc4a99b3d2a7c6f13b0e43015d87
4
- data.tar.gz: 13e92c78deb579b3fd98ff7ccc48bf6c659595b0
3
+ metadata.gz: 10904aa7598a374362dd5086d3b033a8f5a296a1
4
+ data.tar.gz: f61403282080b0722189d571436a8c6dfa89189a
5
5
  SHA512:
6
- metadata.gz: 220d1cada56fdded21fc72b5970505b93bb92f582ffda2eeca4a2f99e583ed1e2abbf02074f73182632ad560f15a4f6ebf00998f8ee97749da2f160089c50d15
7
- data.tar.gz: 8d09e070e936bf79bdb53ec97af71b31eaeba3f3b41dfa4cffa2267fb77a5efe9146412d35edd52cceb4db5b509b5c0194f1e1e8984c217de2556b225b027d59
6
+ metadata.gz: 141b9588147336dc6656f8c49ab6c3c438ea551baaec13cfd2edab42509406ba4ca60fd6aaf37e8b0f37722c220daf4d7b6a04b4bae567a1bba70bf19caec793
7
+ data.tar.gz: 8a2b5cd9b07e850f23ed17f5990a20054193c9effcee6ec66983c6758f615dc5b9c96d6534aa165f7d9a9cfc1dd52816c816160a4177406a19c7c73e2ae2c895
data/Gemfile CHANGED
@@ -8,7 +8,7 @@ source "http://rubygems.org"
8
8
  group :development do
9
9
  gem 'puma'
10
10
  gem 'yard'
11
- gem "rspec", "~> 3.3.0"
11
+ gem "rspec", "~> 3.2.0", "< 3.3"
12
12
  gem "rdoc", "~> 3.12"
13
13
  gem "bundler", "~> 1.0"
14
14
  gem "jeweler", "~> 2.0.1"
data/lib/microget.rb CHANGED
@@ -3,7 +3,9 @@ require 'socket'
3
3
 
4
4
  # An no-nonsense, pedal-to-the-metal unbuffered HTTP streaming client for doing GETs of large bodies, fast.
5
5
  module Microget
6
- VERSION = '1.0.0'
6
+ autoload :ServerRunner, File.dirname(__FILE__) + '/microget/server_runner'
7
+
8
+ VERSION = '1.1.0'
7
9
 
8
10
  extend self
9
11
 
@@ -26,6 +28,8 @@ module Microget
26
28
  raise ('Only plain HTTP is supported (%s)' % uri) unless uri.scheme == 'http'
27
29
  raise "Unknown host" unless uri.host
28
30
 
31
+ # Some reading on what might be usable here:
32
+ # http://www.mikeperham.com/2009/03/15/socket-timeouts-in-ruby/
29
33
  socket = TCPSocket.open(uri.host, uri.port || 80)
30
34
  socket.write("GET #{uri.request_uri} HTTP/1.1\r\n")
31
35
 
@@ -65,24 +69,25 @@ module Microget
65
69
  def perform_get(uri, request_headers: {}, chunk_size: 1024 * 1024 * 5)
66
70
  status_code, header_hash, socket = get_status_headers_and_body_socket(uri, request_headers: request_headers)
67
71
  body_bytes_received = 0
72
+
73
+ # Yield the status and headers once with an empty response
74
+ # so that the client can bail out of the request even before the body
75
+ # starts to arrive
76
+ return body_bytes_received unless yield(status_code, header_hash, '')
77
+
68
78
  # ...and then just read the body, without any buffering, using a non-blocking read
69
79
  while !socket.eof?
70
80
  begin
71
81
  data = socket.read_nonblock(chunk_size)
72
82
  body_bytes_received += data.bytesize
73
- return unless yield(status_code, header_hash, data)
83
+ continue_reading = yield(status_code, header_hash, data)
84
+ return body_bytes_received unless continue_reading
74
85
  rescue IO::WaitReadable
75
86
  IO.select([socket], [], SOCKET_TIMEOUT)
76
87
  retry
77
88
  end
78
89
  end
79
90
 
80
- # Yield the status and headers once with an empty response
81
- # so that the client gets at least something.
82
- if body_bytes_received.zero?
83
- yield(status_code, header_hash, '')
84
- end
85
-
86
91
  body_bytes_received
87
92
  ensure
88
93
  socket.close if socket && !socket.closed?
@@ -0,0 +1,60 @@
1
+ require 'net/http'
2
+
3
+ # A simplistic runner for external web servers within a separate process.
4
+ class Microget::ServerRunner < Struct.new(:name, :command, :port, :rackup_file_path)
5
+ SHOULD_CONNECT_WITHIN = 2
6
+
7
+ def command
8
+ super % [port, rackup_file_path]
9
+ end
10
+
11
+ def start!
12
+ # Boot Puma in a forked process
13
+ @pid = fork do
14
+ $stderr.puts "Spinning up with #{command.inspect}"
15
+
16
+ # Do not pollute the test suite output with the Puma logs,
17
+ # save the stuff to logfiles instead
18
+ $stdout.reopen(File.open('server_runner_%s_stdout.log' % name, 'a'))
19
+ $stderr.reopen(File.open('server_runner_%s_stderr.log' % name, 'a'))
20
+
21
+ # Since we have to do with timing tolerances, having the output drip in ASAP is useful
22
+ $stdout.sync = true
23
+ $stderr.sync = true
24
+ exec(command)
25
+ end
26
+
27
+ Thread.abort_on_exception = true
28
+
29
+ t = Time.now
30
+ # Wait for Puma to be online, poll the alive URL until it stops responding
31
+ loop do
32
+ sleep 0.5
33
+ begin
34
+ alive_check_url = "http://0.0.0.0:%d/" % port
35
+ response = Net::HTTP.get_response(URI(alive_check_url))
36
+ @running = true
37
+ break
38
+ rescue Errno::ECONNREFUSED
39
+ if (Time.now - t) > SHOULD_CONNECT_WITHIN # Timeout when starting
40
+ raise "Could not get the server started in 2 seconds, something might be misconfigured"
41
+ end
42
+ end
43
+ end
44
+
45
+ trap("TERM") { stop! }
46
+ end
47
+
48
+ def running?
49
+ !!@running
50
+ end
51
+
52
+ def stop!
53
+ return unless @pid
54
+
55
+ # Tell the webserver to quit, twice (we do not care if there are running responses)
56
+ %W( TERM TERM KILL ).each {|sig| Process.kill(sig, @pid); sleep 0.5 }
57
+ @pid = nil
58
+ @running = false
59
+ end
60
+ end
data/microget.gemspec ADDED
@@ -0,0 +1,72 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: microget 1.1.0 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "microget"
9
+ s.version = "1.1.0"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
13
+ s.authors = ["Julik Tarkhanov"]
14
+ s.date = "2015-11-04"
15
+ s.description = "Pedal-to-the-metal HTTP client for GET requests"
16
+ s.email = "me@julik.nl"
17
+ s.extra_rdoc_files = [
18
+ "LICENSE.txt",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".rspec",
24
+ ".yardopts",
25
+ "Gemfile",
26
+ "LICENSE.txt",
27
+ "README.md",
28
+ "Rakefile",
29
+ "lib/microget.rb",
30
+ "lib/microget/server_runner.rb",
31
+ "microget.gemspec",
32
+ "spec/helper.rb",
33
+ "spec/microget_spec.rb",
34
+ "spec/microget_with_real_server_spec.rb",
35
+ "spec/streaming_app.ru"
36
+ ]
37
+ s.homepage = "http://github.com/julik/microget"
38
+ s.licenses = ["MIT"]
39
+ s.rubygems_version = "2.2.2"
40
+ s.summary = "Designed for slow and/or large response bodies"
41
+
42
+ if s.respond_to? :specification_version then
43
+ s.specification_version = 4
44
+
45
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
46
+ s.add_development_dependency(%q<puma>, [">= 0"])
47
+ s.add_development_dependency(%q<yard>, [">= 0"])
48
+ s.add_development_dependency(%q<rspec>, ["< 3.3", "~> 3.2.0"])
49
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
50
+ s.add_development_dependency(%q<bundler>, ["~> 1.0"])
51
+ s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
52
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
53
+ else
54
+ s.add_dependency(%q<puma>, [">= 0"])
55
+ s.add_dependency(%q<yard>, [">= 0"])
56
+ s.add_dependency(%q<rspec>, ["< 3.3", "~> 3.2.0"])
57
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
58
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
59
+ s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
60
+ s.add_dependency(%q<simplecov>, [">= 0"])
61
+ end
62
+ else
63
+ s.add_dependency(%q<puma>, [">= 0"])
64
+ s.add_dependency(%q<yard>, [">= 0"])
65
+ s.add_dependency(%q<rspec>, ["< 3.3", "~> 3.2.0"])
66
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
67
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
68
+ s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
69
+ s.add_dependency(%q<simplecov>, [">= 0"])
70
+ end
71
+ end
72
+
data/spec/helper.rb CHANGED
@@ -3,4 +3,3 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
 
4
4
  require 'rspec'
5
5
  require 'microget'
6
- require_relative 'server_runner'
@@ -3,9 +3,8 @@ require_relative 'helper'
3
3
  describe "Microget running against a real server" do
4
4
  before :all do
5
5
  rack_app = File.expand_path(File.join(__dir__, 'streaming_app.ru'))
6
- @server = ServerRunner.new("bundle exec puma --port %d %s", 9393, rack_app)
6
+ @server = Microget::ServerRunner.new(:puma, "bundle exec puma --port %d %s", 9393, rack_app)
7
7
  @server.start!
8
- sleep 0.5 until @server.running?
9
8
  end
10
9
 
11
10
  after :all do
@@ -49,6 +48,9 @@ describe "Microget running against a real server" do
49
48
  t = Time.now
50
49
  end
51
50
 
51
+ first_chunk_and_delta = time_deltas_and_chunks.shift
52
+ expect(first_chunk_and_delta[1]).to be_empty # First chunk is empty to allow header/status checks
53
+
52
54
  time_deltas_and_chunks.each do |(delta, chunk_contents)|
53
55
  expect(chunk_contents).to include('Message number ')
54
56
  expect(delta).to be_within(0.2).of(1.0) # The server "drips" down one message every second, approximately
@@ -61,6 +61,10 @@ map '/with-content-length' do
61
61
  run StreamerWithLength
62
62
  end
63
63
 
64
+ map '/' do
65
+ run ->(env) { [200, {}, ['Yes']]}
66
+ end
67
+
64
68
  map '/alive' do
65
69
  run ->(env) { [200, {}, ['Yes']]}
66
70
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: microget
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-01 00:00:00.000000000 Z
11
+ date: 2015-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: puma
@@ -42,16 +42,22 @@ dependencies:
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
+ - - "<"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.3'
45
48
  - - "~>"
46
49
  - !ruby/object:Gem::Version
47
- version: 3.3.0
50
+ version: 3.2.0
48
51
  type: :development
49
52
  prerelease: false
50
53
  version_requirements: !ruby/object:Gem::Requirement
51
54
  requirements:
55
+ - - "<"
56
+ - !ruby/object:Gem::Version
57
+ version: '3.3'
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: 3.3.0
60
+ version: 3.2.0
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: rdoc
57
63
  requirement: !ruby/object:Gem::Requirement
@@ -124,11 +130,11 @@ files:
124
130
  - README.md
125
131
  - Rakefile
126
132
  - lib/microget.rb
133
+ - lib/microget/server_runner.rb
134
+ - microget.gemspec
127
135
  - spec/helper.rb
128
136
  - spec/microget_spec.rb
129
137
  - spec/microget_with_real_server_spec.rb
130
- - spec/server_runner.rb
131
- - spec/spec_helper.rb
132
138
  - spec/streaming_app.ru
133
139
  homepage: http://github.com/julik/microget
134
140
  licenses:
@@ -1,57 +0,0 @@
1
- require 'net/http'
2
-
3
- class ServerRunner < Struct.new(:command, :port, :rackup_file_path)
4
- def command
5
- super % [port, rackup_file_path]
6
- end
7
-
8
- def start!
9
- # Boot Puma in a forked process
10
- @pid = fork do
11
- $stderr.puts "Spinning up with #{command.inspect}"
12
- # Do not pollute the RSpec output with the Puma logs,
13
- # save the stuff to logfiles instead
14
- # $stdout.reopen(File.open('server_runner_stdout.log' % name, 'a'))
15
- # $stderr.reopen(File.open('server_runner_stderr.log' % name, 'a'))
16
-
17
- # Since we have to do with timing tolerances, having the output drip in ASAP is useful
18
- $stdout.sync = true
19
- $stderr.sync = true
20
- exec(command)
21
- end
22
-
23
- Thread.abort_on_exception = true
24
-
25
- Thread.new do
26
- t = Time.now
27
- # Wait for Puma to be online, poll the alive URL until it stops responding
28
- loop do
29
- sleep 0.5
30
- begin
31
- alive_check_url = "http://0.0.0.0:%d/alive" % port
32
- response = Net::HTTP.get_response(URI(alive_check_url))
33
- @running = true
34
- break
35
- rescue Errno::ECONNREFUSED
36
- if Time.now - t > 2 # Timeout when starting
37
- raise "Could not get the server started in 2 seconds, something might be misconfigured"
38
- end
39
- end
40
- end
41
- end
42
-
43
- trap("TERM") { stop! }
44
- end
45
-
46
- def running?
47
- !!@running
48
- end
49
-
50
- def stop!
51
- return unless @pid
52
-
53
- # Tell the webserver to quit, twice (we do not care if there are running responses)
54
- %W( TERM TERM KILL ).each {|sig| Process.kill(sig, @pid); sleep 0.5 }
55
- @pid = nil
56
- end
57
- end
data/spec/spec_helper.rb DELETED
@@ -1,6 +0,0 @@
1
- require 'simplecov'
2
-
3
-
4
- RSpec.configure do |config|
5
-
6
- end