Skip to content

Commit

Permalink
Add .duplicate transaction method
Browse files Browse the repository at this point in the history
Implement support for the `appsignal_transaction_duplicate` method
implemented in the agent side the extension, in both the Ruby C
extension and the JRuby FFI extension.

Implement a `duplicate` method for the `Transaction` class that
calls the extension's own `duplicate` method to duplicate a
transaction.
  • Loading branch information
unflxw committed Jul 24, 2024
1 parent 85dc75d commit 6f9195c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 15 deletions.
25 changes: 25 additions & 0 deletions ext/appsignal_extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,30 @@ static VALUE finish_transaction(VALUE self, VALUE gc_duration_ms) {
return sample == 1 ? Qtrue : Qfalse;
}

static VALUE duplicate_transaction(VALUE self, VALUE new_transaction_id) {
appsignal_transaction_t* transaction;
appsignal_transaction_t* duplicate_transaction;

Check_Type(new_transaction_id, T_STRING);
Data_Get_Struct(self, appsignal_transaction_t, transaction);

duplicate_transaction = appsignal_duplicate_transaction(
transaction,
make_appsignal_string(new_transaction_id)
);

if (duplicate_transaction) {
return Data_Wrap_Struct(
Transaction,
NULL,
appsignal_free_transaction,
duplicate_transaction
);
} else {
return Qnil;
}
}

static VALUE complete_transaction(VALUE self) {
appsignal_transaction_t* transaction;

Expand Down Expand Up @@ -858,6 +882,7 @@ void Init_appsignal_extension(void) {
rb_define_method(Transaction, "set_queue_start", set_transaction_queue_start, 1);
rb_define_method(Transaction, "set_metadata", set_transaction_metadata, 2);
rb_define_method(Transaction, "finish", finish_transaction, 1);
rb_define_method(Transaction, "duplicate", duplicate_transaction, 1);
rb_define_method(Transaction, "complete", complete_transaction, 0);
rb_define_method(Transaction, "to_json", transaction_to_json, 0);

Expand Down
14 changes: 14 additions & 0 deletions lib/appsignal/extension/jruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ def self.lib_extension
attach_function :appsignal_complete_transaction,
[:pointer],
:void
attach_function :appsignal_duplicate_transaction,
[:pointer, :appsignal_string],
:pointer
attach_function :appsignal_transaction_to_json,
[:pointer],
:appsignal_string
Expand Down Expand Up @@ -432,6 +435,17 @@ def finish(gc_duration_ms)
Extension.appsignal_finish_transaction(pointer, gc_duration_ms)
end

def duplicate(new_transaction_id)
duplicate_transaction = Extension.appsignal_duplicate_transaction(
pointer,
make_appsignal_string(new_transaction_id)
)

return if !duplicate_transaction || duplicate_transaction.null?

Transaction.new(duplicate_transaction)
end

def complete
Extension.appsignal_complete_transaction(pointer)
end
Expand Down
43 changes: 28 additions & 15 deletions lib/appsignal/transaction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def clear_current_transaction!

# @api private
attr_reader :ext, :transaction_id, :action, :namespace, :request, :paused, :tags, :options,
:breadcrumbs, :custom_data
:breadcrumbs, :custom_data, :is_duplicate

# Use {.create} to create new transactions.
#
Expand All @@ -110,6 +110,7 @@ def initialize(transaction_id, namespace)
@session_data = nil
@headers = nil
@errors = []
@is_duplicate = false

@ext = Appsignal::Extension.start_transaction(
@transaction_id,
Expand All @@ -129,24 +130,17 @@ def complete
return
end

sample_data if !@duplicate && @ext.finish(0)
sample_data unless @is_duplicate

transactions =
@errors.each do |error|
# This part would be done in the extension like:
# transaction = @ext.duplicate_transaction

transaction = self.class.new(
SecureRandom.uuid,
namespace,
request,
options
)
transaction.ext = ext.duplicate
transaction.duplicate = true
transaction.set_error(error)
transaction.complete
transaction.duplicate do |transaction|
transaction.set_error(error)
transaction.complete
end
end

@ext.finish(0)
@ext.complete

transactions.each(&:complete)
Expand Down Expand Up @@ -566,6 +560,10 @@ def to_h
end
alias_method :to_hash, :to_h

protected

attr_writer :ext, :is_duplicate

private

def set_sample_data(key, data)
Expand Down Expand Up @@ -608,6 +606,21 @@ def sample_data
end
end

def duplicate
self.class.new(
SecureRandom.uuid,
namespace,
request,
options
).tap do |transaction|
transaction.ext = ext.duplicate(
transaction.transaction_id
)

transaction.is_duplicate = true
end
end

# @api private
def params
return unless @params
Expand Down
4 changes: 4 additions & 0 deletions spec/lib/appsignal/extension_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@
subject.finish(0)
end

it "should have a duplicate method" do
subject.duplicate("request_id")
end

it "should have a complete method" do
subject.complete
end
Expand Down

0 comments on commit 6f9195c

Please sign in to comment.