random-port 0.3.0 → 0.3.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: 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