tiny_tcp_service 1.0.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: d0b5f209ab23524835fe2cc63b60e2189b26ad34662ee3af78c6c28b9fa8c721
4
+ data.tar.gz: 87f8e1c4b84b09d1ee34afdae890a4886b7f9878631f7d86e8e74fa300611b2e
5
5
  SHA512:
6
- metadata.gz: 9412c4a198ad73b150cef0f4f9e98da281cda3fe6dbfbd17eb1caae8b7632cb8e73f24eb2e40bc3dcb20fd6734f1c2f324a91c1230e4edb71e9ed36cc7786e47
7
- data.tar.gz: e57e65acae41614f17650ce7c7c64b9a3a302be645ed2cedd5a33b2f310252bc06077bbfeeb209ab8333920b5bf0a9021c1e150857951a166f05704874a07723
6
+ metadata.gz: c1a76e05e856e23bb33890c9f2fc9c46af0c82b8185501252fa1c1d73f22c1e01115443cebaa97c225c5e1bbd1fcf336bfd6aabb2014bdfa3eb01ae6028b02f0
7
+ data.tar.gz: 279da0f3265028f3f528587d3b1783ba9f148c1d228b0f871a5ba4b889c3f4092c4f8bece422fb484c32873d4e7a2587fdf9eaf2cc228c5706159600ee7c41e1
@@ -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 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.2.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