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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## Unreleased

### Bug Fixes 🐛

- Send buffered logs and metrics on the background worker instead of the thread that filled the buffer by @ikraamg in [#3079](https://github.com/getsentry/sentry-ruby/pull/3079)

## 7.0.0

### Breaking Changes 🛠
Expand Down
11 changes: 10 additions & 1 deletion sentry-ruby/lib/sentry/telemetry_event_buffer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,16 @@ def send_items
{ items: envelope_items }
)

@client.send_envelope(envelope)
# Off the calling thread: send_items runs under @mutex, so a request thread that filled the
# buffer would otherwise hold every other add_item caller behind its HTTP round trip.
queued = Sentry.background_worker.perform do
@client.send_envelope(envelope)
rescue => e
log_error("[#{self.class}] Failed to send #{@event_class}", e, debug: @debug)
end
Comment thread
cursor[bot] marked this conversation as resolved.

# A full worker queue discards the block without raising, the same way it drops an event.
@client.transport.record_lost_event(:queue_overflow, @data_category, num: envelope_items.size) unless queued
rescue => e
log_error("[#{self.class}] Failed to send #{@event_class}", e, debug: @debug)
ensure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,46 @@
end
end

describe "sending" do
let(:max_items) { 3 }

before do
Sentry.configuration.background_worker_threads = 1
Sentry.background_worker = Sentry::BackgroundWorker.new(Sentry.configuration)
end

it "sends the envelope on the background worker, not on the thread that filled the buffer" do
sending_thread = nil
allow(client).to receive(:send_envelope) { sending_thread = Thread.current }

3.times { subject.add_item(event) }
Sentry.background_worker.shutdown

expect(sending_thread).not_to be_nil
expect(sending_thread).not_to eq(Thread.current)
end

it "records the batch as lost when the background worker's queue is full" do
allow(Sentry.background_worker).to receive(:perform).and_return(false)
expect(client.transport).to receive(:record_lost_event).with(:queue_overflow, subject.data_category, num: 3)

3.times { subject.add_item(event) }

expect(subject).to be_empty
end

it "flushes on the background worker too" do
sending_thread = nil
allow(client).to receive(:send_envelope) { sending_thread = Thread.current }

subject.add_item(event)
subject.flush
Sentry.background_worker.shutdown

expect(sending_thread).not_to eq(Thread.current)
end
end

describe "multi-threaded access" do
let(:max_items) { 30 }

Expand Down