Sha256: de16364cd2e8ec77f0f6dddbb0754ceca80c468ce6013c72d8a7317628f4bd6e
Contents?: true
Size: 1.38 KB
Versions: 2
Compression:
Stored size: 1.38 KB
Contents
# frozen_string_literal: true export_default :CancelScope require 'fiber' Exceptions = import('./exceptions') # A cancellation scope that can be used to cancel an asynchronous task class CancelScope def initialize(opts = {}, &block) @opts = opts @fibers = [] start_timeout_waiter if @opts[:timeout] call(&block) if block end def error_class @opts[:mode] == :cancel ? Exceptions::Cancel : Exceptions::MoveOn end def cancel! @cancelled = true @fibers.each do |f| f.cancelled = true f.schedule error_class.new(self, @opts[:value]) end @on_cancel&.() end def start_timeout_waiter @timeout_waiter = spin do sleep @opts[:timeout] @timeout_waiter = nil cancel! end end def stop_timeout_waiter return unless @timeout_waiter @timeout_waiter.stop @timeout_waiter = nil end def reset_timeout return unless @timeout_waiter @timeout_waiter.stop start_timeout_waiter end # def disable # @timeout&.stop # end def call fiber = Fiber.current @fibers << fiber fiber.cancelled = nil yield self rescue Exceptions::MoveOn => e e.scope == self ? e.value : raise(e) ensure @fibers.delete fiber stop_timeout_waiter if @fibers.empty? && @timeout_waiter end def on_cancel(&block) @on_cancel = block end def cancelled? @cancelled end end
Version data entries
2 entries across 2 versions & 1 rubygems
Version | Path |
---|---|
polyphony-0.24 | lib/polyphony/core/cancel_scope.rb |
polyphony-0.23 | lib/polyphony/core/cancel_scope.rb |