Class: Concurrent::Promises::ResolvableFuture — Concurrent Ruby

# Class: Concurrent::Promises::ResolvableFuture

Inherits:
  Future
  - Object
  - Synchronization::Object
  - AbstractEventFuture
  - Future
  - Concurrent::Promises::ResolvableFuture
  show all

Includes:
  Resolvable

Defined in:
  lib/concurrent/promises.rb

## Overview

A Future which can be resolved by user.

## Instance Method Summary collapse

- #evaluate_to(*args) {|*args| ... } ⇒ self

  Evaluates the block and sets its result as future's value fulfilling, if the block raises an exception the future rejects with it.

- #evaluate_to!(*args) {|*args| ... } ⇒ self

  Evaluates the block and sets its result as future's value fulfilling, if the block raises an exception the future rejects with it.

- #fulfill(value, raise_on_reassign = true, reserved = false) ⇒ self, false

  Makes the future fulfilled with `value`, which triggers all dependent futures.

- #reason(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) ⇒ Exception, timeout_value, nil

  Behaves as Future#reason but has one additional optional argument resolve_on_timeout.

- #reject(reason, raise_on_reassign = true, reserved = false) ⇒ self, false

  Makes the future rejected with `reason`, which triggers all dependent futures.

- #resolve(fulfilled = true, value = nil, reason = nil, raise_on_reassign = true, reserved = false) ⇒ self, false

  Makes the future resolved with result of triplet `fulfilled?`, `value`, `reason`, which triggers all dependent futures.

- #result(timeout = nil, resolve_on_timeout = nil) ⇒ ::Array(Boolean, Object, Exception), nil

  Behaves as Future#result but has one additional optional argument resolve_on_timeout.

- #value(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) ⇒ Object, timeout_value, nil

  Behaves as Future#value but has one additional optional argument resolve_on_timeout.

- #value!(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) ⇒ Object, timeout_value, nil

  Behaves as Future#value! but has one additional optional argument resolve_on_timeout.

- #wait(timeout = nil, resolve_on_timeout = nil) ⇒ self, true, false

  Behaves as AbstractEventFuture#wait but has one additional optional argument resolve_on_timeout.

- #wait!(timeout = nil, resolve_on_timeout = nil) ⇒ self, true, false

  Behaves as Future#wait! but has one additional optional argument resolve_on_timeout.

- #with_hidden_resolvable ⇒ Future

  Creates new future wrapping receiver, effectively hiding the resolve method and similar.

- #release ⇒ true, false included from Resolvable

  On successful release of the reservation.

- #reserve ⇒ true, false included from Resolvable

  Reserves the event or future, if reserved others are prevented from resolving it.

## Instance Method Details

### #evaluate_to(*args) {|*args| ... } ⇒ `self`

Evaluates the block and sets its result as future's value fulfilling, if the block raises an exception the future rejects with it.

Yields:

- (`*args`) —

  to the block.

Yield Returns:

- (`Object`) —

  value

Returns:

- (`self`)

    1384
    1385
    1386
    # File 'lib/concurrent/promises.rb', line 1384

    def evaluate_to(*args, &block)
      promise.evaluate_to(*args, block)
    end

### #evaluate_to!(*args) {|*args| ... } ⇒ `self`

Evaluates the block and sets its result as future's value fulfilling, if the block raises an exception the future rejects with it.

Yields:

- (`*args`) —

  to the block.

Yield Returns:

- (`Object`) —

  value

Returns:

- (`self`)

Raises:

- (`Exception`) —

  also raise reason on rejection.

    1395
    1396
    1397
    # File 'lib/concurrent/promises.rb', line 1395

    def evaluate_to!(*args, &block)
      promise.evaluate_to(*args, block).wait!
    end

### #fulfill(value, raise_on_reassign = true, reserved = false) ⇒ `self`, `false`

Makes the future fulfilled with `value`, which triggers all dependent futures.

Parameters:

- value (`Object`)
- raise_on_reassign (`Boolean`) (defaults to: `true`) —

  should method raise exception if already resolved

- reserved (`true`, `false`) (defaults to: `false`) —

  Set to true if the resolvable is Concurrent::Promises::Resolvable#reserved by you, marks resolution of reserved resolvable events and futures explicitly. Advanced feature, ignore unless you use Concurrent::Promises::Resolvable#reserve from edge.

Returns:

- (`self`, `false`) —

  false is returner when raise_on_reassign is false and the receiver is already resolved.

    1364
    1365
    1366
    # File 'lib/concurrent/promises.rb', line 1364

    def fulfill(value, raise_on_reassign = true, reserved = false)
      resolve_with Fulfilled.new(value), raise_on_reassign, reserved
    end

### #reason(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) ⇒ `Exception`, `timeout_value`, `nil`

Behaves as Future#reason but has one additional optional argument resolve_on_timeout.

Parameters:

