sealed trait RemoteVariableScope extends AnyRef

Describes a remote variable's scope

## Scoping rules

### Workflows A top level workflow defines the top level scope by it's unique flow identifier. This guarantees that:

  • separate workflows cannot see each other's variables
  • restarted workflows see the same set of variables as the previous run as they share the flow id

Operation semantics on the top level of workflows (not in a forked fiber and not in an active transaction):

  • New(name): creates a new remote variable in the KV store's variable namespace called "$$flowid$$name"
  • Get(name): reads"$$flowid$$name"
  • Set(name): writes"$$flowid$$name"

### Fibers Forked workflows are like regular workflows but they are not individually submitted, instead created by the executor by the Fork operator.

Each workflow maintains a fork counter and generates new workflow ids based on that. So a forked workflow's flow identifier will be "$$parentId_fork$$parentForkCounter".

Desired semantics:

  • Forked workflows should have read/write access to variables accessible to the parent workflow
  • Creating new variables in a forked workflow should not be accessible to the parent and sibling workflows
  • Parallel forked workflows should be able to create independent variables with the same name

Operation semantics in forked workflows:

  • New(name): creates a new remote variable in the KV store's variable namespace prefixed by the active workflow identifier "$$flowid$$name" (which is "$$parentId_fork$$parentForkCounter$$name").
  • Get(name): first finds the variable's scope by first looking in the current fiber's scope (using "$$flowid$$name") - if it does not exist, it recursively tries to access the variable in the parent scope ("$$parentid$$name").
  • Set(name): same lookup as for Get - Get and Set must always select the same variable in an executor step

### Transactions

In transactions we have to delay the effect of Set (but within the transaction still see that value in Get) until the transaction is committed. This means that we need to store values for the same remote variable name per transaction beside its original value - which means transactions define their own scope.

Desired semantics:

  • Creating a new variable in a transaction: should not behave differently than in a regular scope
    • transactional variable updates are only interesting if there are multiple fibers running transactions modifying the same variable. This means that even if there are "colliding" new variables in parallel transactions, their parent scope will be different (because fibers are also defining scopes) so they would never collide.
  • Within the transaction, Get and Set should work as usual, but the effect of Set should not be visible for other fibers, even if the changed variable is in a shared scope.
  • When the transaction is committed, the changes are either applied to these shared variables, or the transaction gets reverted.

Flow state contains a transaction counter that can be used as a unique identifier for transaction scopes, similar to how fiber scopes are generated: "parentId_tx$$transactionCounter".

Operation semantics in transaction scopes:

  • New(name): creates a new remote variable in the parent scope
  • Get(name): acts the same way as in forked workflows, but also records the accessed variable's version if necessary
  • Set(name): always sets the value in the transaction scope ($$parentid$$name)
Linear Supertypes
Known Subclasses
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. RemoteVariableScope
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. Protected

Abstract Value Members

  1. abstract val flowId: FlowId
  2. abstract val parentScope: Option[RemoteVariableScope]
  3. abstract def rootScope: TopLevel
  4. abstract val transactionId: Option[TransactionId]

Concrete Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##: Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  5. def clone(): AnyRef
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.CloneNotSupportedException]) @native()
  6. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  7. def equals(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef → Any
  8. def finalize(): Unit
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.Throwable])
  9. final def getClass(): Class[_ <: AnyRef]
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  10. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  11. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  12. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  13. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  14. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  15. final def synchronized[T0](arg0: => T0): T0
    Definition Classes
    AnyRef
  16. def toString(): String
    Definition Classes
    AnyRef → Any
  17. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  18. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  19. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException]) @native()

Inherited from AnyRef

Inherited from Any

Ungrouped