Skip to content

Commit

Permalink
Expanded error details if/when a transaction fails to renew, #164
Browse files Browse the repository at this point in the history
  • Loading branch information
kriszyp committed Apr 27, 2022
1 parent 68564ad commit 8d4e047
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 10 deletions.
21 changes: 17 additions & 4 deletions dependencies/lmdb/libraries/liblmdb/mdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -3438,14 +3438,26 @@ mdb_txn_renew(MDB_txn *txn)
{
int rc;

if (!txn || !F_ISSET(txn->mt_flags, MDB_TXN_RDONLY|MDB_TXN_FINISHED))
if (!txn || !F_ISSET(txn->mt_flags, MDB_TXN_RDONLY|MDB_TXN_FINISHED)) {
if (!txn)
last_error = "No transaction to renew";
else if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) {
// Txn is already renewed, we can just keep using it
return MDB_SUCCESS;
} else {
last_error = malloc(100);
sprintf(last_error, "Transaction flag was invalid for renew: %u", txn->mt_flags);
}
return EINVAL;
}

rc = mdb_txn_renew0(txn);
if (rc == MDB_SUCCESS) {
DPRINTF(("renew txn %"Yu"%c %p on mdbenv %p, root page %"Yu,
txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w',
(void *)txn, (void *)txn->mt_env, txn->mt_dbs[MAIN_DBI].md_root));
} else {
last_error = mdb_strerror(rc);
}
return rc;
}
Expand Down Expand Up @@ -7755,9 +7767,10 @@ mdb_get(MDB_txn *txn, MDB_dbi dbi,
last_error = "No key was provided";
else if (!data)
last_error = "No data was provided";
else if (!txn)
last_error = "No transaction available";
else if ((dbi)>=(txn)->mt_numdbs) {
else if (!txn) {
if (!last_error)
last_error = "No transaction available";
} else if ((dbi)>=(txn)->mt_numdbs) {
last_error = malloc(100);
sprintf(last_error, "The dbi %u was out of range for the number of dbis (%u)", dbi, (txn)->mt_numdbs);
} else {
Expand Down
2 changes: 2 additions & 0 deletions read.js
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,8 @@ export function addReadMethods(LMDBStore, {
}
} while (retries++ < 100);
}
// we actually don't renew here, we let the renew take place in the next
// lmdb native read/call so as to avoid an extra native call
readTxnRenewed = setTimeout(resetReadTxn, 0);
store.emit('begin-transaction');
return readTxn;
Expand Down
10 changes: 8 additions & 2 deletions src/cursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,14 @@ int32_t CursorWrap::doPosition(uint32_t offset, uint32_t keySize, uint64_t endKe
//char* keyBuffer = dw->ew->keyBuffer;
MDB_val key, data;
int rc;
if (flags & 0x2000) // TODO: check the txn_id to determine if we need to renew
mdb_cursor_renew(txn = dw->ew->getReadTxn(), cursor);
if (flags & 0x2000) { // TODO: check the txn_id to determine if we need to renew
rc = mdb_cursor_renew(txn = dw->ew->getReadTxn(), cursor);
if (rc) {
if (rc > 0)
rc = -rc;
return rc;
}
}
if (endKeyAddress) {
uint32_t* keyBuffer = (uint32_t*) endKeyAddress;
endKey.mv_size = *keyBuffer;
Expand Down
2 changes: 1 addition & 1 deletion src/dbi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ int DbiWrap::open(int flags, char* name, bool hasVersions, LmdbKeyType keyType,
this->keyType = keyType;
this->flags = flags;
flags &= ~HAS_VERSIONS;
int rc = mdb_dbi_open(txn, name, flags, &this->dbi);
int rc = txn ? mdb_dbi_open(txn, name, flags, &this->dbi) : EINVAL;
if (rc)
return rc;
this->isOpen = true;
Expand Down
7 changes: 4 additions & 3 deletions src/env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,10 @@ MDB_txn* EnvWrap::getReadTxn() {
txn = currentReadTxn;
if (readTxnRenewed)
return txn;
if (txn)
mdb_txn_renew(txn);
else {
if (txn) {
if (mdb_txn_renew(txn))
return nullptr; // if there was an error, signal with nullptr and let error propagate with last_error
} else {
fprintf(stderr, "No current read transaction available");
return nullptr;
}
Expand Down

0 comments on commit 8d4e047

Please sign in to comment.