# Deferred Execution

Consider the following example contracts. They demonstrate another key feature called [**deferred execution**](https://doc.arcology.network/parallel-execution-design/scheduler#deferred-transaction)**,** where the [**scheduler** ](https://doc.arcology.network/parallel-execution-design/scheduler)moves transactions to the next [**generation** ](https://doc.arcology.network/parallel-execution-design/scheduler#generation)to create a custom aggregation point after parallel execution.

#### Example1

`VisitCounterWithDeferred` uses `U256Cumulative` for parallel-safe increments and adds a **deferred join** step: all `visit()` calls in a generation run in parallel, with **one promoted to** **the next generation** to emit the aggregated result after the generation boundary.

```solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0;

import "@arcologynetwork/concurrentlib/lib/commutative/U256Cum.sol"; 
import "@arcologynetwork/concurrentlib/lib/runtime/Runtime.sol"; 

// This counter supports commutative updates, allowing safe aggregation
// of increments from multiple transactions in parallel.
contract VisitCounterWithDeferred { 
    // A cumulative counter instance that allows concurrent increments
    // from multiple transactions without conflicts.   
    U256Cumulative totalVisit; 
    
    event CounterQuery(uint256 value);

    constructor()  {
        // Initialize the cumulative counter with a starting value of 0
        // and an upper limit of 1,000,000. Any attempt to exceed the
        // range will cause the transaction to revert.
        totalVisit = new U256Cumulative(0, 1000000);

        // Inform the scheduler when there are multiple transaction 
        // calling visit(), one of them will be executed in the
        // deferred transaction. Each call to visit() is charged an 
        // extra 2,000 gas to fund the deferred join step run later
        // in the block. If the deferred transaction fails, 
        // the unused gas is refunded.
        Runtime.defer("visit()", 2000);
    }

    // Increments the visit counter by 1.
    // Multiple invocations in the same generation can be executed in parallel
    // and will be merged deterministically by Arcology at commit time.
    function visit() public {
        // The line below adds 1 to the visit counter, which will executed anyway.
        totalVisit.add(1);

        // If the transaction is in a deferred generation, emit the counter value.
        // The code is executed in the deferred transaction only.
        if (Runtime.isInDeferred()) {
            emit CounterQuery(totalVisit.get());
        }
    }
}
```

#### Example 2

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "@arcologynetwork/concurrentlib/lib/array/Address.sol"; 
import "@arcologynetwork/concurrentlib/lib/runtime/Runtime.sol"; 

// SUPER SIMPLE educational lottery — not secure for real funds.
// join(): send ≥0.005 ETH to join the round.
contract EduLottery {
    Address private _players = new Address(false);

    error InsufficientFee(uint256 sent, uint256 required);
    error NoPlayers();

    constructor() {
        // Inform the scheduler that when there are multiple invocations, move one of 
        // them to the next generation for aggregation. All the senders need to pay
        // extra gas fees of 20,000 wei for the deferred execution.
        Runtime.defer("join()", 20000);
    }

    // Joins the lottery by sending ETH. This function can be called in parallel 
    // by multiple users.
    function join() external payable {
        if (msg.value < 0.005 ether) revert InsufficientFee(msg.value, 0.005 ether);
        _players.push(msg.sender);

        // Only draw if this is the deferred transaction
        if (Runtime.isInDeferred()) {
            _draw();
        }
    }

    // Generates a pseudo-random seed.
    function _randomSeed() private view returns (uint256) {
        // Educational pseudo-randomness (prev blockhash, timestamp, contract)
        return uint256(
            keccak256(
                abi.encodePacked(
                    blockhash(block.number - 1),
                    block.timestamp,
                    address(this)
                )
            )
        );
    }

    // Draws a random winner from the players.
    function _draw() internal {
        require(Runtime.isInDeferred(), "only deferred");

        if (_players.fullLength() == 0) revert NoPlayers();
        uint256 idx = _randomSeed() % _players.fullLength();
        address winner = _players.get(idx);

        _players.clear(); // Clear players for the next round
        uint256 prize = address(this).balance;
        (bool ok, ) = payable(winner).call{value: prize}("");
        require(ok, "transfer failed");
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.arcology.network/arcology-concurrent-programming-guide/utility/deferred-execution.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
