1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
# frozen_string_literal: true
# Released under the MIT License.
# Copyright, 2023, by Samuel Williams.
require 'fiber'
class Fiber
# A mechanism for annotating fibers.
module Annotation
# Annotate the current fiber with the given annotation.
# @parameter annotation [Object] The annotation to set.
def initialize(annotation: nil, **options, &block)
@annotation = annotation
super(**options, &block)
end
# Get the current annotation.
# @returns [Object] The current annotation.
attr_accessor :annotation
# Annotate the current fiber with the given annotation.
#
# If a block is given, the annotation is set for the duration of the block and then restored to the previous value.
#
# The block form of this method should only be invoked on the current fiber.
#
# @parameter annotation [Object] The annotation to set.
# @yields {} The block to execute with the given annotation.
# @returns [Object] The return value of the block.
def annotate(annotation)
if block_given?
raise "Cannot annotation a different fiber!" unless Fiber.current == self
begin
current_annotation = @annotation
@annotation = annotation
return yield
ensure
@annotation = current_annotation
end
else
@annotation = annotation
end
end
end
end
unless Fiber.method_defined?(:annotation)
Fiber.prepend(Fiber::Annotation)
# @scope Fiber
# @name self.annotate
# Annotate the current fiber with the given annotation.
def Fiber.annotate(...)
Fiber.current.annotate(...)
end
end
|