nats-pure 2.4.0 → 2.6.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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/README.md +10 -3
  4. data/lib/nats/client.rb +7 -3
  5. data/lib/nats/io/client.rb +464 -328
  6. data/lib/nats/io/errors.rb +2 -0
  7. data/lib/nats/io/jetstream/api.rb +53 -50
  8. data/lib/nats/io/jetstream/errors.rb +30 -14
  9. data/lib/nats/io/jetstream/js/config.rb +9 -3
  10. data/lib/nats/io/jetstream/js/header.rb +15 -9
  11. data/lib/nats/io/jetstream/js/status.rb +11 -5
  12. data/lib/nats/io/jetstream/js/sub.rb +4 -2
  13. data/lib/nats/io/jetstream/js.rb +10 -8
  14. data/lib/nats/io/jetstream/manager.rb +103 -101
  15. data/lib/nats/io/jetstream/msg/ack.rb +22 -12
  16. data/lib/nats/io/jetstream/msg/ack_methods.rb +30 -24
  17. data/lib/nats/io/jetstream/msg/metadata.rb +10 -7
  18. data/lib/nats/io/jetstream/msg.rb +11 -4
  19. data/lib/nats/io/jetstream/pull_subscription.rb +21 -10
  20. data/lib/nats/io/jetstream/push_subscription.rb +3 -1
  21. data/lib/nats/io/jetstream.rb +102 -106
  22. data/lib/nats/io/kv/api.rb +7 -3
  23. data/lib/nats/io/kv/bucket_status.rb +7 -5
  24. data/lib/nats/io/kv/errors.rb +25 -2
  25. data/lib/nats/io/kv/manager.rb +19 -10
  26. data/lib/nats/io/kv.rb +354 -22
  27. data/lib/nats/io/msg.rb +19 -19
  28. data/lib/nats/io/parser.rb +23 -23
  29. data/lib/nats/io/rails.rb +2 -0
  30. data/lib/nats/io/subscription.rb +33 -23
  31. data/lib/nats/io/version.rb +4 -2
  32. data/lib/nats/io/websocket.rb +40 -18
  33. data/lib/nats/nuid.rb +33 -22
  34. data/lib/nats/service/callbacks.rb +22 -0
  35. data/lib/nats/service/endpoint.rb +155 -0
  36. data/lib/nats/service/errors.rb +44 -0
  37. data/lib/nats/service/group.rb +37 -0
  38. data/lib/nats/service/monitoring.rb +108 -0
  39. data/lib/nats/service/stats.rb +52 -0
  40. data/lib/nats/service/status.rb +66 -0
  41. data/lib/nats/service/validator.rb +31 -0
  42. data/lib/nats/service.rb +121 -0
  43. data/lib/nats/utils/list.rb +26 -0
  44. data/lib/nats-pure.rb +5 -0
  45. data/lib/nats.rb +10 -6
  46. metadata +176 -8
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "monitor"
4
+
5
+ module NATS
6
+ class Service
7
+ class Stats
8
+ include MonitorMixin
9
+
10
+ attr_reader :num_requests, :num_errors, :last_error, :processing_time, :average_processing_time
11
+
12
+ def initialize
13
+ super
14
+ reset
15
+ end
16
+
17
+ def reset
18
+ synchronize do
19
+ @num_requests = 0
20
+ @processing_time = 0
21
+ @average_processing_time = 0
22
+
23
+ @num_errors = 0
24
+ @last_error = ""
25
+ end
26
+ end
27
+
28
+ def record(started_at)
29
+ synchronize do
30
+ @num_requests += 1
31
+ @processing_time += to_nsec(Time.now - started_at)
32
+ @average_processing_time = @processing_time / @num_requests
33
+ end
34
+ end
35
+
36
+ def error(error)
37
+ error = ErrorWrapper.new(error)
38
+
39
+ synchronize do
40
+ @num_errors += 1
41
+ @last_error = error.description
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def to_nsec(seconds)
48
+ (seconds * 10**9).to_i
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NATS
4
+ class Service
5
+ class Status
6
+ attr_reader :service, :started_at
7
+
8
+ def initialize(service)
9
+ @service = service
10
+ @started_at = Time.now
11
+ end
12
+
13
+ def basic
14
+ {
15
+ name: service.name,
16
+ id: service.id,
17
+ version: service.version,
18
+ metadata: service.metadata
19
+ }
20
+ end
21
+
22
+ def info
23
+ {
24
+ **basic,
25
+ description: service.description,
26
+ endpoints: service.endpoints.map do |endpoint|
27
+ {
28
+ name: endpoint.name,
29
+ subject: endpoint.subject,
30
+ queue_group: endpoint.queue,
31
+ metadata: endpoint.metadata
32
+ }
33
+ end
34
+ }
35
+ end
36
+
37
+ def stats
38
+ {
39
+ **basic,
40
+ started: started_at.utc.iso8601,
41
+ endpoints: service.endpoints.map do |endpoint|
42
+ endpoint_stats(endpoint)
43
+ end
44
+ }
45
+ end
46
+
47
+ private
48
+
49
+ def endpoint_stats(endpoint)
50
+ endpoint.stats.synchronize do
51
+ {
52
+ name: endpoint.name,
53
+ subject: endpoint.subject,
54
+ queue_group: endpoint.queue,
55
+ num_requests: endpoint.stats.num_requests,
56
+ processing_time: endpoint.stats.processing_time,
57
+ average_processing_time: endpoint.stats.average_processing_time,
58
+ num_errors: endpoint.stats.num_errors,
59
+ last_error: endpoint.stats.last_error,
60
+ data: service.callbacks.call(:stats, endpoint)
61
+ }
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NATS
4
+ class Service
5
+ module Validator
6
+ REGEX = {
7
+ name: /[A-Za-z0-9\-_]+$/,
8
+ version: /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/,
9
+ subject: /^[^ >]*>?$/,
10
+ queue: /^[^ >]*>?$/
11
+ }.freeze
12
+
13
+ class << self
14
+ def validate(values)
15
+ raise InvalidNameError unless valid?(values, :name)
16
+ raise InvalidVersionError unless valid?(values, :version)
17
+ raise InvalidSubjectError unless valid?(values, :subject) || nil?(values, :subject)
18
+ raise InvalidQueueError unless valid?(values, :queue) || nil?(values, :queue)
19
+ end
20
+
21
+ def valid?(values, key)
22
+ !values.has_key?(key) || values[key] =~ REGEX[key]
23
+ end
24
+
25
+ def nil?(values, key)
26
+ values.has_key?(key) && values[key].nil?
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "monitor"
4
+
5
+ require_relative "service/group"
6
+ require_relative "service/endpoint"
7
+ require_relative "service/errors"
8
+
9
+ require_relative "service/validator"
10
+ require_relative "service/callbacks"
11
+ require_relative "service/monitoring"
12
+ require_relative "service/status"
13
+ require_relative "service/stats"
14
+
15
+ module NATS
16
+ class Service
17
+ include MonitorMixin
18
+
19
+ DEFAULT_QUEUE = "q"
20
+
21
+ attr_reader :client, :name, :id, :version, :description, :metadata, :queue
22
+ attr_reader :monitoring, :status, :callbacks, :groups, :endpoints
23
+
24
+ def initialize(client, options)
25
+ super()
26
+ validate(options)
27
+
28
+ setup_options(options)
29
+ setup_internals(client)
30
+ end
31
+
32
+ def on_stats(&block)
33
+ callbacks.register(:stats, &block)
34
+ end
35
+
36
+ def on_stop(&block)
37
+ callbacks.register(:stop, &block)
38
+ end
39
+
40
+ def stopped?
41
+ !!@stopped
42
+ end
43
+
44
+ def stop(error = nil)
45
+ return if stopped?
46
+
47
+ synchronize do
48
+ monitoring&.stop
49
+ endpoints&.each(&:stop)
50
+
51
+ callbacks&.call(:stop, error)
52
+ end
53
+ ensure
54
+ synchronize { @stopped = true }
55
+ end
56
+
57
+ def reset
58
+ endpoints.each(&:reset)
59
+ end
60
+
61
+ def info
62
+ status.info
63
+ end
64
+
65
+ def stats
66
+ status.stats
67
+ end
68
+
69
+ def service
70
+ self
71
+ end
72
+
73
+ def subject
74
+ nil
75
+ end
76
+
77
+ private
78
+
79
+ def validate(options)
80
+ Validator.validate(options.slice(:name, :version, :queue))
81
+ end
82
+
83
+ def setup_options(options)
84
+ @name = options[:name]
85
+ @version = options[:version]
86
+ @description = options[:description]
87
+ @metadata = options[:metadata].freeze
88
+ @queue = options[:queue] || DEFAULT_QUEUE
89
+ end
90
+
91
+ def setup_internals(client)
92
+ @client = client
93
+ @id = NATS::NUID.next
94
+
95
+ @monitoring = Monitoring.new(self)
96
+ @status = Status.new(self)
97
+ @callbacks = Callbacks.new(self)
98
+
99
+ @groups = Groups.new(self)
100
+ @endpoints = Endpoints.new(self)
101
+ end
102
+ end
103
+
104
+ class Services < NATS::Utils::List
105
+ attr_reader :client
106
+
107
+ def initialize(client)
108
+ @client = client
109
+ super
110
+ end
111
+
112
+ def add(options)
113
+ client.synchronize do
114
+ service = NATS::Service.new(client, options)
115
+ insert(service)
116
+
117
+ service
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NATS
4
+ class Utils
5
+ class List
6
+ include Enumerable
7
+
8
+ attr_reader :parent
9
+
10
+ def initialize(parent)
11
+ @parent = parent
12
+ @items = Set.new
13
+ end
14
+
15
+ def each
16
+ @items.each do |item|
17
+ yield item
18
+ end
19
+ end
20
+
21
+ def insert(item)
22
+ @items << item
23
+ end
24
+ end
25
+ end
26
+ end
data/lib/nats-pure.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nats/io/client"
4
+ require "nats/utils/list"
5
+ require "nats/service"
data/lib/nats.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2021 The NATS Authors
2
4
  # Licensed under the Apache License, Version 2.0 (the "License");
