amq-protocol 2.5.0 → 2.5.1
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/ChangeLog.md +5 -2
- data/lib/amq/protocol/version.rb +1 -1
- metadata +3 -55
- data/.github/ISSUE_TEMPLATE.md +0 -18
- data/.github/workflows/ci.yml +0 -31
- data/.gitignore +0 -18
- data/.gitmodules +0 -3
- data/.rspec +0 -1
- data/.travis.yml +0 -17
- data/AGENTS.md +0 -23
- data/CLAUDE.md +0 -1
- data/GEMINI.md +0 -1
- data/Gemfile +0 -27
- data/Rakefile +0 -55
- data/amq-protocol.gemspec +0 -27
- data/benchmarks/frame_encoding.rb +0 -75
- data/benchmarks/int_allocator.rb +0 -34
- data/benchmarks/method_encoding.rb +0 -198
- data/benchmarks/pack_unpack.rb +0 -158
- data/benchmarks/pure/body_framing_with_256k_payload.rb +0 -28
- data/benchmarks/pure/body_framing_with_2k_payload.rb +0 -28
- data/benchmarks/run_all.rb +0 -64
- data/benchmarks/table_encoding.rb +0 -110
- data/codegen/__init__.py +0 -0
- data/codegen/amqp_0.9.1_changes.json +0 -1
- data/codegen/codegen.py +0 -151
- data/codegen/codegen_helpers.py +0 -162
- data/codegen/protocol.rb.pytemplate +0 -320
- data/generate.rb +0 -24
- data/profiling/README.md +0 -9
- data/profiling/stackprof/body_framing_with_2k_payload.rb +0 -33
- data/spec/amq/bit_set_spec.rb +0 -249
- data/spec/amq/endianness_spec.rb +0 -23
- data/spec/amq/int_allocator_spec.rb +0 -136
- data/spec/amq/pack_spec.rb +0 -58
- data/spec/amq/protocol/basic_spec.rb +0 -325
- data/spec/amq/protocol/blank_body_encoding_spec.rb +0 -9
- data/spec/amq/protocol/channel_spec.rb +0 -127
- data/spec/amq/protocol/confirm_spec.rb +0 -41
- data/spec/amq/protocol/connection_spec.rb +0 -146
- data/spec/amq/protocol/constants_spec.rb +0 -10
- data/spec/amq/protocol/exceptions_spec.rb +0 -70
- data/spec/amq/protocol/exchange_spec.rb +0 -106
- data/spec/amq/protocol/float_32bit_spec.rb +0 -27
- data/spec/amq/protocol/frame_spec.rb +0 -156
- data/spec/amq/protocol/method_spec.rb +0 -43
- data/spec/amq/protocol/queue_spec.rb +0 -126
- data/spec/amq/protocol/table_spec.rb +0 -291
- data/spec/amq/protocol/tx_spec.rb +0 -55
- data/spec/amq/protocol/value_decoder_spec.rb +0 -183
- data/spec/amq/protocol/value_encoder_spec.rb +0 -161
- data/spec/amq/protocol_spec.rb +0 -812
- data/spec/amq/settings_spec.rb +0 -58
- data/spec/amq/uri_parsing_spec.rb +0 -287
- data/spec/spec_helper.rb +0 -29
data/benchmarks/pack_unpack.rb
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: utf-8
|
|
3
|
-
# frozen_string_literal: true
|
|
4
|
-
|
|
5
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
6
|
-
|
|
7
|
-
require "amq/protocol/client"
|
|
8
|
-
require "benchmark/ips"
|
|
9
|
-
|
|
10
|
-
puts
|
|
11
|
-
puts "-" * 80
|
|
12
|
-
puts "Pack/Unpack Micro-benchmarks on #{RUBY_DESCRIPTION}"
|
|
13
|
-
puts "-" * 80
|
|
14
|
-
|
|
15
|
-
# Test data
|
|
16
|
-
UINT64_VALUE = 0x123456789ABCDEF0
|
|
17
|
-
UINT32_VALUE = 0x12345678
|
|
18
|
-
UINT16_VALUE = 0x1234
|
|
19
|
-
|
|
20
|
-
PACKED_UINT64_BE = (+"\x12\x34\x56\x78\x9A\xBC\xDE\xF0").force_encoding('BINARY').freeze
|
|
21
|
-
PACKED_UINT32_BE = (+"\x12\x34\x56\x78").force_encoding('BINARY').freeze
|
|
22
|
-
PACKED_UINT16_BE = (+"\x12\x34").force_encoding('BINARY').freeze
|
|
23
|
-
|
|
24
|
-
puts "=== Pack Operations ==="
|
|
25
|
-
|
|
26
|
-
Benchmark.ips do |x|
|
|
27
|
-
x.config(time: 5, warmup: 2)
|
|
28
|
-
|
|
29
|
-
x.report("AMQ::Pack.pack_uint64_big_endian") do
|
|
30
|
-
AMQ::Pack.pack_uint64_big_endian(UINT64_VALUE)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Alternative: direct pack with 'Q>' directive (Ruby 1.9.3+)
|
|
34
|
-
x.report("[val].pack('Q>')") do
|
|
35
|
-
[UINT64_VALUE].pack('Q>')
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
x.report("[val].pack('N') uint32") do
|
|
39
|
-
[UINT32_VALUE].pack('N')
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
x.report("[val].pack('n') uint16") do
|
|
43
|
-
[UINT16_VALUE].pack('n')
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
x.compare!
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
puts
|
|
50
|
-
puts "=== Unpack Operations ==="
|
|
51
|
-
|
|
52
|
-
Benchmark.ips do |x|
|
|
53
|
-
x.config(time: 5, warmup: 2)
|
|
54
|
-
|
|
55
|
-
x.report("AMQ::Pack.unpack_uint64_big_endian") do
|
|
56
|
-
AMQ::Pack.unpack_uint64_big_endian(PACKED_UINT64_BE)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Alternative: direct unpack with 'Q>' directive
|
|
60
|
-
x.report("data.unpack('Q>')") do
|
|
61
|
-
PACKED_UINT64_BE.unpack('Q>')
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
x.report("data.unpack1('Q>')") do
|
|
65
|
-
PACKED_UINT64_BE.unpack1('Q>')
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
x.report("data.unpack('N').first") do
|
|
69
|
-
PACKED_UINT32_BE.unpack('N').first
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
x.report("data.unpack1('N')") do
|
|
73
|
-
PACKED_UINT32_BE.unpack1('N')
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
x.compare!
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
puts
|
|
80
|
-
puts "=== String Slicing ==="
|
|
81
|
-
|
|
82
|
-
DATA = ("x" * 1000).force_encoding('BINARY').freeze
|
|
83
|
-
|
|
84
|
-
Benchmark.ips do |x|
|
|
85
|
-
x.config(time: 5, warmup: 2)
|
|
86
|
-
|
|
87
|
-
x.report("data[offset, length]") do
|
|
88
|
-
DATA[100, 50]
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
x.report("data.byteslice(offset, length)") do
|
|
92
|
-
DATA.byteslice(100, 50)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
x.report("data.slice(offset, length)") do
|
|
96
|
-
DATA.slice(100, 50)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
x.compare!
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
puts
|
|
103
|
-
puts "=== Single Byte Access ==="
|
|
104
|
-
|
|
105
|
-
Benchmark.ips do |x|
|
|
106
|
-
x.config(time: 5, warmup: 2)
|
|
107
|
-
|
|
108
|
-
x.report("data[0, 1].unpack('C').first") do
|
|
109
|
-
DATA[0, 1].unpack('C').first
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
x.report("data.getbyte(0)") do
|
|
113
|
-
DATA.getbyte(0)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
x.report("data[0].ord") do
|
|
117
|
-
DATA[0].ord
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
x.report("data.unpack1('C')") do
|
|
121
|
-
DATA.unpack1('C')
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
x.compare!
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
puts
|
|
128
|
-
puts "=== Buffer Building ==="
|
|
129
|
-
|
|
130
|
-
Benchmark.ips do |x|
|
|
131
|
-
x.config(time: 5, warmup: 2)
|
|
132
|
-
|
|
133
|
-
x.report("String.new + <<") do
|
|
134
|
-
buf = String.new
|
|
135
|
-
buf << "hello"
|
|
136
|
-
buf << "world"
|
|
137
|
-
buf << [1234].pack('N')
|
|
138
|
-
buf
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
x.report("+'' + <<") do
|
|
142
|
-
buf = +''
|
|
143
|
-
buf << "hello"
|
|
144
|
-
buf << "world"
|
|
145
|
-
buf << [1234].pack('N')
|
|
146
|
-
buf
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
x.report("Array#join") do
|
|
150
|
-
parts = []
|
|
151
|
-
parts << "hello"
|
|
152
|
-
parts << "world"
|
|
153
|
-
parts << [1234].pack('N')
|
|
154
|
-
parts.join
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
x.compare!
|
|
158
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: utf-8
|
|
3
|
-
|
|
4
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib"))
|
|
5
|
-
|
|
6
|
-
require "amq/protocol/client"
|
|
7
|
-
require "benchmark"
|
|
8
|
-
|
|
9
|
-
FRAME_SIZE = 128 * 1024
|
|
10
|
-
|
|
11
|
-
puts
|
|
12
|
-
puts "-" * 80
|
|
13
|
-
puts "Benchmarking on #{RUBY_DESCRIPTION}"
|
|
14
|
-
|
|
15
|
-
n = 250_000
|
|
16
|
-
|
|
17
|
-
# warm up the JIT, etc
|
|
18
|
-
puts "Doing a warmup run..."
|
|
19
|
-
15_000.times { AMQ::Protocol::Method.encode_body("a" * 256 * 1024, 1, FRAME_SIZE) }
|
|
20
|
-
|
|
21
|
-
t = Benchmark.realtime do
|
|
22
|
-
n.times { AMQ::Protocol::Method.encode_body("a" * 256 * 1024, 1, FRAME_SIZE) }
|
|
23
|
-
end
|
|
24
|
-
r = (n.to_f/t.to_f)
|
|
25
|
-
|
|
26
|
-
puts "AMQ::Protocol::Method.encode_body rate: #{(r / 1000).round(2)} KGHz"
|
|
27
|
-
puts
|
|
28
|
-
puts "-" * 80
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: utf-8
|
|
3
|
-
|
|
4
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib"))
|
|
5
|
-
|
|
6
|
-
require "amq/protocol/client"
|
|
7
|
-
require "benchmark"
|
|
8
|
-
|
|
9
|
-
FRAME_SIZE = 128 * 1024
|
|
10
|
-
|
|
11
|
-
puts
|
|
12
|
-
puts "-" * 80
|
|
13
|
-
puts "Benchmarking on #{RUBY_DESCRIPTION}"
|
|
14
|
-
|
|
15
|
-
n = 250_000
|
|
16
|
-
|
|
17
|
-
# warm up the JIT, etc
|
|
18
|
-
puts "Doing a warmup run..."
|
|
19
|
-
15_000.times { AMQ::Protocol::Method.encode_body("ab" * 1024, 1, FRAME_SIZE) }
|
|
20
|
-
|
|
21
|
-
t = Benchmark.realtime do
|
|
22
|
-
n.times { AMQ::Protocol::Method.encode_body("ab" * 1024, 1, FRAME_SIZE) }
|
|
23
|
-
end
|
|
24
|
-
r = (n.to_f/t.to_f)
|
|
25
|
-
|
|
26
|
-
puts "AMQ::Protocol::Method.encode_body rate: #{(r / 1000).round(2)} KGHz"
|
|
27
|
-
puts
|
|
28
|
-
puts "-" * 80
|
data/benchmarks/run_all.rb
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: utf-8
|
|
3
|
-
# frozen_string_literal: true
|
|
4
|
-
|
|
5
|
-
# Master benchmark runner
|
|
6
|
-
# Usage: ruby benchmarks/run_all.rb
|
|
7
|
-
|
|
8
|
-
require 'fileutils'
|
|
9
|
-
|
|
10
|
-
BENCHMARK_DIR = File.dirname(__FILE__)
|
|
11
|
-
RESULTS_DIR = File.join(BENCHMARK_DIR, "results")
|
|
12
|
-
|
|
13
|
-
FileUtils.mkdir_p(RESULTS_DIR)
|
|
14
|
-
|
|
15
|
-
benchmarks = %w[
|
|
16
|
-
pack_unpack.rb
|
|
17
|
-
frame_encoding.rb
|
|
18
|
-
table_encoding.rb
|
|
19
|
-
method_encoding.rb
|
|
20
|
-
]
|
|
21
|
-
|
|
22
|
-
timestamp = Time.now.strftime("%Y%m%d_%H%M%S")
|
|
23
|
-
ruby_version = RUBY_VERSION.gsub('.', '_')
|
|
24
|
-
results_file = File.join(RESULTS_DIR, "benchmark_#{ruby_version}_#{timestamp}.txt")
|
|
25
|
-
|
|
26
|
-
puts "=" * 80
|
|
27
|
-
puts "AMQ-Protocol Benchmark Suite"
|
|
28
|
-
puts "=" * 80
|
|
29
|
-
puts "Ruby: #{RUBY_DESCRIPTION}"
|
|
30
|
-
puts "Time: #{Time.now}"
|
|
31
|
-
puts "Results will be saved to: #{results_file}"
|
|
32
|
-
puts "=" * 80
|
|
33
|
-
puts
|
|
34
|
-
|
|
35
|
-
File.open(results_file, 'w') do |f|
|
|
36
|
-
f.puts "AMQ-Protocol Benchmark Results"
|
|
37
|
-
f.puts "Ruby: #{RUBY_DESCRIPTION}"
|
|
38
|
-
f.puts "Time: #{Time.now}"
|
|
39
|
-
f.puts "=" * 80
|
|
40
|
-
f.puts
|
|
41
|
-
|
|
42
|
-
benchmarks.each do |benchmark|
|
|
43
|
-
benchmark_path = File.join(BENCHMARK_DIR, benchmark)
|
|
44
|
-
|
|
45
|
-
if File.exist?(benchmark_path)
|
|
46
|
-
puts "\n>>> Running #{benchmark}..."
|
|
47
|
-
puts
|
|
48
|
-
|
|
49
|
-
output = `ruby #{benchmark_path} 2>&1`
|
|
50
|
-
puts output
|
|
51
|
-
|
|
52
|
-
f.puts ">>> #{benchmark}"
|
|
53
|
-
f.puts output
|
|
54
|
-
f.puts
|
|
55
|
-
else
|
|
56
|
-
puts "Warning: #{benchmark_path} not found, skipping..."
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
puts
|
|
62
|
-
puts "=" * 80
|
|
63
|
-
puts "Benchmark complete! Results saved to: #{results_file}"
|
|
64
|
-
puts "=" * 80
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: utf-8
|
|
3
|
-
# frozen_string_literal: true
|
|
4
|
-
|
|
5
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
6
|
-
|
|
7
|
-
require "amq/protocol/client"
|
|
8
|
-
require "benchmark/ips"
|
|
9
|
-
|
|
10
|
-
puts
|
|
11
|
-
puts "-" * 80
|
|
12
|
-
puts "Table Encoding/Decoding Benchmarks on #{RUBY_DESCRIPTION}"
|
|
13
|
-
puts "-" * 80
|
|
14
|
-
|
|
15
|
-
# Test data - various table sizes and types
|
|
16
|
-
EMPTY_TABLE = {}
|
|
17
|
-
|
|
18
|
-
SIMPLE_TABLE = {
|
|
19
|
-
"key1" => "value1",
|
|
20
|
-
"key2" => 42,
|
|
21
|
-
"key3" => true
|
|
22
|
-
}.freeze
|
|
23
|
-
|
|
24
|
-
TYPICAL_HEADERS = {
|
|
25
|
-
"content_type" => "application/json",
|
|
26
|
-
"content_encoding" => "utf-8",
|
|
27
|
-
"x-custom-header" => "some-value",
|
|
28
|
-
"x-retry-count" => 3,
|
|
29
|
-
"x-timestamp" => Time.now.to_i
|
|
30
|
-
}.freeze
|
|
31
|
-
|
|
32
|
-
COMPLEX_TABLE = {
|
|
33
|
-
"string" => "hello world",
|
|
34
|
-
"integer" => 123456789,
|
|
35
|
-
"float" => 3.14159,
|
|
36
|
-
"boolean_true" => true,
|
|
37
|
-
"boolean_false" => false,
|
|
38
|
-
"nested" => {
|
|
39
|
-
"inner_key" => "inner_value",
|
|
40
|
-
"inner_number" => 999
|
|
41
|
-
},
|
|
42
|
-
"array" => [1, 2, 3, "four", true]
|
|
43
|
-
}.freeze
|
|
44
|
-
|
|
45
|
-
LARGE_TABLE = (1..50).to_h { |i| ["key_#{i}", "value_#{i}"] }.freeze
|
|
46
|
-
|
|
47
|
-
# Pre-encode tables for decode benchmarks
|
|
48
|
-
ENCODED_EMPTY = AMQ::Protocol::Table.encode(EMPTY_TABLE)
|
|
49
|
-
ENCODED_SIMPLE = AMQ::Protocol::Table.encode(SIMPLE_TABLE)
|
|
50
|
-
ENCODED_TYPICAL = AMQ::Protocol::Table.encode(TYPICAL_HEADERS)
|
|
51
|
-
ENCODED_COMPLEX = AMQ::Protocol::Table.encode(COMPLEX_TABLE)
|
|
52
|
-
ENCODED_LARGE = AMQ::Protocol::Table.encode(LARGE_TABLE)
|
|
53
|
-
|
|
54
|
-
puts "Table sizes (bytes): empty=#{ENCODED_EMPTY.bytesize}, simple=#{ENCODED_SIMPLE.bytesize}, typical=#{ENCODED_TYPICAL.bytesize}, complex=#{ENCODED_COMPLEX.bytesize}, large=#{ENCODED_LARGE.bytesize}"
|
|
55
|
-
puts
|
|
56
|
-
|
|
57
|
-
puts "=== Table Encoding ==="
|
|
58
|
-
Benchmark.ips do |x|
|
|
59
|
-
x.config(time: 5, warmup: 2)
|
|
60
|
-
|
|
61
|
-
x.report("encode empty") do
|
|
62
|
-
AMQ::Protocol::Table.encode(EMPTY_TABLE)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
x.report("encode simple (3 keys)") do
|
|
66
|
-
AMQ::Protocol::Table.encode(SIMPLE_TABLE)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
x.report("encode typical headers (5 keys)") do
|
|
70
|
-
AMQ::Protocol::Table.encode(TYPICAL_HEADERS)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
x.report("encode complex (nested/array)") do
|
|
74
|
-
AMQ::Protocol::Table.encode(COMPLEX_TABLE)
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
x.report("encode large (50 keys)") do
|
|
78
|
-
AMQ::Protocol::Table.encode(LARGE_TABLE)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
x.compare!
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
puts
|
|
85
|
-
puts "=== Table Decoding ==="
|
|
86
|
-
Benchmark.ips do |x|
|
|
87
|
-
x.config(time: 5, warmup: 2)
|
|
88
|
-
|
|
89
|
-
x.report("decode empty") do
|
|
90
|
-
AMQ::Protocol::Table.decode(ENCODED_EMPTY)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
x.report("decode simple (3 keys)") do
|
|
94
|
-
AMQ::Protocol::Table.decode(ENCODED_SIMPLE)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
x.report("decode typical headers (5 keys)") do
|
|
98
|
-
AMQ::Protocol::Table.decode(ENCODED_TYPICAL)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
x.report("decode complex (nested/array)") do
|
|
102
|
-
AMQ::Protocol::Table.decode(ENCODED_COMPLEX)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
x.report("decode large (50 keys)") do
|
|
106
|
-
AMQ::Protocol::Table.decode(ENCODED_LARGE)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
x.compare!
|
|
110
|
-
end
|
data/codegen/__init__.py
DELETED
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"tx": {"select-ok": ["client"], "rollback": ["server"], "commit": ["server"], "rollback-ok": ["client"], "select": ["server"], "commit-ok": ["client"]}, "exchange": {"delete-ok": ["client"], "declare-ok": ["client"], "declare": ["server"], "delete": ["server"], "bind": ["server"], "bind-ok": ["client"], "unbind": ["server"], "unbind-ok": ["client"]}, "queue": {"unbind": ["server"], "unbind-ok": ["client"], "purge-ok": ["client"], "bind": ["server"], "purge": ["server"], "declare-ok": ["client"], "delete-ok": ["client"], "delete": ["server"], "declare": ["server"], "bind-ok": ["client"]}, "connection": {"secure": ["client"], "secure-ok": ["server"], "open-ok": ["client"], "close-ok": ["client", "server"], "start": ["client"], "tune": ["client"], "start-ok": ["server"], "close": ["client", "server"], "open": ["server"], "tune-ok": ["server"]}, "basic": {"qos": ["server"], "consume": ["server"], "reject": ["server"], "get": ["server"], "ack": ["client", "server"], "get-ok": ["client"], "consume-ok": ["client"], "deliver": ["client"], "recover-ok": ["client"], "publish": ["server"], "cancel": ["server", "client"], "recover-async": ["server"], "get-empty": ["client"], "qos-ok": ["client"], "return": ["client"], "recover": ["server"], "cancel-ok": ["client"]}, "channel": {"flow-ok": ["server", "client"], "flow": ["server", "client"], "open-ok": ["client"], "close-ok": ["client", "server"], "close": ["client", "server"], "open": ["server"]}}
|
data/codegen/codegen.py
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
# Documentation for Mako templates:
|
|
5
|
-
# http://www.makotemplates.org/docs/syntax.html
|
|
6
|
-
|
|
7
|
-
import os, sys, re
|
|
8
|
-
|
|
9
|
-
sys.path.append(os.path.join("codegen", "rabbitmq-codegen"))
|
|
10
|
-
|
|
11
|
-
from amqp_codegen import *
|
|
12
|
-
try:
|
|
13
|
-
from mako.template import Template
|
|
14
|
-
except ImportError:
|
|
15
|
-
print("Mako isn't installed. Please install mako via pip or similar.")
|
|
16
|
-
sys.exit(1)
|
|
17
|
-
|
|
18
|
-
# main class
|
|
19
|
-
class AmqpSpecObject(AmqpSpec):
|
|
20
|
-
IGNORED_CLASSES = ["access"]
|
|
21
|
-
IGNORED_FIELDS = {
|
|
22
|
-
'ticket': 0,
|
|
23
|
-
'capabilities': '',
|
|
24
|
-
'insist' : 0,
|
|
25
|
-
'out_of_band': '',
|
|
26
|
-
'known_hosts': '',
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
def __init__(self, path):
|
|
30
|
-
AmqpSpec.__init__(self, path)
|
|
31
|
-
|
|
32
|
-
def extend_field(field):
|
|
33
|
-
field.ruby_name = re.sub("[- ]", "_", field.name)
|
|
34
|
-
field.type = self.resolveDomain(field.domain)
|
|
35
|
-
field.ignored = bool(field.name in self.__class__.IGNORED_FIELDS) # I. e. deprecated
|
|
36
|
-
|
|
37
|
-
for klass in self.classes:
|
|
38
|
-
klass.ignored = bool(klass.name in self.__class__.IGNORED_CLASSES)
|
|
39
|
-
|
|
40
|
-
for field in klass.fields:
|
|
41
|
-
extend_field(field)
|
|
42
|
-
|
|
43
|
-
for method in klass.methods:
|
|
44
|
-
for field in method.arguments:
|
|
45
|
-
extend_field(field)
|
|
46
|
-
|
|
47
|
-
self.classes = filter(lambda klass: not klass.ignored, self.classes)
|
|
48
|
-
|
|
49
|
-
original_init = AmqpEntity.__init__
|
|
50
|
-
def new_init(self, arg):
|
|
51
|
-
original_init(self, arg)
|
|
52
|
-
constant_name = ""
|
|
53
|
-
for chunk in self.name.split("-"):
|
|
54
|
-
constant_name += chunk.capitalize()
|
|
55
|
-
self.constant_name = constant_name
|
|
56
|
-
AmqpEntity.__init__ = new_init
|
|
57
|
-
|
|
58
|
-
# method.accepted_by("server")
|
|
59
|
-
# method.accepted_by("client", "server")
|
|
60
|
-
accepted_by_update = json.loads(open("codegen/amqp_0.9.1_changes.json").read())
|
|
61
|
-
|
|
62
|
-
def accepted_by(self, *receivers):
|
|
63
|
-
def get_accepted_by(self):
|
|
64
|
-
try:
|
|
65
|
-
return accepted_by_update[self.klass.name][self.name]
|
|
66
|
-
except KeyError:
|
|
67
|
-
return ["server", "client"]
|
|
68
|
-
|
|
69
|
-
actual_receivers = get_accepted_by(self)
|
|
70
|
-
return all(map(lambda receiver: receiver in actual_receivers, receivers))
|
|
71
|
-
|
|
72
|
-
AmqpMethod.accepted_by = accepted_by
|
|
73
|
-
|
|
74
|
-
def convert_value_to_ruby(value):
|
|
75
|
-
values = {None: "nil", False: "false", True: "true", "": "EMPTY_STRING"}
|
|
76
|
-
|
|
77
|
-
try:
|
|
78
|
-
return values[value]
|
|
79
|
-
except:
|
|
80
|
-
return value.__repr__()
|
|
81
|
-
|
|
82
|
-
def convert_to_ruby(field):
|
|
83
|
-
name = re.sub("-", "_", field.name) # TODO: use ruby_name
|
|
84
|
-
if name == "ticket":
|
|
85
|
-
return "%s = %s" % (name, field.defaultvalue) # we want to keep it as an int, not as a boolean
|
|
86
|
-
else:
|
|
87
|
-
return "%s = %s" % (name, convert_value_to_ruby(field.defaultvalue))
|
|
88
|
-
|
|
89
|
-
def not_ignored_args(self):
|
|
90
|
-
if self.hasContent:
|
|
91
|
-
return ["payload", "user_headers"] + map(lambda argument: argument.ruby_name, filter(lambda argument: not argument.ignored, self.arguments)) + ["frame_size"]
|
|
92
|
-
else:
|
|
93
|
-
return map(lambda argument: argument.ruby_name, filter(lambda argument: not argument.ignored, self.arguments))
|
|
94
|
-
|
|
95
|
-
AmqpMethod.not_ignored_args = not_ignored_args
|
|
96
|
-
|
|
97
|
-
def ignored_args(self):
|
|
98
|
-
return filter(lambda argument: argument.ignored, self.arguments)
|
|
99
|
-
|
|
100
|
-
AmqpMethod.ignored_args = ignored_args
|
|
101
|
-
|
|
102
|
-
# helpers
|
|
103
|
-
def to_ruby_name(name):
|
|
104
|
-
return re.sub("[- ]", "_", name)
|
|
105
|
-
|
|
106
|
-
def to_ruby_class_name(name):
|
|
107
|
-
parts = re.split("[- ]", name)
|
|
108
|
-
ruby_class_name = ""
|
|
109
|
-
for part in parts:
|
|
110
|
-
ruby_class_name = ruby_class_name + part[0].upper() + part[1:].lower()
|
|
111
|
-
return ruby_class_name
|
|
112
|
-
|
|
113
|
-
def params(self):
|
|
114
|
-
buffer = []
|
|
115
|
-
for f in self.arguments:
|
|
116
|
-
buffer.append(convert_to_ruby(f))
|
|
117
|
-
if self.hasContent:
|
|
118
|
-
buffer.append("user_headers = nil")
|
|
119
|
-
buffer.append("payload = \"\"")
|
|
120
|
-
buffer.append("frame_size = nil")
|
|
121
|
-
return buffer
|
|
122
|
-
|
|
123
|
-
AmqpMethod.params = params
|
|
124
|
-
|
|
125
|
-
def args(self):
|
|
126
|
-
return map(lambda item: item.split(" ")[0], self.params())
|
|
127
|
-
|
|
128
|
-
AmqpMethod.args = args
|
|
129
|
-
|
|
130
|
-
def binary(self):
|
|
131
|
-
method_id = self.klass.index << 16 | self.index
|
|
132
|
-
return "0x%08X # %i, %i, %i" % (method_id, self.klass.index, self.index, method_id)
|
|
133
|
-
|
|
134
|
-
AmqpMethod.binary = binary
|
|
135
|
-
|
|
136
|
-
# helpers
|
|
137
|
-
def render(path, **context):
|
|
138
|
-
file = open(path)
|
|
139
|
-
template = Template(file.read())
|
|
140
|
-
return template.render(**context)
|
|
141
|
-
|
|
142
|
-
def generateMain(type):
|
|
143
|
-
def main(json_spec_path):
|
|
144
|
-
spec = AmqpSpecObject(json_spec_path)
|
|
145
|
-
spec.type = type
|
|
146
|
-
print(render("codegen/protocol.rb.pytemplate", spec = spec))
|
|
147
|
-
|
|
148
|
-
return main
|
|
149
|
-
|
|
150
|
-
if __name__ == "__main__":
|
|
151
|
-
do_main_dict({"client": generateMain("client")})
|