random-port 0.3.0 → 0.3.1

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: 1dbc9a31f4b53484b240f4f2bb37c7f1ed9208bc1e5e31b09df8c95c9aa909d1
4
- data.tar.gz: 9d6f1d3e5a912ffa03ac3a168bc47d1492775435276a709a33d918b5b103ec00
3
+ metadata.gz: 8d89270eaf87254ef245e9a207758052081e2d50b530d3d0f893bda91e35406d
4
+ data.tar.gz: 61261be32c1b20a47306df4773ecd527e86efc20d8cb734d127cdeb6fa92a8cf
5
5
  SHA512:
6
- metadata.gz: d382bafa4db3b722d8ebefda93d5c5460a3e61581bab49646cc804841f4f7edafb9203c2006557c16ef6aa6b6111ed9db011cd68f3a104b1a165fc8834e31f40
7
- data.tar.gz: d1318acea077ce7df07d2d514c6b9f676581c8d2b69ddb43337cc148567cdeb16f7c1584559723833319053ae287dbba6ca228a9d236493d6bd52b9433441d3d
6
+ metadata.gz: f6c36601ddfe67c1cd4d427ec3d7afd9a2ffaa82f698e13077707cd904b2241ab6fd73ac16bb5e5d2547f239df08a18340d4bf6253fd24514dd73556ca894a84
7
+ data.tar.gz: f46462e3038d131436fdbd82cdd3e65ae413c005f4e30a6652bda1a09a1560018fcb1c94f6fbd4ff8830bdcea468c76833f41666dd04ccfe18123bceee416d95
@@ -2,7 +2,7 @@ AllCops:
2
2
  DisplayCopNames: true
3
3
  TargetRubyVersion: 2.3.3
4
4
 
5
- Style/FileName:
5
+ Naming/FileName:
6
6
  Enabled: false
7
7
  Metrics/MethodLength:
8
8
  Max: 50
data/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
  [![Build Status](https://travis-ci.org/yegor256/random-port.svg)](https://travis-ci.org/yegor256/random-port)
5
5
  [![Gem Version](https://badge.fury.io/rb/random-port.svg)](http://badge.fury.io/rb/random-port)
6
6
  [![Maintainability](https://api.codeclimate.com/v1/badges/349b8c31884d3b34d926/maintainability)](https://codeclimate.com/github/yegor256/random-port/maintainability)
7
+ [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://rubydoc.info/github/yegor256/random-port/master/frames)
7
8
 
8
9
  It's a simple Ruby gem to get a random TCP port.
9
10
 
@@ -46,7 +47,9 @@ RandomPort::Pool::SINGLETON.acquire do |port|
46
47
  end
47
48
  ```
48
49
 
49
- The pool is _not_ thread-safe.
50
+ The pool is thread-safe by default.
51
+ You can configure it to be
52
+ not-thread-safe, using optional `sync` argument of the constructor.
50
53
 
51
54
  # How to contribute
52
55
 
@@ -23,39 +23,62 @@
23
23
  # SOFTWARE.
24
24
 
25
25
  require 'socket'
26
+ require 'monitor'
26
27
 
27
28
  module RandomPort
28
29
  # Pool of TPC ports.
29
30
  #
30
- # The class is NOT thread-safe!
31
+ # Use it like this:
32
+ #
33
+ # RandomPort::Pool.new.acquire do |port|
34
+ # # Use the TCP port. It will be returned back
35
+ # # to the pool afterwards.
36
+ # end
37
+ #
38
+ # The class is thread-safe, by default. You can configure it to be
39
+ # not-thread-safe, using optional <tt>sync</tt> argument of the constructor.
31
40
  #
32
41
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
33
42
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
34
43
  # License:: MIT
35
44
  class Pool
36
- def initialize
45
+ def initialize(sync: false)
37
46
  @ports = []
47
+ @sync = sync
48
+ @monitor = Monitor.new
38
49
  end
39
50
 
40
51
  # Application wide pool of ports
41
52
  SINGLETON = Pool.new
42
53
 
54
+ # Acquire a new random TCP port.
43
55
  def acquire
44
56
  loop do
45
57
  server = TCPServer.new('127.0.0.1', 0)
46
58
  port = server.addr[1]
47
59
  server.close
48
60
  next if @ports.include?(port)
49
- @ports << port
61
+ safe { @ports << port }
50
62
  return port unless block_given?
51
63
  yield port
52
- @ports.delete(port)
64
+ safe { @ports.delete(port) }
53
65
  break
54
66
  end
55
67
  end
56
68
 
69
+ # Return it back to the pool.
57
70
  def release(port)
58
- @ports.delete(port)
71
+ safe { @ports.delete(port) }
72
+ end
73
+
74
+ private
75
+
76
+ def safe
77
+ if @sync
78
+ @monitor.synchronize { yield }
79
+ else
80
+ yield
81
+ end
59
82
  end
60
83
  end
61
84
  end
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
31
31
  s.rubygems_version = '2.3.3'
32
32
  s.required_ruby_version = '>=2.3'
33
33
  s.name = 'random-port'
34
- s.version = '0.3.0'
34
+ s.version = '0.3.1'
35
35
  s.license = 'MIT'
36
36
  s.summary = 'Random TCP port'
37
37
  s.description = 'Reserves a random TCP port'
@@ -42,9 +42,9 @@ Gem::Specification.new do |s|
42
42
  s.test_files = s.files.grep(%r{^(test)/})
43
43
  s.rdoc_options = ['--charset=UTF-8']
44
44
  s.extra_rdoc_files = ['README.md']
45
- s.add_development_dependency 'minitest', '~>5.11'
46
- s.add_development_dependency 'rake', '~>12.3'
47
- s.add_development_dependency 'rdoc', '~>4.2'
45
+ s.add_development_dependency 'minitest', '5.11.3'
46
+ s.add_development_dependency 'rake', '12.3.1'
47
+ s.add_development_dependency 'rdoc', '4.3.0'
48
48
  s.add_development_dependency 'rubocop', '0.58.1'
49
49
  s.add_development_dependency 'rubocop-rspec', '1.27.0'
50
50
  end
@@ -52,5 +52,18 @@ module RandomPort
52
52
  assert(port.positive?)
53
53
  end
54
54
  end
55
+
56
+ def test_acquires_unique_numbers
57
+ total = 25
58
+ numbers = (0..total - 1).map { Pool::SINGLETON.acquire }
59
+ assert_equal(total, numbers.uniq.count)
60
+ end
61
+
62
+ def test_acquires_unique_numbers_in_no_sync_mode
63
+ total = 25
64
+ pool = Pool.new(sync: false)
65
+ numbers = (0..total - 1).map { pool.acquire }
66
+ assert_equal(total, numbers.uniq.count)
67
+ end
55
68
  end
56
69
  end
metadata CHANGED
@@ -1,57 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: random-port
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-27 00:00:00.000000000 Z
11
+ date: 2018-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: '5.11'
19
+ version: 5.11.3
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: '5.11'
26
+ version: 5.11.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: '12.3'
33
+ version: 12.3.1
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: '12.3'
40
+ version: 12.3.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rdoc
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: '4.2'
47
+ version: 4.3.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: '4.2'
54
+ version: 4.3.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rubocop
57
57
  requirement: !ruby/object:Gem::Requirement