backport 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
  SHA256:
3
- metadata.gz: ef66ad1688e603cf9a8c9844c5551bbc3ca9187abf747bca2064e46fb7c2600f
4
- data.tar.gz: 3952f19adbe1639f82c98568d4adc97aa0c690d5fa568fef768efbcf6134ee7c
3
+ metadata.gz: 37e4d45bec3b70c07d7bb7ec027399c01ce149f3567ab9f5ddb4661741c8f990
4
+ data.tar.gz: '0906731f50ef216c4bb239fdfffc63f40e086c4e6817849363736c93e1c9b9b7'
5
5
  SHA512:
6
- metadata.gz: 334cb82482d72e1b617fa9fa2a1a1b87764b800e4a8abf6ecc2c63fc012406fb05bf744b362aa6f3211aae0f868ab188902132825602ee3909b54358e2cd1813
7
- data.tar.gz: 2ff55f4495545b50e4e226f961d38b5471cc8d1890a4339091f126139f61422e1ae3af1e1a8c3fc80aafb915b187da099ef312a5e7da1ad4a500f737e9a6909c
6
+ metadata.gz: aa2e6670f6ea2503bcd3ada456522a547c35b18cd4fb12fd38f0a3e00aece71cdae3aa72a168c83ab590d3ea306e8a04b3dc0daec8dd0cc459351cac488907f0
7
+ data.tar.gz: 5eeb2227c5b2f3474b3fbbe6792f0f005f28ce9342b3f395cc596f6cc764741abce8d4daa8cc90dff95d71d877a4fd3c336a5e72ae5980656a2ab971a473c538
@@ -1,3 +1,7 @@
1
+ ## 1.1.0 - May 27, 2019
2
+ - Interval server uses threads for timing
3
+ - Servers use observer patterns to reduce polling
4
+
1
5
  ## 1.0.0 - February 19, 2019
2
6
  - Renamed Adapter#sending to Adapter#receiving
3
7
  - Travis tests up to Ruby 2.6
@@ -79,6 +79,7 @@ module Backport
79
79
  def close
80
80
  return if closed?
81
81
  _data[:closed] = true
82
+ _data[:on_close].call unless _data[:on_close].nil?
82
83
  closing
83
84
  end
84
85
  end
@@ -1,7 +1,11 @@
1
+ require 'observer'
2
+
1
3
  module Backport
2
4
  # A client connected to a connectable Backport server.
3
5
  #
4
6
  class Client
7
+ include Observable
8
+
5
9
  # @return [Adapter]
6
10
  attr_reader :adapter
7
11
 
@@ -33,6 +37,8 @@ module Backport
33
37
  return if stopped?
34
38
  @adapter.closing
35
39
  @stopped = true
40
+ changed
41
+ notify_observers self
36
42
  end
37
43
 
38
44
  # Start running the client. This method will start the thread that reads
@@ -53,12 +59,8 @@ module Backport
53
59
  #
54
60
  # @return [void]
55
61
  def tick
56
- if adapter.closed?
57
- stop
58
- else
59
- input = read
60
- @adapter.receiving input unless input.nil?
61
- end
62
+ input = read
63
+ @adapter.receiving input unless input.nil?
62
64
  end
63
65
 
64
66
  private
@@ -105,16 +107,18 @@ module Backport
105
107
  #
106
108
  # @return [void]
107
109
  def read_input
108
- @in.flush
109
110
  begin
111
+ @in.flush
110
112
  chars = @in.sysread(255)
111
- rescue EOFError, Errno::ECONNRESET
113
+ rescue EOFError, IOError, Errno::ECONNRESET
112
114
  chars = nil
113
115
  end
114
116
  if chars.nil?
115
117
  stop
116
118
  else
117
119
  mutex.synchronize { @buffer.concat chars }
120
+ changed
121
+ notify_observers self
118
122
  end
119
123
  end
120
124
  end
@@ -41,6 +41,7 @@ module Backport
41
41
  # @param server [Server::Base]
42
42
  # @return [void]
43
43
  def prepare server
44
+ server.add_observer self
44
45
  servers.push server
45
46
  server.start unless stopped?
46
47
  end
@@ -50,26 +51,28 @@ module Backport
50
51
  @servers ||= []
51
52
  end
52
53
 
53
- # Update the machine's servers.
54
- #
55
- # @return [void]
56
- def tick
57
- servers.delete_if(&:stopped?)
58
- stop if servers.empty?
59
- servers.each(&:tick)
54
+ # @param server [Server::Base]
55
+ def update server
56
+ if server.stopped?
57
+ servers.delete server
58
+ stop if servers.empty?
59
+ else
60
+ mutex.synchronize { server.tick }
61
+ end
60
62
  end
