tiny_tcp_service 1.0.1 → 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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tiny_tcp_service.rb +35 -13
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 807a9c4df229014efd5376a0ab636806fe82399999ab99ca367a6f2d057d0bdb
4
- data.tar.gz: e30fd27d92a5f8a6ffd64b4183765050777f933c80a970256c2dc72804ec98bd
3
+ metadata.gz: 1836cd2d7baa8228f9fbfddfe63718aadc35cf26d59e54cbda26c8bea584c2f1
4
+ data.tar.gz: 8e5982655d66d8950d8dafd8239b67dc2977d35dcde6efcd53697adbfe519314
5
5
  SHA512:
6
- metadata.gz: 9412c4a198ad73b150cef0f4f9e98da281cda3fe6dbfbd17eb1caae8b7632cb8e73f24eb2e40bc3dcb20fd6734f1c2f324a91c1230e4edb71e9ed36cc7786e47
7
- data.tar.gz: e57e65acae41614f17650ce7c7c64b9a3a302be645ed2cedd5a33b2f310252bc06077bbfeeb209ab8333920b5bf0a9021c1e150857951a166f05704874a07723
6
+ metadata.gz: d3f632a782bda92c4f3c83e2ba459a276a073dbd9ea264c54ffd2657428cad420392e76fe5eacff3e80c3f84689aef7a6dbb5167bad98fa24ea76d3389dab401
7
+ data.tar.gz: fcb2d4b300629ae12417d41f98f1e9a30bda1d2ff25e07c6afa4f8d15898ccb1e40019766d2b94597ca9a4f8707f8b90edcc2278d03bcd66e178dfe951547bb7
@@ -9,21 +9,35 @@ require 'socket'
9
9
  # s.start! # everything runs in background threads
10
10
  # s.stop! # gracefully shutdown the server
11
11
  #
12
- # NOTE: the msg_handler does not need to be a proc/lambda, it just needs to be
13
- # an object that responds_to?(:call), and accepts a single message object.
14
- # however, if your msg_handler is simple enough to fit into something as tiny as
15
- # a proc then more power to you.
12
+ # TinyTCPService implements a line-based, call and response protocol, where
13
+ # every incoming message must be a newline-terminated ("\n") String, and for
14
+ # every received message the service responds with a newline-terminated String.
15
+ # been set).
16
+ #
17
+ # If you need more complex objects to be sent over the wire, consider something
18
+ # like JSON.
19
+ #
20
+ # NOTE: if you're running a TinyTCPService and a client of your system violates
21
+ # your communication protocol, you should raise an instance of
22
+ # TinyTCPService::BadClient, and the TinyTCPService instance will take care of
23
+ # safely removing the client.
16
24
  class TinyTCPService
17
- def initialize(port, msg_handler)
25
+ def initialize(port)
18
26
  @port = port
19
- @msg_handler = msg_handler
20
27
 
21
28
  @server = TCPServer.new(port)
22
29
  @clients = []
23
30
  @running = false
31
+
32
+ @msg_handler = nil
24
33
  @error_handlers = {}
25
34
  end
26
35
 
36
+ # h - some object that responds to #call
37
+ def set_msg_handler!(h)
38
+ @msg_handler = h
39
+ end
40
+
27
41
  # returns true if the server is running
28
42
  # false otherwise
29
43
  def running?
@@ -47,6 +61,11 @@ class TinyTCPService
47
61
  @clients.length
48
62
  end
49
63
 
64
+ def _remove_client!(c)
65
+ @clients.delete(c)
66
+ c.close if c && !c.closed?
67
+ end
68
+
50
69
  # starts the server
51
70
  def start!
52
71
  return if running?
@@ -59,7 +78,7 @@ class TinyTCPService
59
78
  @clients << @server.accept
60
79
  end
61
80
 
62
- @clients.each{|c| c.close if c && !c.closed? }
81
+ @clients.each{|c| _remove_client!(c) if c && !c.closed? }
63
82
  @server.close
64
83
  end
65
84
 
@@ -69,9 +88,11 @@ class TinyTCPService
69
88
  break unless running?
70
89
 
71
90
  readable, _, errored = IO.select(@clients, nil, @clients, 1)
72
- readable&.each do |client|
91
+ readable&.each do |c|
73
92
  begin
74
- @msg_handler.call(client.gets.chomp)
93
+ @msg_handler&.call(c.gets.chomp)
94
+ rescue TinyTCPService::BadClient => e
95
+ _remove_client!(c)
75
96
  rescue => e
76
97
  handler = @error_handlers[e.class]
77
98
 
@@ -79,14 +100,13 @@ class TinyTCPService
79
100
  handler.call(e)
80
101
  else
81
102
  stop!
82
- raise e unless handler
103
+ raise e
83
104
  end
84
105
  end
85
106
  end
86
107
 
87
- errored&.each do |client|
88
- @clients.delete(client)
89
- client.close if client && !client.closed?
108
+ errored&.each do |c|
109
+ _remove_client!(c)
90
110
  end
91
111
  end
92
112
  end
@@ -97,3 +117,5 @@ class TinyTCPService
97
117
  @running = false
98
118
  end
99
119
  end
120
+
121
+ class TinyTCPService::BadClient < RuntimeError; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tiny_tcp_service
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Lunt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-30 00:00:00.000000000 Z
11
+ date: 2023-11-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: a tiny TCP service with automated client lifecycle
14
14
  email: jefflunt@gmail.com