AWS::S3 is not threadsafe. Hell, it’s not even reusable; most methods go through a class constant. To use it in threaded code, it’s necessary to isolate S3 operations in memory. Fork to the rescue!

def s3(key, data, bucket, opts)
  begin
    fork_to do
      AWS::S3::Base.establish_connection!(
        :access_key_id => KEY,
        :secret_access_key => SECRET
      )
      AWS::S3::S3Object.store key, data, bucket, opts
    end
  rescue Timeout::Error
    raise SubprocessTimedOut
  end
end

def fork_to(timeout = 4)
  r, w, pid = nil, nil, nil
  begin
    # Open pipe
    r, w = IO.pipe

    # Start subprocess
    pid = fork do
      # Child
      begin
        r.close

        val = begin
          Timeout.timeout(timeout) do
            # Run block
            yield
          end
        rescue Exception => e
          e
        end

        w.write Marshal.dump val
        w.close
      ensure
        # YOU SHALL NOT PASS
        # Skip at_exit handlers.
        exit!
      end
    end

    # Parent
    w.close

    Timeout.timeout(timeout) do
      # Read value from pipe
      begin
        val = Marshal.load r.read
      rescue ArgumentError => e
        # Marshal data too short
        # Subprocess likely exited without writing.
        raise Timeout::Error
      end

      # Return or raise value from subprocess.
      case val
      when Exception
        raise val
      else
        return val
      end
    end
  ensure
    if pid
      Process.kill "TERM", pid rescue nil
      Process.kill "KILL", pid rescue nil
      Process.waitpid pid rescue nil
    end
    r.close rescue nil
    w.close rescue nil
  end
end

Continue reading (312 words)

Hello, law enforcement. I suspect you’re reading this because, as a TSA supervisor told me recently, “… we are interested in you”.

Yes, I asked to fly selectee–to not provide ID–at Denver International recently. Yes, I’ve done this before. Yes, there was a lot of confusion between TSA employees on whether that was legal or not–eventually M. Gatling of the DIA police told me I was required to display ID. Yes, I opted out of AIT. Yes, it did take no fewer than eight TSA officers, airline representatives, and police about 45 minutes to determine I posed no threat. Yes, I was exceedingly polite, and most of us got along quite well. Yes, I was asked all kinds of questions I was under no obligation to answer (among them my address and phone number), and no, the TSA supervisor was not very pleased that I asked whether I was legally required to respond.

Continue reading (1453 words)

So Technology Review published a summary of an arxiv article arguing for mass quantization in black holes. Looks like an ultraviolet catastrophe argument, which is fascinating in itself. But first, I have to address this journalistic clusterfuck:

Of course, the question of this kind of black hole production at the LHC once again raises the thorny question of whether the safety assurances we’ve been given about these experiments are valid.

Continue reading (498 words)

If you ever need to unzip data compressed with zlib without a header (e.g. produced by Erlang’s zlib:zip), it pays to be aware that

windowBits can also be -8..-15 for raw inflate. In this case, -windowBits determines the window size. inflate() will then process raw deflate data, not looking for a zlib or gzip header, not generating a check value, and not looking for any check values for comparison at the end of the stream. (zlib.h)

Continue reading (95 words)