Class: Restate::CombinedFuture

Inherits:
Object
  • Object
show all
Defined in:
lib/restate/durable_future.rb

Overview

A lazy combinator over one or more child futures. The child set can mix DurableFuture leaves (with raw handles) and nested CombinedFuture nodes. The shared-core uses the tree shape to make suspension decisions; nothing blocks until .await is called, so combinators are composable:

Restate.race(Restate.all(a, b), c).await

Supported variants (mirroring UnresolvedFuture in restate-sdk-shared-core):

:first_completed                 → JS Promise.race
:all_succeeded_or_first_failed   → JS Promise.all
:first_succeeded_or_all_failed   → JS Promise.any
:all_completed                   → JS Promise.allSettled

Constant Summary collapse

VALID_VARIANTS =
%i[
  first_completed
  all_succeeded_or_first_failed
  first_succeeded_or_all_failed
  all_completed
].freeze

Instance Method Summary collapse

Constructor Details

#initialize(ctx, variant, children) ⇒ CombinedFuture

Returns a new instance of CombinedFuture.

Raises:

  • (ArgumentError)


138
139
140
141
142
143
144
145
146
147
# File 'lib/restate/durable_future.rb', line 138

def initialize(ctx, variant, children)
  raise ArgumentError, "unknown combinator variant: #{variant}" unless VALID_VARIANTS.include?(variant)

  @ctx = ctx
  @variant = variant
  @children = children
  @resolved = false
  @value = nil
  @error = nil
end

Instance Method Details

#awaitObject

Block until this combinator settles per its variant. Caches results (including failures) across calls.

Raises:

  • (@error)


157
158
159
160
161
162
# File 'lib/restate/durable_future.rb', line 157

def await
  resolve_combined! unless @resolved
  raise @error if @error

  @value
end

#completed?Boolean

Non-blocking introspection. True iff calling .await is guaranteed not to block. Conservative for the variants that allow early-completion on failure (:all_succeeded_or_first_failed, :first_succeeded_or_all_failed) — we report false until every child is settled, because checking failure status of a leaf would require consuming its notification.

Returns:

  • (Boolean)


169
170
171
172
173
174
175
176
177
178
# File 'lib/restate/durable_future.rb', line 169

def completed?
  return true if @resolved

  case @variant
  when :first_completed
    @children.any?(&:completed?)
  else
    @children.all?(&:completed?)
  end
end

#treeObject

Recursive tree representation the native do_await binding consumes. Leaves are integer handles; inner nodes are [variant, [child…]] pairs.



151
152
153
# File 'lib/restate/durable_future.rb', line 151

def tree
  [@variant, @children.map { |c| c.is_a?(CombinedFuture) ? c.tree : c.handle }]
end