- resolve_on_timeout (`::Array(true, Object, nil)`, `::Array(false, nil, Exception)`, `nil`) (defaults to: `nil`) —

  If it times out and the argument is not nil it will also resolve the future to the provided resolution.

Returns:

- (`Exception`, `timeout_value`, `nil`)

See Also:

- Future#reason

    1492
    1493
    1494
    1495
    1496
    1497
    1498
    1499
    1500
    1501
    1502
    1503
    1504
    1505
    # File 'lib/concurrent/promises.rb', line 1492

    def reason(timeout = nil, timeout_value = nil, resolve_on_timeout = nil)
      if wait_until_resolved timeout
        internal_state.reason
      else
        if resolve_on_timeout
          unless resolve(*resolve_on_timeout, false)
            # if it fails to resolve it was resolved in the meantime
            # so return value as if there was no timeout
            return internal_state.reason
          end
        end
        timeout_value
      end
    end

### #reject(reason, raise_on_reassign = true, reserved = false) ⇒ `self`, `false`

Makes the future rejected with `reason`, which triggers all dependent futures.

Parameters:

- reason (`Object`)
- raise_on_reassign (`Boolean`) (defaults to: `true`) —

  should method raise exception if already resolved

- reserved (`true`, `false`) (defaults to: `false`) —

  Set to true if the resolvable is Concurrent::Promises::Resolvable#reserved by you, marks resolution of reserved resolvable events and futures explicitly. Advanced feature, ignore unless you use Concurrent::Promises::Resolvable#reserve from edge.

Returns:

- (`self`, `false`) —

  false is returner when raise_on_reassign is false and the receiver is already resolved.

    1374
    1375
    1376
    # File 'lib/concurrent/promises.rb', line 1374

    def reject(reason, raise_on_reassign = true, reserved = false)
      resolve_with Rejected.new(reason), raise_on_reassign, reserved
    end

### #resolve(fulfilled = true, value = nil, reason = nil, raise_on_reassign = true, reserved = false) ⇒ `self`, `false`

Makes the future resolved with result of triplet `fulfilled?`, `value`, `reason`, which triggers all dependent futures.

Parameters:

- fulfilled (`true`, `false`) (defaults to: `true`)
- value (`Object`) (defaults to: `nil`)
- reason (`Object`) (defaults to: `nil`)
- raise_on_reassign (`Boolean`) (defaults to: `true`) —

  should method raise exception if already resolved

- reserved (`true`, `false`) (defaults to: `false`) —

  Set to true if the resolvable is Concurrent::Promises::Resolvable#reserved by you, marks resolution of reserved resolvable events and futures explicitly. Advanced feature, ignore unless you use Concurrent::Promises::Resolvable#reserve from edge.

Returns:

- (`self`, `false`) —

  false is returner when raise_on_reassign is false and the receiver is already resolved.

    1354
    1355
    1356
    # File 'lib/concurrent/promises.rb', line 1354

    def resolve(fulfilled = true, value = nil, reason = nil, raise_on_reassign = true, reserved = false)
      resolve_with(fulfilled ? Fulfilled.new(value) : Rejected.new(reason), raise_on_reassign, reserved)
    end

### #result(timeout = nil, resolve_on_timeout = nil) ⇒ `::Array(Boolean, Object, Exception)`, `nil`

Behaves as Future#result but has one additional optional argument resolve_on_timeout.

Parameters:

- resolve_on_timeout (`::Array(true, Object, nil)`, `::Array(false, nil, Exception)`, `nil`) (defaults to: `nil`) —

  If it times out and the argument is not nil it will also resolve the future to the provided resolution.

Returns:

- (`::Array(Boolean, Object, Exception)`, `nil`)

See Also:

- Future#result

    1513
    1514
    1515
    1516
    1517
    1518
    1519
    1520
    1521
    1522
    1523
    1524
    1525
    1526
    # File 'lib/concurrent/promises.rb', line 1513

    def result(timeout = nil, resolve_on_timeout = nil)
      if wait_until_resolved timeout
        internal_state.result
      else
        if resolve_on_timeout
          unless resolve(*resolve_on_timeout, false)
            # if it fails to resolve it was resolved in the meantime
            # so return value as if there was no timeout
            internal_state.result
          end
        end
        # otherwise returns nil
      end
    end

### #value(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) ⇒ `Object`, `timeout_value`, `nil`

Behaves as Future#value but has one additional optional argument resolve_on_timeout.

Parameters:

- resolve_on_timeout (`::Array(true, Object, nil)`, `::Array(false, nil, Exception)`, `nil`) (defaults to: `nil`) —

  If it times out and the argument is not nil it will also resolve the future to the provided resolution.

Returns:

- (`Object`, `timeout_value`, `nil`)

See Also:

