def new_transaction(group_name, category, key)
if !@server_address
return Transaction.new(nil, nil)
elsif !group_name || group_name.empty?
raise ArgumentError, 'Group name may not be empty'
end
Lock.new(@mutex).synchronize do |_lock|
if Time.now < @next_reconnect_time
return Transaction.new(nil, nil)
end
Lock.new(@connection.mutex).synchronize do |connection_lock|
if !@connection.connected?
begin
connect
connection_lock.reset(@connection.mutex)
rescue SystemCallError, IOError
@connection.disconnect
UnionStationHooks::Log.warn(
"Cannot connect to the UstRouter at #{@server_address}; " \
"retrying in #{@reconnect_timeout} second(s).")
@next_reconnect_time = Time.now + @reconnect_timeout
return Transaction.new(nil, nil)
rescue Exception => e
@connection.disconnect
raise e
end
end
begin
@connection.channel.write('openTransaction',
'', group_name, '', category,
Utils.encoded_timestamp,
key,
true,
true)
result = @connection.channel.read
if result[0] != 'status'
raise "Expected UstRouter to respond with 'status', " \
"but got #{result.inspect} instead"
elsif result[1] == 'error'
if result[2]
raise "Unable to close transaction: #{result[2]}"
else
raise 'Unable to close transaction (no server message given)'
end
elsif result[1] != 'ok'
raise "Expected UstRouter to respond with 'ok' or 'error', " \
"but got #{result.inspect} instead"
elsif result.size < 3
raise 'Expected UstRouter to respond with an autogenerated ' \
'transaction ID, but got none'
end
return Transaction.new(@connection, result[2])
rescue SystemCallError, IOError
@connection.disconnect
UnionStationHooks::Log.warn(
"The UstRouter at #{@server_address}" \
' closed the connection; will reconnect in ' \
"#{@reconnect_timeout} second(s).")
@next_reconnect_time = Time.now + @reconnect_timeout
return Transaction.new(nil, nil)
rescue Exception => e
@connection.disconnect
raise e
end
end
end
end