nats-async 0.1.0 → 0.1.3
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 +4 -4
- data/.rspec +1 -1
- data/README.md +17 -9
- data/examples/basic_pub_sub.rb +21 -0
- data/examples/jetstream_roundtrip.rb +61 -0
- data/lib/nats-async.rb +0 -1
- data/lib/version.rb +1 -1
- data/spec/examples_spec.rb +121 -0
- data/spec/nats_async_spec.rb +6 -12
- metadata +9 -11
- data/README.erb +0 -46
- data/bin/nats-async +0 -9
- data/lib/nats_async/command_line.rb +0 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 14ba43d9d274e8b3bf2ed955560a480dcc9bf5c6668949b1007db1ebf17f02e8
|
|
4
|
+
data.tar.gz: fb0aa3853cbe25ddc1c61882b3e74031de3e916c6366d4450a7c750d4b27bdb7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3d95c6affdcd42236c16e1f1264dfb1ef4c9cde64bf90fdfe775fceac5f90924bc3e9126b8590d8683fb369121a294a71e9cf8c901b27520c25e0ea814520ee9
|
|
7
|
+
data.tar.gz: cf6213706289cb5b3b6e97d6b2a1ac94c8d75053d50cf7dc9c746f22bc6ff465cc21207e086f2c17498c00ca83d152d761f9fa01e2ad7a23cdeb6c40fbff0e0a
|
data/.rspec
CHANGED
data/README.md
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
# Nats Async
|
|
2
2
|
|
|
3
|
-
`nats-async` packages the `nats-test`
|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
$ ./bin/nats-async --help
|
|
7
|
-
Usage: nats-async [--version] [--help]
|
|
8
|
-
|
|
9
|
-
Library gem for the NatsAsync connector prototype.
|
|
10
|
-
|
|
11
|
-
```
|
|
3
|
+
`nats-async` packages the `nats-test` is a Ruby gem.
|
|
12
4
|
|
|
13
5
|
## Installation
|
|
14
6
|
|
|
@@ -40,6 +32,22 @@ connector.run(duration: 1) do |client, task|
|
|
|
40
32
|
end
|
|
41
33
|
```
|
|
42
34
|
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
Core pub/sub:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
bundle exec ruby examples/basic_pub_sub.rb
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
JetStream publish and pull:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
bundle exec ruby examples/jetstream_roundtrip.rb
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The integration spec boots the bundled [`bin/nats-server`](bin/nats-server) and runs these examples locally.
|
|
50
|
+
|
|
43
51
|
## Development
|
|
44
52
|
|
|
45
53
|
```bash
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "bundler/setup"
|
|
5
|
+
require "nats-async"
|
|
6
|
+
|
|
7
|
+
url = ENV.fetch("NATS_URL", "nats://127.0.0.1:4222")
|
|
8
|
+
subject = ENV.fetch("NATS_SUBJECT", "demo.subject")
|
|
9
|
+
payload = ENV.fetch("NATS_PAYLOAD", "hello from nats-async")
|
|
10
|
+
|
|
11
|
+
connector = NatsAsync::SimpleConnector.new(url: url, verbose: true)
|
|
12
|
+
|
|
13
|
+
connector.run(duration: 1.5, ping_every: 1, ping_timeout: 1) do |client, task|
|
|
14
|
+
sid = client.subscribe(subject) do |message|
|
|
15
|
+
puts "received subject=#{message.subject} data=#{message.data.inspect}"
|
|
16
|
+
client.unsubscribe(sid)
|
|
17
|
+
task.stop
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
client.publish(subject, payload)
|
|
21
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "bundler/setup"
|
|
5
|
+
require "nats-async"
|
|
6
|
+
|
|
7
|
+
url = ENV.fetch("NATS_URL", "nats://127.0.0.1:4222")
|
|
8
|
+
stream_name = ENV.fetch("JS_STREAM", "test_stream")
|
|
9
|
+
subject = ENV.fetch("JS_SUBJECT", "test_stream")
|
|
10
|
+
consumer = ENV.fetch("JS_CONSUMER", "example_consumer")
|
|
11
|
+
payload = ENV.fetch("JS_PAYLOAD", "hello jetstream")
|
|
12
|
+
js_api_prefix = ENV.fetch("JS_API_PREFIX", "$JS.API")
|
|
13
|
+
|
|
14
|
+
connector = NatsAsync::SimpleConnector.new(
|
|
15
|
+
url: url,
|
|
16
|
+
verbose: true,
|
|
17
|
+
js_api_prefix: js_api_prefix
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
connector.run(duration: 3, ping_every: 1, ping_timeout: 1) do |client, _task|
|
|
21
|
+
client.request(
|
|
22
|
+
client.js_api_subject("STREAM.CREATE", stream_name),
|
|
23
|
+
{
|
|
24
|
+
name: stream_name,
|
|
25
|
+
subjects: [subject]
|
|
26
|
+
},
|
|
27
|
+
timeout: 2
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
client.request(
|
|
31
|
+
client.js_api_subject("CONSUMER.CREATE", stream_name, consumer),
|
|
32
|
+
{
|
|
33
|
+
stream_name: stream_name,
|
|
34
|
+
config: {
|
|
35
|
+
name: consumer,
|
|
36
|
+
durable_name: consumer,
|
|
37
|
+
ack_policy: "explicit",
|
|
38
|
+
deliver_policy: "new",
|
|
39
|
+
filter_subject: subject
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
timeout: 2
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
pub_ack = client.request(subject, payload, timeout: 2)
|
|
46
|
+
puts "published seq=#{pub_ack[:seq]} stream=#{pub_ack[:stream]}"
|
|
47
|
+
|
|
48
|
+
message = client.request(
|
|
49
|
+
client.js_api_subject("CONSUMER.MSG.NEXT", stream_name, consumer),
|
|
50
|
+
{batch: 1, expires: 1_000_000_000},
|
|
51
|
+
timeout: 2,
|
|
52
|
+
parse_json: false
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
puts "received subject=#{message.subject} data=#{message.data.inspect}"
|
|
56
|
+
puts "metadata=#{message.metadata.inspect}"
|
|
57
|
+
message.ack if message.reply
|
|
58
|
+
|
|
59
|
+
client.request(client.js_api_subject("CONSUMER.DELETE", stream_name, consumer), {}, timeout: 2)
|
|
60
|
+
client.request(client.js_api_subject("STREAM.DELETE", stream_name), {}, timeout: 2)
|
|
61
|
+
end
|
data/lib/nats-async.rb
CHANGED
data/lib/version.rb
CHANGED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rubocop:disable RSpec/ExampleLength, RSpec/NoExpectationExample
|
|
4
|
+
# rubocop:disable RSpec/DescribeClass
|
|
5
|
+
|
|
6
|
+
require_relative "spec_helper"
|
|
7
|
+
|
|
8
|
+
require "open3"
|
|
9
|
+
require "socket"
|
|
10
|
+
require "tempfile"
|
|
11
|
+
require "tmpdir"
|
|
12
|
+
|
|
13
|
+
RSpec.describe "example scripts" do
|
|
14
|
+
def report_server_start_failure(reason, log_path)
|
|
15
|
+
log = File.exist?(log_path) ? File.read(log_path) : "(log file missing)"
|
|
16
|
+
message = <<~MSG
|
|
17
|
+
nats-server example integration skipped: #{reason}
|
|
18
|
+
--- nats-server log ---
|
|
19
|
+
#{log}
|
|
20
|
+
--- end nats-server log ---
|
|
21
|
+
MSG
|
|
22
|
+
|
|
23
|
+
warn(message)
|
|
24
|
+
warn("::warning::#{message.gsub("\n", "%0A")}") if ENV["GITHUB_ACTIONS"] == "true"
|
|
25
|
+
skip(message)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def project_path = File.expand_path("..", __dir__)
|
|
29
|
+
def server_path = File.join(project_path, "bin", "nats-server")
|
|
30
|
+
|
|
31
|
+
def free_port
|
|
32
|
+
server = TCPServer.new("127.0.0.1", 0)
|
|
33
|
+
server.addr[1]
|
|
34
|
+
ensure
|
|
35
|
+
server&.close
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def wait_for_server(port, server_pid, log_path, timeout: 5)
|
|
39
|
+
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout
|
|
40
|
+
|
|
41
|
+
loop do
|
|
42
|
+
socket = TCPSocket.new("127.0.0.1", port)
|
|
43
|
+
socket.close
|
|
44
|
+
return
|
|
45
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
|
46
|
+
if Process.waitpid(server_pid, Process::WNOHANG)
|
|
47
|
+
report_server_start_failure("bundled nats-server exited before becoming ready", log_path)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if Process.clock_gettime(Process::CLOCK_MONOTONIC) >= deadline
|
|
51
|
+
report_server_start_failure("bundled nats-server did not start on port #{port}", log_path)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
sleep 0.1
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def run_example(example_path, env)
|
|
59
|
+
stdout, stderr, status = Open3.capture3(env, "bundle", "exec", "ruby", example_path, chdir: project_path)
|
|
60
|
+
return if status.success?
|
|
61
|
+
|
|
62
|
+
raise <<~MSG
|
|
63
|
+
example failed: #{example_path}
|
|
64
|
+
status: #{status.exitstatus}
|
|
65
|
+
stdout:
|
|
66
|
+
#{stdout}
|
|
67
|
+
stderr:
|
|
68
|
+
#{stderr}
|
|
69
|
+
MSG
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "runs the bundled examples against the local nats-server" do
|
|
73
|
+
port = free_port
|
|
74
|
+
url = "nats://127.0.0.1:#{port}"
|
|
75
|
+
Tempfile.create(["nats-async-example", ".log"]) do |log|
|
|
76
|
+
log_path = log.path
|
|
77
|
+
Tempfile.create(["nats-async", ".conf"]) do |config|
|
|
78
|
+
config.write("debug: true\ntrace: true\n")
|
|
79
|
+
config.flush
|
|
80
|
+
|
|
81
|
+
Dir.mktmpdir("nats-async-js") do |store_dir|
|
|
82
|
+
server = Process.spawn(
|
|
83
|
+
server_path,
|
|
84
|
+
"-c", config.path,
|
|
85
|
+
"-js",
|
|
86
|
+
"-sd", store_dir,
|
|
87
|
+
"-p", port.to_s,
|
|
88
|
+
out: log,
|
|
89
|
+
err: log,
|
|
90
|
+
chdir: project_path
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
begin
|
|
94
|
+
wait_for_server(port, server, log_path)
|
|
95
|
+
run_example("examples/basic_pub_sub.rb", {"NATS_URL" => url})
|
|
96
|
+
run_example(
|
|
97
|
+
"examples/jetstream_roundtrip.rb",
|
|
98
|
+
{
|
|
99
|
+
"NATS_URL" => url,
|
|
100
|
+
"JS_STREAM" => "spec_stream",
|
|
101
|
+
"JS_SUBJECT" => "spec.subject",
|
|
102
|
+
"JS_CONSUMER" => "spec_consumer",
|
|
103
|
+
"JS_PAYLOAD" => "spec payload"
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
ensure
|
|
107
|
+
begin
|
|
108
|
+
Process.kill("TERM", server)
|
|
109
|
+
Process.wait(server)
|
|
110
|
+
rescue Errno::ESRCH, Process::Waiter::Error
|
|
111
|
+
nil
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# rubocop:enable RSpec/ExampleLength, RSpec/NoExpectationExample
|
|
121
|
+
# rubocop:enable RSpec/DescribeClass
|
data/spec/nats_async_spec.rb
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
require_relative "spec_helper"
|
|
4
|
+
|
|
5
|
+
describe NatsAsync do
|
|
6
|
+
# it "exposes a version" do
|
|
7
|
+
# expect(NatsAsync::VERSION).to eq("0.1.0")
|
|
8
|
+
# end
|
|
7
9
|
|
|
8
10
|
it "loads the simple connector" do
|
|
9
11
|
expect(NatsAsync::SimpleConnector).to be_a(Class)
|
|
10
12
|
end
|
|
11
|
-
|
|
12
|
-
it "formats cli help" do
|
|
13
|
-
output = StringIO.new
|
|
14
|
-
|
|
15
|
-
NatsAsync::CommandLine.run([], stdout: output)
|
|
16
|
-
|
|
17
|
-
expect(output.string).to include("Usage: nats-async")
|
|
18
|
-
end
|
|
19
13
|
end
|
metadata
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nats-async
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- Artem Borodkin
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
@@ -183,33 +183,31 @@ dependencies:
|
|
|
183
183
|
- - "~>"
|
|
184
184
|
- !ruby/object:Gem::Version
|
|
185
185
|
version: 0.5.1
|
|
186
|
-
description: Lightweight async Ruby connector for NATS
|
|
187
|
-
JetStream ack helpers.
|
|
186
|
+
description: Lightweight async Ruby connector for NATS
|
|
188
187
|
email:
|
|
189
188
|
- author@email.address
|
|
190
|
-
executables:
|
|
191
|
-
- nats-async
|
|
189
|
+
executables: []
|
|
192
190
|
extensions: []
|
|
193
191
|
extra_rdoc_files: []
|
|
194
192
|
files:
|
|
195
193
|
- ".github/workflows/release.yml"
|
|
196
194
|
- ".rspec"
|
|
197
195
|
- ".rubocop.yml"
|
|
198
|
-
- README.erb
|
|
199
196
|
- README.md
|
|
200
197
|
- Rakefile
|
|
201
|
-
-
|
|
198
|
+
- examples/basic_pub_sub.rb
|
|
199
|
+
- examples/jetstream_roundtrip.rb
|
|
202
200
|
- lib/nats-async.rb
|
|
203
|
-
- lib/nats_async/command_line.rb
|
|
204
201
|
- lib/nats_async/simple_connector.rb
|
|
205
202
|
- lib/version.rb
|
|
203
|
+
- spec/examples_spec.rb
|
|
206
204
|
- spec/nats_async_spec.rb
|
|
207
205
|
- spec/spec_helper.rb
|
|
208
206
|
homepage: https://rubygems.org/gems/nats-async
|
|
209
207
|
licenses:
|
|
210
208
|
- Nonstandard
|
|
211
209
|
metadata:
|
|
212
|
-
source_code_uri: https://github.com/
|
|
210
|
+
source_code_uri: https://github.com/artyomb/nats-async
|
|
213
211
|
rdoc_options: []
|
|
214
212
|
require_paths:
|
|
215
213
|
- lib
|
|
@@ -226,5 +224,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
226
224
|
requirements: []
|
|
227
225
|
rubygems_version: 3.6.7
|
|
228
226
|
specification_version: 4
|
|
229
|
-
summary: Async NATS connector
|
|
227
|
+
summary: Async NATS connector
|
|
230
228
|
test_files: []
|
data/README.erb
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# Nats Async
|
|
2
|
-
|
|
3
|
-
`nats-async` packages the `nats-test` prototype as a Ruby gem with the same project layout and build flow as `dry-stack`.
|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
$ ./bin/nats-async --help
|
|
7
|
-
<%= %x{./bin/nats-async --help} %>
|
|
8
|
-
```
|
|
9
|
-
|
|
10
|
-
## Installation
|
|
11
|
-
|
|
12
|
-
Add the gem to your bundle:
|
|
13
|
-
|
|
14
|
-
```ruby
|
|
15
|
-
gem "nats-async"
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Or install it directly:
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
gem install nats-async
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Usage
|
|
25
|
-
|
|
26
|
-
```ruby
|
|
27
|
-
require "nats-async"
|
|
28
|
-
|
|
29
|
-
connector = NatsAsync::SimpleConnector.new(url: "nats://127.0.0.1:4222", verbose: false)
|
|
30
|
-
connector.run(duration: 1) do |client, task|
|
|
31
|
-
client.subscribe("demo.subject") do |message|
|
|
32
|
-
puts "received: #{message.data}"
|
|
33
|
-
task.stop
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
client.publish("demo.subject", "hello")
|
|
37
|
-
end
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Development
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
bundle install
|
|
44
|
-
bundle exec rspec
|
|
45
|
-
rake build
|
|
46
|
-
```
|
data/bin/nats-async
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module NatsAsync
|
|
4
|
-
module CommandLine
|
|
5
|
-
module_function
|
|
6
|
-
|
|
7
|
-
def run(argv, stdout: $stdout)
|
|
8
|
-
case argv.first
|
|
9
|
-
when "-v", "--version"
|
|
10
|
-
stdout.puts(NatsAsync::VERSION)
|
|
11
|
-
else
|
|
12
|
-
stdout.puts("Usage: nats-async [--version] [--help]")
|
|
13
|
-
stdout.puts
|
|
14
|
-
stdout.puts("Library gem for the NatsAsync connector prototype.")
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|