Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion app/controllers/runtime/stagings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,28 @@ def download_package(guid)
raise ApiError.new_from_details('BlobstoreNotLocal') unless package_blobstore.local?

package = PackageModel.find(guid:)
raise ApiError.new_from_details('NotFound', guid) if package.nil?
if package.nil?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a 2nd condition here so that this can only run in tests? Maybe some existing rspec env var?

# FLAKE_DEBUG: temporary instrumentation for the intermittent 404 on this
# endpoint (a just-created package un-findable by its own guid). Fires only
# on the nil path, so it is silent in normal operation. Captures, on the
# connection the SELECT actually used, whether the row is physically present
# (raw_match), how many package rows are visible at all (total_count), whether
# the surrounding transaction is still open (in_txn), and the identity of the
# db/connection/thread so a swap vs. the inserting side is detectable.
# Revert once CI has logged one occurrence. See the test-side counterpart in
# spec/unit/controllers/runtime/stagings_controller_spec.rb.
db = PackageModel.db
raw_match = db[:packages].where(guid:).count
total_count = db[:packages].count
conn_id = db.synchronize(&:object_id)
logger.error(
"FLAKE_DEBUG stagings-404 guid=#{guid} raw_match=#{raw_match} " \
"total_count=#{total_count} in_txn=#{db.in_transaction?} " \
"db_id=#{db.object_id} conn_id=#{conn_id} " \
"thread_id=#{Thread.current.object_id}"
)
raise ApiError.new_from_details('NotFound', guid)
end

blob = package_blobstore.blob(guid)
if blob.nil?
Expand Down
20 changes: 19 additions & 1 deletion spec/unit/controllers/runtime/stagings_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,25 @@ module VCAP::CloudController
describe 'GET /staging/packages/:guid' do
let(:package) { create(:package_model) }

before { authorize(staging_user, staging_password) }
# FLAKE_DEBUG: temporary instrumentation for the intermittent 404 on this
# endpoint. Force the lazy `package` INSERT here and log the db/connection/
# thread identity of the INSERTING side, so the controller-side FLAKE_DEBUG
# line (app/controllers/runtime/stagings_controller.rb) has a baseline to
# compare against -- a connection or thread swap between insert and read is
# only conclusive with both sides logged. Revert together with the
# controller-side probe once CI has captured one occurrence.
before do
authorize(staging_user, staging_password)

db = VCAP::CloudController::PackageModel.db
guid = package.guid
conn_id = db.synchronize(&:object_id)
warn(
"FLAKE_DEBUG stagings-404-insert guid=#{guid} " \
"in_txn=#{db.in_transaction?} db_id=#{db.object_id} " \
"conn_id=#{conn_id} thread_id=#{Thread.current.object_id}"
)
end

def create_test_blob
tmpfile = Tempfile.new('staging-test-blob')
Expand Down
Loading