3
5
  # you may not use this file except in compliance with the License.
@@ -12,8 +14,10 @@
12
14
  # limitations under the License.
13
15
  #
14
16
 
15
- require 'nats/io/client'
16
- require 'nats/nuid'
17
+ require "nats/utils/list"
18
+ require "nats/io/client"
19
+ require "nats/service"
20
+ require "nats/nuid"
17
21
 
18
22
  # A thread safe Ruby client for the NATS messaging system (https://nats.io).
19
23
  #
@@ -25,15 +29,15 @@ require 'nats/nuid'
25
29
  #
26
30
  # resp = nc.request("foo")
27
31
  # puts "Received: #{msg.data}"
28
- #
29
- #
32
+ #
33
+ #
30
34
  # @example Stream example
31
35
  # nc = NATS.connect("demo.nats.io")
32
36
  # sub = nc.subscribe("foo")
33
- #
37
+ #
34
38
  # nc.publish("foo")
35
39
  # msg = sub.next_msg
36
40
  # puts "Received: #{msg.data}"
37
- #
41
+ #
38
42
  module NATS
39
43
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nats-pure
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Waldemar Quevedo
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-11-22 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: concurrent-ruby
@@ -24,6 +23,160 @@ dependencies:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
25
  version: '1.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: uri
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: securerandom
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: json
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: base64
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: nkeys
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: websocket
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: bundler
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '1'
117
+ type: :development
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '1'
124
+ - !ruby/object:Gem::Dependency
125
+ name: rake
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '13.0'
131
+ type: :development
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '13.0'
138
+ - !ruby/object:Gem::Dependency
139
+ name: rspec
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '3.5'
145
+ type: :development
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '3.5'
152
+ - !ruby/object:Gem::Dependency
153
+ name: timecop
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ type: :development
160
+ prerelease: false
161
+ version_requirements: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ - !ruby/object:Gem::Dependency
167
+ name: resolv-replace
168
+ requirement: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ type: :development
174
+ prerelease: false
175
+ version_requirements: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
27
180
  description: NATS is an open-source, high-performance, lightweight cloud messaging
