载入中...
搜索中...
未找到
StatePatch.cpp
浏览该文件的文档.
47 std::invoke(std::forward<Release>(release), ref).ignore("rollback failed owned state-patch allocation");
51 auto result = eve::script::projectStatusResult(vm, eve::Status::success(eve::StatusCode::Applied));
155bool PatchBatch::set(const std::string& subject, const std::string& key, const std::string& jsonValue) {
162bool PatchBatch::setExpected(const std::string& subject, const std::string& key, const std::string& jsonValue,
181bool PatchBatch::removeExpected(const std::string& subject, const std::string& key, const std::string& expectedJson) {
197eve::Result<PatchBatchHandleRef> Store::newBatch() { return batches_.emplace(std::make_unique<PatchBatch>()); }
203eve::Result<void> Store::releaseBatch(PatchBatchHandleRef reference) { return batches_.erase(reference); }
219 batch->result_.errors.push_back({static_cast<int>(i), operation.subject, operation.key, code, message});
224 if (!batch->result_.errors.empty() && batch->result_.errors.back().operationIndex == static_cast<int>(i))
262 oldSubject == values_.end() ? std::map<std::string, Value>::const_iterator{} : oldSubject->second.find(key);
264 newSubject == staged.end() ? std::map<std::string, Value>::const_iterator{} : newSubject->second.find(key);
268 changes.push_back({subject, key, had ? oldValue->second.json : "", has ? newValue->second.json : "", !has});
273 batch->result_.errors.push_back({-1, {}, {}, "revision_exhausted", "revision or event sequence exhausted"});
386 return eve::Result<void>::failure(eve::Diagnostic::error(eve::DiagnosticCode::ParseError, parseError.empty() ? "invalid state patch snapshot" : parseError,
390 if (!root.isObject()) return eve::Result<void>::failure(eve::Diagnostic::error(eve::DiagnosticCode::ParseError, "snapshot root must be an object",
395 if (root.getInt("version") != 1) return eve::Result<void>::failure(eve::Diagnostic::error(eve::DiagnosticCode::ParseError, "unsupported state patch snapshot version",
398 return eve::Result<void>::failure(eve::Diagnostic::error(eve::DiagnosticCode::ParseError, "snapshot revision must be a decimal string",
401 return eve::Result<void>::failure(eve::Diagnostic::error(eve::DiagnosticCode::ParseError, "snapshot nextSequence must be a non-zero decimal string",
407 return eve::Result<void>::failure(eve::Diagnostic::error(eve::DiagnosticCode::ParseError, "values and dirty must be arrays",
416 !parseU64(item.get("revision"), valueRevision) || valueRevision > restoredRevision || !item.get("value")) {
417 return eve::Result<void>::failure(eve::Diagnostic::error(eve::DiagnosticCode::ParseError, "invalid value at index " + std::to_string(i),
423 return eve::Result<void>::failure(eve::Diagnostic::error(eve::DiagnosticCode::ParseError, "duplicate subject and key",
432 return eve::Result<void>::failure(eve::Diagnostic::error(eve::DiagnosticCode::ParseError, "invalid dirty key at index " + std::to_string(i),
448eve::Result<eve::SnapshotEnvelope> Store::snapshot(const eve::SnapshotHashProvider& hashProvider) const {
451 return eve::makeSnapshotEnvelope("statepatch.store", statePatchSchema(), eve::SchemaVersion(1), instanceId_,
466 auto metadata = eve::validateSnapshotPayloadMetadata(candidateEnvelope.payload, candidateEnvelope.revision,
477 eve::DiagnosticCode::Conflict, "state patch payload revision disagrees with snapshot envelope"));
484eve::Result<std::string> Store::snapshotEnvelopeJson(const eve::SnapshotHashProvider& hashProvider) const {
491eve::Result<void> Store::restoreSnapshotJson(std::string_view json, const eve::SnapshotHashProvider& hashProvider) {
521 if (snapshotJson() != other.snapshotJson() || events_.size() != other.events_.size()) return false;
525 if (left.sequence != right.sequence || left.revision != right.revision || left.subject != right.subject ||
559bool StoreTransactionParticipant::contextMatches(const transaction::TransactionContext& context) const noexcept {
560 return context.transactionId() == transactionId_ && context.correlationId() == correlationId_ &&
564eve::Result<void> StoreTransactionParticipant::lifecycleFailure(std::string_view operation) const {
571eve::Result<void> StoreTransactionParticipant::contextFailure(const transaction::TransactionContext& context) const {
574 eve::DiagnosticCode::Conflict, "transaction context changed between participant lifecycle calls",
578eve::Result<void> StoreTransactionParticipant::prepare(const transaction::TransactionContext& context) {
606eve::Result<void> StoreTransactionParticipant::commit(const transaction::TransactionContext& context) {
618eve::Result<void> StoreTransactionParticipant::rollback(const transaction::TransactionContext& context) {
628eve::Result<void> StoreTransactionParticipant::compensate(const transaction::TransactionContext& context) {
633 eve::DiagnosticCode::Conflict, "state patch store changed before compensation", "statepatch.store"));
641StatePatch::~StatePatch() {
646 eve::cap::removeListener<eve::IStateMutation>(static_cast<eve::IStateMutation*>(adapter.get()));
662 eve::cap::removeListener<eve::IStateQuery>(static_cast<eve::IStateQuery*>(found->second.get()));
663 eve::cap::removeListener<eve::IStateMutation>(static_cast<eve::IStateMutation*>(found->second.get()));
677eve::script::Borrowed<PatchBatch> StatePatch::resolveBatch(StateBatchHandleRef reference) noexcept {
694 eve::DiagnosticCode::StaleHandle, "owning StatePatch store is stale", "store", {}, "statepatch.squirrel"));
733 auto error = table.addClass<PatchError>("PatchError", std::function<PatchError*()>([] { return nullptr; }), false);
741 table.addClass<PatchResult>("PatchResult", std::function<PatchResult*()>([] { return nullptr; }), false);
744 result.addFunc("getRevisionBefore", [](PatchResult* r) { return r ? static_cast<int64_t>(r->revisionBefore) : 0; });
745 result.addFunc("getRevisionAfter", [](PatchResult* r) { return r ? static_cast<int64_t>(r->revisionAfter) : 0; });
746 result.addFunc("errorCount", [](PatchResult* r) { return r ? static_cast<int>(r->errors.size()) : 0; });
748 return r && index >= 0 && static_cast<size_t>(index) < r->errors.size() ? &r->errors[static_cast<size_t>(index)]
753 table.addClass<ChangeEvent>("StateChangeEvent", std::function<ChangeEvent*()>([] { return nullptr; }), false);
754 event.addFunc("getSequence", [](ChangeEvent* e) { return e ? static_cast<int64_t>(e->sequence) : 0; });
755 event.addFunc("getRevision", [](ChangeEvent* e) { return e ? static_cast<int64_t>(e->revision) : 0; });
762 auto batch = table.addClass<PatchBatch>("PatchBatch", std::function<PatchBatch*()>([] { return nullptr; }), false);
770 [](PatchBatch* b) -> PatchResult* { return b ? const_cast<PatchResult*>(&b->result()) : nullptr; });
791 ownedBatch.addFunc("set", [vm](ScriptStateBatch* value, const std::string& subject, const std::string& key,
793 auto view = value ? StatePatch::resolveBatch(value->reference) : eve::script::Borrowed<PatchBatch>();
798 eve::DiagnosticCode::StaleHandle, std::string("owned state-patch ") + "batch" + " handle is stale",
801 return eve::script::projectResult(vm, eve::Result<bool>::success(view->set(subject, key, jsonValue)),
804 ownedBatch.addFunc("remove", [vm](ScriptStateBatch* value, const std::string& subject, const std::string& key) {
805 auto view = value ? StatePatch::resolveBatch(value->reference) : eve::script::Borrowed<PatchBatch>();
810 eve::DiagnosticCode::StaleHandle, std::string("owned state-patch ") + "batch" + " handle is stale",
816 ownedBatch.addFunc("setExpected", [vm](ScriptStateBatch* value, const std::string& subject, const std::string& key,
818 auto view = value ? StatePatch::resolveBatch(value->reference) : eve::script::Borrowed<PatchBatch>();
823 eve::DiagnosticCode::StaleHandle, std::string("owned state-patch ") + "batch" + " handle is stale",
832 auto view = value ? StatePatch::resolveBatch(value->reference) : eve::script::Borrowed<PatchBatch>();
837 eve::DiagnosticCode::StaleHandle, std::string("owned state-patch ") + "batch" + " handle is stale",
845 auto view = value ? StatePatch::resolveBatch(value->reference) : eve::script::Borrowed<PatchBatch>();
849 auto view = value ? StatePatch::resolveBatch(value->reference) : eve::script::Borrowed<PatchBatch>();
853 auto view = value ? StatePatch::resolveBatch(value->reference) : eve::script::Borrowed<PatchBatch>();
857 auto store = table.addClass<Store>("StateStore", std::function<Store*()>([] { return nullptr; }), false);
861 store.addFunc("valueRevision", [](Store* s, const std::string& subject, const std::string& key) {
864 store.addFunc("revision", [](Store* s) { return s ? static_cast<int64_t>(s->revision()) : 0; });
916 ownedStore.addFunc("has", [](ScriptStateStore* value, const std::string& subject, const std::string& key) {
920 ownedStore.addFunc("get", [](ScriptStateStore* value, const std::string& subject, const std::string& key) {
The single Squirrel projection for common Result, Status and Value.
Consumer-owned query and mutation contracts for authoritative world state.
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Human-readable, scoped identifier in the form namespace:name.
Definition Identity.h:411
static std::optional< LogicalId > parse(std::string_view text)
Parses a scoped logical name.
Definition Identity.cpp:36
void ignore(std::string_view reason={}) const noexcept
Explicitly discard this result after documenting the reason.
Definition Result.h:537
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Result< void > add(LogicalId schema, SchemaVersion from, SchemaVersion to, Migration migration)
Register one schema-local migration edge.
Definition Snapshot.cpp:196
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
static Result< Value > fromJson(std::string_view json)
Parse one strict JSON value into an owning Value.
Definition Value.cpp:57
static Document parse(const std::string &text, std::string *error=nullptr)
Parse.
Definition Json.cpp:581
Non-owning C++ observation with no implicit lifetime extension.
Definition RuntimeRegistry.h:42
All-or-nothing mutation boundary owned by the consumer.
Definition StateAccess.h:107
Read-only world-state boundary owned by consumers such as Dialogue.
Definition StateAccess.h:79
Ordered collection of set and remove operations committed atomically.
Definition StatePatch.h:86
bool setExpected(const std::string &subject, const std::string &key, const std::string &jsonValue, const std::string &expectedJson)
Appends a set operation guarded by an expected current JSON value.
Definition StatePatch.cpp:162
bool set(const std::string &subject, const std::string &key, const std::string &jsonValue)
Appends an unconditional set operation.
Definition StatePatch.cpp:155
bool remove(const std::string &subject, const std::string &key)
Appends an unconditional remove operation.
Definition StatePatch.cpp:176
const PatchResult & result() const
Returns the result of the most recent commit attempt.
Definition StatePatch.cpp:195
bool removeExpected(const std::string &subject, const std::string &key, const std::string &expectedJson)
Appends a remove operation guarded by an expected current JSON value.
Definition StatePatch.cpp:181
Script module factory for generic state patch stores.
Definition StatePatch.h:272
static eve::Result< void > releaseBatch(StateBatchHandleRef reference)
Releases a store-qualified patch batch.
Definition StatePatch.cpp:685
static eve::script::Borrowed< PatchBatch > resolveBatch(StateBatchHandleRef reference) noexcept
Resolves a store-qualified batch as a non-owning observation.
Definition StatePatch.cpp:677
static bool isBatchStale(StateBatchHandleRef reference) noexcept
Reports whether a store-qualified batch reference is stale.
Definition StatePatch.cpp:698
static eve::Result< void > release(StateStoreHandleRef reference)
Releases a module-owned state store.
Definition StatePatch.cpp:712
Deterministic subject-and-key JSON value store with atomic patching.
Definition StatePatch.h:119
bool has(const std::string &subject, const std::string &key) const
Returns whether a subject and key currently exist.
Definition StatePatch.cpp:291
bool commit(PatchBatch *batch)
Validates and atomically commits a batch.
Definition StatePatch.cpp:210
eve::Result< void > releaseBatch(PatchBatchHandleRef reference)
Releases a store-owned patch batch.
Definition StatePatch.cpp:203
eve::Result< void > restoreJson(const std::string &json)
Transactionally restores a snapshot produced by snapshotJson().
Definition StatePatch.cpp:382
eve::script::Borrowed< PatchBatch > resolveBatch(PatchBatchHandleRef reference) noexcept
Resolves a live batch as a non-owning observation.
Definition StatePatch.cpp:199
Store(eve::PersistentId instanceId={})
Creates an empty store with an optional persistent identity.
Definition StatePatch.cpp:153
bool isBatchStale(PatchBatchHandleRef reference) const noexcept
Reports whether a batch reference is stale for this Store.
Definition StatePatch.cpp:205
eve::Result< PatchBatchHandleRef > newBatch()
Allocates a store-owned empty patch batch and returns its handle.
Definition StatePatch.cpp:197
Immutable context shared by every participant of one transaction.
Definition Transaction.h:30
@ Borrowed
ssq::Table projectStatusResult(HSQUIRRELVM vm, const Status &status)
Project a checked native status that carries no payload.
Definition SquirrelBinding.cpp:454
ssq::Table projectResult(HSQUIRRELVM vm, Result< void > &&result)
Consume and project a void native Result using the common schema.
Definition SquirrelBinding.cpp:470
Definition StateAccessAdapter.cpp:13
eve::script::RuntimeHandleRef< StateStoreHandleTag > StateStoreHandleRef
Generation- and module-epoch-qualified state store reference.
Definition StatePatch.h:28
@ InvalidArgument
@ PreconditionViolation
@ Failed
@ ParseError
@ StaleHandle
@ Conflict
Result< void > validateSnapshotPayloadMetadata(const Value &payload, Revision revision, SimulationTick tick)
Validate optional payload copies of envelope revision and tick.
Definition Snapshot.cpp:80
@ Pending
@ Applied
@ Rejected
@ Failed
@ Conflict
Result< SnapshotEnvelope > parseSnapshotEnvelope(std::string_view json, const SnapshotHashProvider &hashProvider)
Parse and verify an envelope from canonical or compatible JSON text.
Definition Snapshot.cpp:190
Result< std::string > serializeSnapshotEnvelope(const SnapshotEnvelope &snapshot)
Serialize an envelope as deterministic compact JSON.
Definition Snapshot.cpp:184
Result< SnapshotEnvelope > makeSnapshotEnvelope(std::string type, LogicalId schema, SchemaVersion schemaVersion, PersistentId instanceId, Revision revision, SimulationTick tick, Value payload, const SnapshotHashProvider &hashProvider)
Construct and seal a snapshot envelope.
Definition Snapshot.cpp:103
std::function< Result< ContentId >(std::string_view canonicalInput)> SnapshotHashProvider
Injected content-digest implementation used by snapshots.
Definition Snapshot.h:36
Definition Container.h:602
StatePatch implementation of the common world-state contracts.
Stable outer format shared by persistence and cross-process snapshots.
Definition Snapshot.h:46
Immutable description of one committed value change.
Definition StatePatch.h:75
One validation error produced while applying a patch batch.
Definition StatePatch.h:57
Summary of the most recent batch commit attempt.
Definition StatePatch.h:66
A patch batch reference qualified by both its owning Store and batch slot.
Definition StatePatch.h:41