github.com/anycable/anycable-go@v1.5.1/features/enats_broker.testfile (about) 1 launch :rpc, "bundle exec anyt --only-rpc", 2 env: {"ANYCABLE_BROADCAST_ADAPTER" => "http"} 3 wait_tcp 50051 4 5 store_path = File.expand_path("../tmp/nats-data", __dir__) 6 FileUtils.rm_rf(store_path) if File.directory?(store_path) 7 8 launch :anycable_1, 9 "./dist/anycable-go --port 8080 --broker=nats --pubsub=nats --broadcast_adapter=http --embed_nats --enats_addr=nats://localhost:4242 --enats_cluster=nats://localhost:4342 --enats_gateway=nats://localhost:4442 --enats_cluster_routes=nats://localhost:4342 --enats_store_dir=#{store_path}/one" 10 11 sleep 1 12 13 launch :anycable_2, 14 "./dist/anycable-go --port 8081 --broker=nats --pubsub=nats --broadcast_adapter=nats --embed_nats --enats_addr=nats://localhost:4243 --enats_cluster=nats://localhost:4343 --enats_cluster_routes=nats://localhost:4342 --enats_store_dir=#{store_path}/two" 15 16 sleep 1 17 18 launch :anycable_3, 19 "./dist/anycable-go --port 8082 --broker=nats --pubsub=nats --broadcast_adapter=nats --embed_nats --enats_addr=nats://localhost:4244 --enats_cluster=nats://localhost:4344 --enats_cluster_routes=nats://localhost:4342 --enats_store_dir=#{store_path}/three" 20 21 wait_tcp 8080 22 wait_tcp 8081 23 wait_tcp 8082 24 25 # Wait for JetStream to be ready; we can do this by checking that the epoch data has been written on disk 26 timeout = 20 27 log(:info) { "Waiting for JetStream to be ready" } 28 loop do 29 break if Dir["#{store_path}/**/*"].any? { |f| f =~ /KV__anycable_epoch_/ } 30 31 Kernel.sleep 0.5 32 timeout -= 0.5 33 34 if timeout < 0 35 fail "JetStream is not ready" 36 end 37 end 38 39 # Let's wait for epoch to be propagated to all nodes 40 sleep 2 41 42 # We need to obtain epoch first 43 epoch_scenario = [ 44 { 45 client: { 46 protocol: "action_cable", 47 actions: [ 48 { 49 subscribe: { 50 channel: "BenchmarkChannel" 51 } 52 }, 53 { 54 perform: { 55 channel: "BenchmarkChannel", 56 action: "broadcast", 57 data: { 58 message: "hello" 59 } 60 } 61 }, 62 { 63 receive: { 64 channel: "BenchmarkChannel", 65 "data>": { 66 message: "hello", 67 action: "broadcast", 68 }, 69 stream_id: "all", 70 print: true 71 } 72 } 73 ] 74 } 75 } 76 ] 77 78 result = nil 79 80 retrying(delay: 2) do 81 run :wsdirector, "bundle exec wsdirector ws://localhost:8080/cable -i #{epoch_scenario.to_json}" 82 83 result = stdout(:wsdirector) 84 85 if result !~ /1 clients, 0 failures/ 86 fail "Unexpected scenario result:\n#{result}" 87 end 88 end 89 90 epoch = result.match(/"epoch":"([^"]+)"/)[1] 91 92 if epoch.nil? || epoch.empty? 93 fail "Epoch is missing" 94 end 95 96 scenario = [ 97 { 98 client: { 99 protocol: "action_cable", 100 name: "publisher", 101 actions: [ 102 { 103 subscribe: { 104 channel: "BenchmarkChannel" 105 } 106 }, 107 "wait_all", 108 { 109 perform: { 110 channel: "BenchmarkChannel", 111 action: "broadcast", 112 data: { 113 message: "hello" 114 } 115 } 116 }, 117 { 118 receive: { 119 channel: "BenchmarkChannel", 120 "data>": { 121 message: "hello", 122 action: "broadcast", 123 }, 124 stream_id: "all", 125 epoch: epoch 126 } 127 }, 128 { 129 receive: { 130 channel: "BenchmarkChannel", 131 data: { 132 message: "hello", 133 action: "broadcastResult" 134 } 135 } 136 } 137 ] 138 } 139 }, 140 { 141 client: { 142 protocol: "action_cable", 143 name: "subscriber", 144 multiplier: ":scale", 145 connection_options: { 146 url: "http://localhost:8081/cable" 147 }, 148 actions: [ 149 { 150 subscribe: { 151 channel: "BenchmarkChannel" 152 } 153 }, 154 "wait_all", 155 { 156 receive: { 157 channel: "BenchmarkChannel", 158 "data>": { 159 message: "hello", 160 action: "broadcast" 161 }, 162 stream_id: "all", 163 epoch: epoch 164 } 165 } 166 ] 167 } 168 }, 169 { 170 client: { 171 protocol: "action_cable", 172 name: "another_subscriber", 173 multiplier: ":scale", 174 connection_options: { 175 url: "http://localhost:8082/cable" 176 }, 177 actions: [ 178 { 179 subscribe: { 180 channel: "BenchmarkChannel" 181 } 182 }, 183 "wait_all", 184 { 185 receive: { 186 channel: "BenchmarkChannel", 187 "data>": { 188 message: "hello", 189 action: "broadcast" 190 }, 191 stream_id: "all", 192 epoch: epoch 193 } 194 } 195 ] 196 } 197 } 198 ] 199 200 TEST_COMMAND = <<~CMD 201 bundle exec wsdirector ws://localhost:8080/cable -i #{scenario.to_json} -s 4 202 CMD 203 204 retrying(delay: 2) do 205 run :wsdirector, TEST_COMMAND 206 207 result = stdout(:wsdirector) 208 209 unless result.include?("Group publisher: 1 clients, 0 failures") && 210 result.include?("Group subscriber: 4 clients, 0 failures") && 211 result.include?("Group another_subscriber: 4 clients, 0 failures") 212 fail "Unexpected scenario result:\n#{result}" 213 end 214 end