View on GitHub

stencil

Code Generator based on Model Template binding Transformations

[[TOC]]

Overview

Transactions can be used for the following scenarios, mainly to deal with sparse changes to object models.

  1. Object Model listeners
  2. Generate Events / Send RPC messages with delta changes to Object models
  3. Optimized Record and Replay Object model changes with sparse delta
  4. Logging Object model changes
  5. Suppress / Avoid non-change edits

In general the use-cases involve the following steps

  1. Start Transaction
  2. Make changes to objects and sub-objects
    • Change values
    • Add remove list values
    • Edit sub-structs
  3. End Transaction
  4. Notify listeners with transaction data

with the following characteristics

Dependencies

Use-cases

struct SubStruct
{
    int     val1;
    string  val2;
}

struct ListObject
{
    int val
}

struct Foo
{
    SubStruct        child1;
    list<ListObject> list1;
    int              val3;
}

Generating a transaction

Foo foo;
{
    auto txn = Transaction<Foo>(foo);
    txn.child1().set_val1(1);
    txn.child1().set_val2("newvalue");
    txn.add_list1({val = 1});
    txn.add_list1({val = 2});
    txn.set_val3(2);
}

Dev Notes

Multiple levels of recordings

Features

  1. Recursive (Nesting). For codegen support (structs)
  2. Primitives need to be empty. Struct members tagged via bitmask ( Parent support required )
  3. Editing objects via visitors (serialization/deserialization) support
  4. Detect no-changes for primitive values. (Recursively)
    • Testcase : deserializing twice into same obj should produce empty txn on the second attempt.
    • What to do for lists
  5. Serializing /deserializing into patches via protocol ( json, string, binary)

Proposals: Containers and State

Primitives dont have state for perf reasons Primitives rely on owner to maintain state - This is useful because the bool changed can not be a bitfield in parent. However if we have no state in transaction then the owner needs to provide some context so it understands which child transaction is requesting the callback

[APPROVED] Container: Transaction<T, TContainer>

[Approved] ElementState: Transaction<...>::ElementState

[Testing] ContainerState: Transaction<T, TContainer>::TContainer::ContainerState

[REJECTED] AccessorFn

How to access object from the Transaction

A Transaction doesnt directly have access to the object. Reason: The object could be a managed object and so parents could move pointer around for no apparent reason (containers, vector, unordered_map) So Access to the object is granted by an accessorfn provided by the parent Within a Transaction AccessorFn can be called by providing an Owner object and will provide access to the object Vector/List: AccessorFn is uniform so some obj-state must be provided The AccessorFn will need some identifier to identify the exact object

Pros-Cons

Proposals: Visitors for Transactions

Mutator support

VisitChanges

FAQ