61
63
 
62
64
  private
63
65
 
66
+ def mutex
67
+ @mutex ||= Mutex.new
68
+ end
69
+
64
70
  # Start the thread that updates servers via the #tick method.
65
71
  #
66
72
  # @return [void]
67
73
  def run_server_thread
68
74
  servers.map(&:start)
69
- until stopped?
70
- tick
71
- sleep 0.001
72
- end
75
+ sleep 0.1 until stopped?
73
76
  end
74
77
  end
75
78
  end
@@ -1,9 +1,13 @@
1
+ require 'observer'
2
+
1
3
  module Backport
2
4
  module Server
3
5
  # An extendable server class that provides basic start/stop functionality
4
6
  # and common callbacks.
5
7
  #
6
8
  class Base
9
+ include Observable
10
+
7
11
  # Start the server.
8
12
  #
9
13
  def start
@@ -18,6 +22,8 @@ module Backport
18
22
  return if stopped?
19
23
  stopping
20
24
  @started = false
25
+ changed
26
+ notify_observers self
21
27
  end
22
28
 
23
29
  def started?
@@ -5,12 +5,12 @@ module Backport
5
5
  # Connectable servers check clients for incoming data on each tick.
6
6
  #
7
7
  module Connectable
8
- def tick
9
- mutex.synchronize do
10
- clients.each(&:tick)
11
- clients.delete_if(&:stopped?)
12
- end
13
- end
8
+ # def tick
9
+ # mutex.synchronize do
10
+ # # clients.each(&:tick)
11
+ # clients.delete_if(&:stopped?)
12
+ # end
13
+ # end
14
14
 
15
15
  def starting
16
16
  clients.map(&:run)
@@ -9,18 +9,32 @@ module Backport
9
9
  def initialize period, &block
10
10
  @period = period
11
11
  @block = block
12
- @last_time = Time.now
12
+ @ready = false
13
13
  end
14
14
 
15
15
  def starting
16
- @last_time = Time.now
16
+ @ready = false
17
+ run_ready_thread
17
18
  end
18
19
 
19
20
  def tick
20
- now = Time.now
21
- return unless now - @last_time >= @period
21
+ return unless @ready
22
22
  @block.call self
23
- @last_time = now
23
+ @ready = false
24
+ end
25
+
26
+ private
27
+
28
+ def run_ready_thread
29
+ Thread.new do
30
+ until stopped?
31
+ sleep @period
32
+ break if stopped?
33
+ @ready = true
34
+ changed
35
+ notify_observers self
36
+ end
37
+ end
24
38
  end
25
39
  end
26
40
  end
@@ -11,6 +11,11 @@ module Backport
11
11
  @out.binmode
12
12
  @adapter = adapter
13
13
  clients.push Client.new(input, output, adapter)
14
+ clients.last.add_observer self
15
+ end
16
+
17
+ def update client
18
+ client.tick
14
19
  end
15
20
  end
16
21
  end
@@ -38,7 +38,7 @@ module Backport
38
38
  result = nil
39
39
  mutex.synchronize do
40
40
  begin
41
- conn = socket.accept_nonblock
41
+ conn = socket.accept
42
42
  addr = conn.addr(true)
43
43
  data = {
44
44
  family: addr[0],
@@ -47,6 +47,13 @@ module Backport
47
47
  address: addr[3]
48
48
  }
49
49
  clients.push Client.new(conn, conn, @adapter, data)
50
+ this = self
51
+ clients.last.adapter._data[:on_close] = Proc.new {
52
+ conn.close
53
+ changed
54
+ notify_observers this
55
+ }
56
+ clients.last.add_observer self
50
57
  clients.last.run
51
58
  result = clients.last
52
59
  rescue IO::WaitReadable, Errno::EAGAIN
@@ -62,6 +69,14 @@ module Backport
62
69
  result
63
70
  end
64
71
 
72
+ def update client
73
+ if client.stopped?
74
+ clients.delete client
75
+ else
76
+ client.tick
77
+ end
78
+ end
79
+
65
80
  private
66
81
 
67
82
  # @return [TCPSocket]
@@ -1,3 +1,3 @@
1
1
  module Backport
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backport
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
  - Fred Snyder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-19 00:00:00.000000000 Z
11
+ date: 2019-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -101,8 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
103
  requirements: []
104
- rubyforge_project:
105
- rubygems_version: 2.7.6
104
+ rubygems_version: 3.0.3
106
105
  signing_key:
107
106
  specification_version: 4
108
107
  summary: A pure Ruby library for event-driven IO