ores.compute.result

Table of Contents

Bridges the workunit definition and the actual execution on a grid node. Tracks the server-side lifecycle (Inactive/Unsent/InProgress/Done) and the location of output data. The BOINC equivalent of 'result'.

The entity carries no change-reason cache: the grid machinery writes results and there is no human edit flow.

Generator-signature exception: the generator takes only the generation context; a caller that needs a specific workunit links it by member assignment after generation. No parameterized overload or model knob is needed.

result declares no key field, so callers address it by its storage key.

1. Flags

2. Columns

2.1. id

UUID primary key for the result.

2.2. party_id

The party that submitted the batch the result belongs to, copied from the session when the batch is created. NULL for work that predates the party scope.

2.3. workunit_id

FK reference to ores_compute_workunits_tbl.

2.4. host_id

FK reference to ores_compute_hosts_tbl; NULL until the result is dispatched.

boost::uuids::uuid{}

2.5. server_state

State machine: 1=Inactive, 2=Unsent, 4=InProgress, 5=Done.

1

2.6. outcome

Result outcome code: 1=Success, 3=ClientError, 4=NoReply.

0

2.7. output_uri

URI where the wrapper uploaded the zipped output; NULL until completed.

std::string()

2.8. error_message

Human-readable error description from the wrapper; empty on success.

std::string()

2.9. received_at

Timestamp when the output was received by the server pool.

std::chrono::system_clock::time_point{}

2.10. started_at

When a node took the run, by the server's clock at the claim. The claim marks the run InProgress, and this is the time of that mark. The server writes it, so it needs no agreement between the clock of the node and the clock of the server. The epoch means no claim was recorded: a run that predates the column, or one that the server ended without a claim.

std::chrono::system_clock::time_point{}

2.11. duration_ms

How long the engine ran, in milliseconds, by the monotonic clock of the node that ran it. It does not include the download of the input or the upload of the output. Null until the run ends, and for a run whose node did not run the engine or did not report the time. A screen reads null as unknown and never as zero.

3. Foreign keys

3.1. workunit_id

3.2. host_id

Hosts are a deployment-level registry: a node registers itself on first heartbeat under the system tenant, and the fleet is shared, so one node runs work for every tenant. A result is a tenant's row that names the node that ran it, so the soft-FK check admits the row's own tenant or the system tenant. A host row is never a tenant's to own.

4. SQL

4.1. Flags

5. Indexes

The work-queue queries filter by FK and by server state on the current row version, so the composite partial indexes below are the hot paths; the generator owns them from this model.

5.1. workunit_id

5.2. host_id

5.3. server_state

6. C++

6.1. Flags

6.2. Repository

6.3. Domain includes

#include <string>
#include <cstdint>
#include <boost/uuid/uuid.hpp>

6.4. Conventions

6.5. Table display

column header
id ID
workunit_id Workunit ID
host_id Host ID
server_state Server State
outcome Outcome
output_uri Output URI
error_message Error Message
received_at Received At
modified_by Modified By
recorded_at Recorded At

6.6. Custom repository methods

Pagination, the active-count aggregate, and the per-FK list reads come from the standard repository template; the state-filtered read below is the one method beyond it.

6.6.1. Repository declarations

/**
 * @brief Reads the latest version of all results in a given server state.
 */
std::vector<domain::result> read_by_state(context ctx, int server_state);

6.6.2. Repository implementations

std::vector<domain::result> result_repository::read_by_state(context ctx, int server_state) {
    BOOST_LOG_SEV(lg(), debug) << "Reading results by state: " << server_state;
    static constexpr auto max = db_timestamp::max();
    const auto tid = ctx.tenant_id().to_string();
    const auto query = query_builder::read<std::vector<result_entity>> |
                       query_builder::where("tenant_id"_c == tid && "server_state"_c == server_state &&
                             "valid_to"_c == max);

    return query_builder::execute_read_query<result_entity, domain::result>(
        ctx,
        query,
        [](const auto& entities) { return result_mapper::map(entities); },
        lg(),
        "Reading results by state.");
}

6.7. Custom service methods

The work handler dispatches results by server state (Unsent and InProgress); the generated service surface has no state filter, so the forwarding method below is carried as a paste block.

6.7.1. Service declarations

/**
 * @brief Lists results in a given server state, newest first.
 */
std::vector<domain::result> list_by_state(int server_state);

6.7.2. Service implementations

std::vector<domain::result> result_service::list_by_state(int server_state) {
    BOOST_LOG_SEV(lg(), debug) << "Listing results by state: " << server_state;
    return repo_.read_by_state(ctx_, server_state);
}

7. See also

Emacs 29.3 (Org mode 9.6.15)