Skip to content

Commit 803c7bd

Browse files
committed
feat: added vault efs resource aquisition
1 parent f771659 commit 803c7bd

File tree

2 files changed

+88
-1
lines changed

2 files changed

+88
-1
lines changed

src/vaults/Vault.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ interface Vault {
88
writeG: VaultInternal['writeG'];
99
readF: VaultInternal['readF'];
1010
readG: VaultInternal['readG'];
11+
acquireRead: VaultInternal['acquireRead'];
12+
acquireWrite: VaultInternal['acquireWrite'];
1113
log: VaultInternal['log'];
1214
version: VaultInternal['version'];
1315
}

src/vaults/VaultInternal.ts

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ import {
2525
CreateDestroyStartStop,
2626
ready,
2727
} from '@matrixai/async-init/dist/CreateDestroyStartStop';
28-
import { withF, withG } from '@matrixai/resources';
28+
import {
29+
ResourceAcquire,
30+
ResourceRelease,
31+
withF,
32+
withG,
33+
} from '@matrixai/resources';
2934
import { RWLockWriter } from '@matrixai/async-locks';
3035
import * as vaultsUtils from './utils';
3136
import * as vaultsErrors from './errors';
@@ -536,6 +541,86 @@ class VaultInternal {
536541
});
537542
}
538543

544+
/**
545+
* Acquire a read-only lock on this vault
546+
*/
547+
@ready(new vaultsErrors.ErrorVaultNotRunning())
548+
public acquireRead(): ResourceAcquire<FileSystemReadable> {
549+
return async () => {
550+
const acquire = this.lock.read();
551+
const [release] = await acquire();
552+
return [
553+
async (e?: Error) => {
554+
release(e);
555+
},
556+
this.efsVault,
557+
];
558+
};
559+
}
560+
561+
/**
562+
* Acquire a read-write lock on this vault
563+
*/
564+
@ready(new vaultsErrors.ErrorVaultNotRunning())
565+
public acquireWrite(
566+
tran?: DBTransaction,
567+
): ResourceAcquire<FileSystemWritable> {
568+
return async () => {
569+
let releaseTran: ResourceRelease | undefined = undefined;
570+
const acquire = this.lock.write();
571+
const [release] = await acquire([tran]);
572+
if (tran == null) {
573+
const acquireTran = this.db.transaction();
574+
[releaseTran, tran] = await acquireTran();
575+
}
576+
// The returned transaction can be undefined, too. We won't handle those
577+
// cases.
578+
if (tran == null) utils.never();
579+
await tran.lock(
580+
[...this.vaultMetadataDbPath, VaultInternal.dirtyKey].join(''),
581+
);
582+
if (
583+
(await tran.get([
584+
...this.vaultMetadataDbPath,
585+
VaultInternal.remoteKey,
586+
])) != null
587+
) {
588+
// Mirrored vaults are immutable
589+
throw new vaultsErrors.ErrorVaultRemoteDefined();
590+
}
591+
await tran.put(
592+
[...this.vaultMetadataDbPath, VaultInternal.dirtyKey],
593+
true,
594+
);
595+
return [
596+
async (e?: Error) => {
597+
if (e != null) {
598+
try {
599+
// After doing mutation we need to commit the new history
600+
await this.createCommit();
601+
} catch (e_) {
602+
e = e_;
603+
}
604+
// This would happen if an error was caught inside the catch block
605+
if (e != null) {
606+
// Error implies dirty state
607+
await this.cleanWorkingDirectory();
608+
}
609+
}
610+
// For some reason, the transaction type doesn't properly waterfall
611+
// down to here.
612+
await tran!.put(
613+
[...this.vaultMetadataDbPath, VaultInternal.dirtyKey],
614+
false,
615+
);
616+
if (releaseTran != null) releaseTran(e);
617+
release(e);
618+
},
619+
this.efsVault,
620+
];
621+
};
622+
}
623+
539624
/**
540625
* Pulls changes to a vault from the vault's default remote.
541626
* If `pullNodeId` and `pullVaultNameOrId` it uses that for the remote instead.

0 commit comments

Comments
 (0)