Something went wrong. Try again.
A tool for measuring the coverage of Bluesky/ATProto relays forked from mackuba.eu/pulsar
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138#!/usr/bin/env ruby
require 'bundler/setup'
require 'optparse'require 'skyfall'require 'timeout'require 'yaml'
require_relative 'init'require_relative 'models'
$stdout.sync = true
def get_hosts(entries) if entries entries.map { |x| x.is_a?(Hash) ? x['host'] : x } else [] endend
def parse_options(argv) options = {}
parser = OptionParser.new do |opts| opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
opts.on('-i', '--interval SECONDS', Integer, 'Interval to wait between pingu attempts') do |seconds| options[:interval] = seconds end
opts.on('-t', '--timeout SECONDS', Integer, 'Max number of seconds to wait for connection and response') do |seconds| options[:timeout] = seconds end
opts.on('-n', '--no-save', "Don't save pingu results to the database") do options[:dont_save] = true end
opts.on('-h', '--help', 'Show help') do puts opts exit 0 end end
parser.parse!(argv)
optionsrescue OptionParser::ParseError => e warn e.message warn parser exit 1end
config = YAML.load(File.read(SOURCES))options = parse_options(ARGV)
relays = get_hosts(config['relays'])jetstreams = get_hosts(config['jetstreams'])
ping_interval = options[:interval] || 5 * 60.0timeout_len = options[:timeout] || 15.0
sources = (relays.map { |h| [:firehose, h] } + jetstreams.map { |h| [:jetstream, h] }).sort_by(&:last)
last_times = Ping.select('MAX(time) AS time, host').group('host').map { |x| [x.host, x.time] }.to_hstarting_host = sources.map { |type, host| [host, last_times[host].to_i] }.sort_by { |host, time| [time, host] }[0][0]index = sources.index { |type, host| host == starting_host }
sky = nilstopping = false
trap("SIGINT") { puts "Stopping..." stopping = true sky ? sky.disconnect : raise(Interrupt)}
trap("SIGTERM") { puts "Shutting down the service..." stopping = true sky ? sky.disconnect : raise(Interrupt)}
begin loop do type, host = sources[index] sky = (type == :firehose) ? Skyfall::Firehose.new(host) : Skyfall::Jetstream.new(host)
connected = false got_error = false got_message = false start_time = Time.now
sky.on_connecting do puts "[#{Time.now}] #{host}: Connecting..." end
sky.on_connect do puts "[#{Time.now}] #{host}: Connected ✓" connected = true end
sky.on_error do |e| puts "[#{Time.now}] #{host}: ERROR: #{e.message}" got_error = true sky.disconnect end
sky.on_message do |msg| puts "[#{Time.now}] #{host}: Received message ✓" unless got_message got_message = true sky.disconnect end
begin Timeout.timeout(timeout_len) do sky.connect puts "[#{Time.now}] #{host}: Closed connection" end rescue Timeout::Error puts "[#{Time.now}] #{host}: Connection timed out" ensure sky = nil end
break if stopping
Ping.create!(host: host, time: start_time, connected: connected, got_error: got_error, got_message: got_message)
index = (index + 1) % sources.length sleep(ping_interval) endrescue Interrupt # finishend