backport 1.0.0 → 1.1.0

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: 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