# File src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/context.rb, line 104
    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