- Future#value

    1448
    1449
    1450
    1451
    1452
    1453
    1454
    1455
    1456
    1457
    1458
    1459
    1460
    1461
    # File 'lib/concurrent/promises.rb', line 1448

    def value(timeout = nil, timeout_value = nil, resolve_on_timeout = nil)
      if wait_until_resolved timeout
        internal_state.value
      else
        if resolve_on_timeout
          unless resolve(*resolve_on_timeout, false)
            # if it fails to resolve it was resolved in the meantime
            # so return value as if there was no timeout
            return internal_state.value
          end
        end
        timeout_value
      end
    end

### #value!(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) ⇒ `Object`, `timeout_value`, `nil`

Behaves as Future#value! but has one additional optional argument resolve_on_timeout.

Parameters:

- resolve_on_timeout (`::Array(true, Object, nil)`, `::Array(false, nil, Exception)`, `nil`) (defaults to: `nil`) —

  If it times out and the argument is not nil it will also resolve the future to the provided resolution.

Returns:

- (`Object`, `timeout_value`, `nil`)

Raises:

- (`Exception`) —

  #reason on rejection

See Also:

- Future#value!

    1470
    1471
    1472
    1473
    1474
    1475
    1476
    1477
    1478
    1479
    1480
    1481
    1482
    1483
    1484
    # File 'lib/concurrent/promises.rb', line 1470

    def value!(timeout = nil, timeout_value = nil, resolve_on_timeout = nil)
      if wait_until_resolved! timeout
        internal_state.value
      else
        if resolve_on_timeout
          unless resolve(*resolve_on_timeout, false)
            # if it fails to resolve it was resolved in the meantime
            # so return value as if there was no timeout
            raise self if rejected?
            return internal_state.value
          end
        end
        timeout_value
      end
    end

### #wait(timeout = nil, resolve_on_timeout = nil) ⇒ `self`, `true`, `false`

Behaves as AbstractEventFuture#wait but has one additional optional argument resolve_on_timeout.

Parameters:

- resolve_on_timeout (`::Array(true, Object, nil)`, `::Array(false, nil, Exception)`, `nil`) (defaults to: `nil`) —

  If it times out and the argument is not nil it will also resolve the future to the provided resolution.

Returns:

- (`self`, `true`, `false`)

See Also:

- AbstractEventFuture#wait

    1410
    1411
    1412
    1413
    1414
    1415
    1416
    1417
    1418
    # File 'lib/concurrent/promises.rb', line 1410

    def wait(timeout = nil, resolve_on_timeout = nil)
      super(timeout) or if resolve_on_timeout
                          # if it fails to resolve it was resolved in the meantime
                          # so return true as if there was no timeout
                          !resolve(*resolve_on_timeout, false)
                        else
                          false
                        end
    end

### #wait!(timeout = nil, resolve_on_timeout = nil) ⇒ `self`, `true`, `false`

Behaves as Future#wait! but has one additional optional argument resolve_on_timeout.

Parameters:

- resolve_on_timeout (`::Array(true, Object, nil)`, `::Array(false, nil, Exception)`, `nil`) (defaults to: `nil`) —

  If it times out and the argument is not nil it will also resolve the future to the provided resolution.

Returns:

- (`self`, `true`, `false`)

Raises:

- (`Exception`) —

  #reason on rejection

See Also:

- Future#wait!

    1427
    1428
    1429
    1430
    1431
    1432
    1433
    1434
    1435
    1436
    1437
    1438
    1439
    1440
    # File 'lib/concurrent/promises.rb', line 1427

    def wait!(timeout = nil, resolve_on_timeout = nil)
      super(timeout) or if resolve_on_timeout
                          if resolve(*resolve_on_timeout, false)
                            false
                          else
                            # if it fails to resolve it was resolved in the meantime
                            # so return true as if there was no timeout
                            raise self if rejected?
                            true
                          end
                        else
                          false
                        end
    end

### #with_hidden_resolvable ⇒ `Future`

Creates new future wrapping receiver, effectively hiding the resolve method and similar.

Returns:

- (`Future`)

    1531
    1532
    1533
    # File 'lib/concurrent/promises.rb', line 1531

    def with_hidden_resolvable
      @with_hidden_resolvable ||= FutureWrapperPromise.new_blocked_by1(self, @DefaultExecutor).future
    end

### #release ⇒ `true`, `false` Originally defined in module Resolvable

Returns on successful release of the reservation

Returns:

- (`true`, `false`) —

  on successful release of the reservation

### #reserve ⇒ `true`, `false` Originally defined in module Resolvable

Reserves the event or future, if reserved others are prevented from resolving it. Advanced feature. Be careful about the order of reservation to avoid deadlocks, the method blocks if the future or event is already reserved until it is released or resolved.

Examples:

    f = Concurrent::Promises.resolvable_future
    reserved = f.reserve
    Thread.new { f.resolve true, :val, nil } # fails
    f.resolve true, :val, nil, true if reserved # must be called only if reserved

Returns:

- (`true`, `false`) —

  on successful reservation