28
181
  system.
29
182
  email:
@@ -32,8 +185,10 @@ executables: []
32
185
  extensions: []
33
186
  extra_rdoc_files: []
34
187
  files:
188
+ - CHANGELOG.md
35
189
  - LICENSE
36
190
  - README.md
191
+ - lib/nats-pure.rb
37
192
  - lib/nats.rb
38
193
  - lib/nats/client.rb
39
194
  - lib/nats/io/client.rb
@@ -65,6 +220,16 @@ files:
65
220
  - lib/nats/io/version.rb
66
221
  - lib/nats/io/websocket.rb
67
222
  - lib/nats/nuid.rb
223
+ - lib/nats/service.rb
224
+ - lib/nats/service/callbacks.rb
225
+ - lib/nats/service/endpoint.rb
226
+ - lib/nats/service/errors.rb
227
+ - lib/nats/service/group.rb
228
+ - lib/nats/service/monitoring.rb
229
+ - lib/nats/service/stats.rb
230
+ - lib/nats/service/status.rb
231
+ - lib/nats/service/validator.rb
232
+ - lib/nats/utils/list.rb
68
233
  - sig/nats/io/client.rbs
69
234
  - sig/nats/io/errors.rbs
70
235
  - sig/nats/io/jetstream.rbs
@@ -95,8 +260,12 @@ files:
95
260
  homepage: https://nats.io
96
261
  licenses:
97
262
  - Apache-2.0
98
- metadata: {}
99
- post_install_message:
263
+ metadata:
264
+ bug_tracker_uri: https://github.com/nats-io/nats-pure.rb/issues
265
+ changelog_uri: https://github.com/nats-io/nats-pure.rb/blob/main/CHANGELOG.md
266
+ documentation_uri: https://github.com/nats-io/nats-pure.rb
267
+ homepage_uri: https://github.com/nats-io/nats-pure.rb
268
+ source_code_uri: https://github.com/nats-io/nats-pure.rb
100
269
  rdoc_options: []
101
270
  require_paths:
102
271
  - lib
@@ -104,15 +273,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
273
  requirements:
105
274
  - - ">="
106
275
  - !ruby/object:Gem::Version
107
- version: '0'
276
+ version: '3.0'
108
277
  required_rubygems_version: !ruby/object:Gem::Requirement
109
278
  requirements:
110
279
  - - ">="
111
280
  - !ruby/object:Gem::Version
112
281
  version: '0'
113
282
  requirements: []
114
- rubygems_version: 3.4.1
115
- signing_key:
283
+ rubygems_version: 4.0.21
116
284
  specification_version: 4
117
285
  summary: NATS is an open-source, high-performance, lightweight cloud messaging system.
118
286
  test_files: []