11import type { ReadCommitResult } from 'isomorphic-git' ;
22import type { EncryptedFS } from 'encryptedfs' ;
3+ import type { ContextCancellable } from '@matrixai/contexts' ;
34import type { DB , DBTransaction , LevelPath } from '@matrixai/db' ;
45import type { RPCClient } from '@matrixai/rpc' ;
56import type { ResourceAcquire , ResourceRelease } from '@matrixai/resources' ;
@@ -27,11 +28,12 @@ import {
2728 ready ,
2829} from '@matrixai/async-init/dist/CreateDestroyStartStop' ;
2930import { withF , withG } from '@matrixai/resources' ;
31+ import { context , cancellable } from '@matrixai/contexts/dist/decorators' ;
3032import { RWLockWriter } from '@matrixai/async-locks' ;
33+ import { tagLast } from './types' ;
3134import * as vaultsUtils from './utils' ;
3235import * as vaultsErrors from './errors' ;
3336import * as vaultsEvents from './events' ;
34- import { tagLast } from './types' ;
3537import * as ids from '../ids' ;
3638import * as nodesUtils from '../nodes/utils' ;
3739import * as gitUtils from '../git/utils' ;
@@ -441,13 +443,20 @@ class VaultInternal {
441443 /**
442444 * With context handler for using a vault in a writable context.
443445 */
446+ public async writeF (
447+ f : ( fs : FileSystemWritable ) => Promise < void > ,
448+ ctx ?: Partial < ContextCancellable > ,
449+ tran ?: DBTransaction ,
450+ ) : Promise < void > ;
444451 @ready ( new vaultsErrors . ErrorVaultNotRunning ( ) )
452+ @cancellable ( true )
445453 public async writeF (
446454 f : ( fs : FileSystemWritable ) => Promise < void > ,
455+ @context ctx : ContextCancellable ,
447456 tran ?: DBTransaction ,
448457 ) : Promise < void > {
449458 if ( tran == null ) {
450- return this . db . withTransactionF ( ( tran ) => this . writeF ( f , tran ) ) ;
459+ return this . db . withTransactionF ( ( tran ) => this . writeF ( f , ctx , tran ) ) ;
451460 }
452461
453462 return withF ( [ this . lock . write ( ) ] , async ( ) => {
@@ -475,7 +484,7 @@ class VaultInternal {
475484 try {
476485 await f ( this . efsVault ) ;
477486 // After doing mutation we need to commit the new history
478- await this . createCommit ( ) ;
487+ await this . createCommit ( ctx ) ;
479488 } catch ( e ) {
480489 // Error implies dirty state
481490 await this . cleanWorkingDirectory ( ) ;
@@ -494,15 +503,16 @@ class VaultInternal {
494503 @ready ( new vaultsErrors . ErrorVaultNotRunning ( ) )
495504 public writeG < T , TReturn , TNext > (
496505 g : ( fs : FileSystemWritable ) => AsyncGenerator < T , TReturn , TNext > ,
506+ ctx : ContextCancellable ,
497507 tran ?: DBTransaction ,
498508 ) : AsyncGenerator < T , TReturn , TNext > {
499509 if ( tran == null ) {
500- return this . db . withTransactionG ( ( tran ) => this . writeG ( g , tran ) ) ;
510+ return this . db . withTransactionG ( ( tran ) => this . writeG ( g , ctx , tran ) ) ;
501511 }
502512
503513 const efsVault = this . efsVault ;
504514 const vaultMetadataDbPath = this . vaultMetadataDbPath ;
505- const createCommit = ( ) => this . createCommit ( ) ;
515+ const createCommit = ( ) => this . createCommit ( ctx ) ;
506516 const cleanWorkingDirectory = ( ) => this . cleanWorkingDirectory ( ) ;
507517 return withG ( [ this . lock . write ( ) ] , async function * ( ) {
508518 if (
@@ -559,6 +569,7 @@ class VaultInternal {
559569 */
560570 @ready ( new vaultsErrors . ErrorVaultNotRunning ( ) )
561571 public acquireWrite (
572+ ctx : ContextCancellable ,
562573 tran ?: DBTransaction ,
563574 ) : ResourceAcquire < FileSystemWritable > {
564575 return async ( ) => {
@@ -593,7 +604,7 @@ class VaultInternal {
593604 if ( e == null ) {
594605 try {
595606 // After doing mutation we need to commit the new history
596- await this . createCommit ( ) ;
607+ await this . createCommit ( ctx ) ;
597608 } catch ( e_ ) {
598609 e = e_ ;
599610 // Error implies dirty state
@@ -968,7 +979,7 @@ class VaultInternal {
968979 * and the old history is removed from the old canonical head to the branch point. This is to maintain the strict
969980 * non-branching linear history.
970981 */
971- protected async createCommit ( ) {
982+ protected async createCommit ( ctx : ContextCancellable ) {
972983 // Forced wait for 1 ms to allow difference in mTime between file changes
973984 await utils . sleep ( 1 ) ;
974985 // Checking if commit is appending or branching
@@ -1080,7 +1091,7 @@ class VaultInternal {
10801091 } ) ;
10811092 // We clean old history if a commit was made on previous version
10821093 if ( headRef !== masterRef ) {
1083- await this . garbageCollectGitObjectsLocal ( masterRef , headRef ) ;
1094+ await this . garbageCollectGitObjectsLocal ( masterRef , headRef , ctx ) ;
10841095 }
10851096 }
10861097 }
@@ -1131,7 +1142,13 @@ class VaultInternal {
11311142 * This will walk the current canonicalBranch history and delete any objects that are not a part of it.
11321143 * This is costly since it will compare the walked tree with all existing objects.
11331144 */
1134- protected async garbageCollectGitObjectsGlobal ( ) {
1145+ protected async garbageCollectGitObjectsGlobal (
1146+ ctx ?: Partial < ContextCancellable > ,
1147+ ) : Promise < void > ;
1148+ @cancellable ( true )
1149+ protected async garbageCollectGitObjectsGlobal (
1150+ @context ctx : ContextCancellable ,
1151+ ) {
11351152 const objectIdsAll = await gitUtils . listObjectsAll ( {
11361153 fs : this . efs ,
11371154 gitDir : this . vaultGitDir ,
@@ -1143,13 +1160,16 @@ class VaultInternal {
11431160 gitdir : this . vaultGitDir ,
11441161 ref : vaultsUtils . canonicalBranch ,
11451162 } ) ;
1146- const reachableObjects = await gitUtils . listObjects ( {
1147- efs : this . efs ,
1148- dir : this . vaultDataDir ,
1149- gitDir : this . vaultGitDir ,
1150- wants : [ masterRef ] ,
1151- haves : [ ] ,
1152- } ) ;
1163+ const reachableObjects = await gitUtils . listObjects (
1164+ {
1165+ efs : this . efs ,
1166+ dir : this . vaultDataDir ,
1167+ gitDir : this . vaultGitDir ,
1168+ wants : [ masterRef ] ,
1169+ haves : [ ] ,
1170+ } ,
1171+ ctx ,
1172+ ) ;
11531173 // Walk from head to all reachable objects
11541174 for ( const objectReachable of reachableObjects ) {
11551175 objects . delete ( objectReachable ) ;
@@ -1172,14 +1192,18 @@ class VaultInternal {
11721192 protected async garbageCollectGitObjectsLocal (
11731193 startId : string ,
11741194 stopId : string ,
1195+ ctx : ContextCancellable ,
11751196 ) {
1176- const objects = await gitUtils . listObjects ( {
1177- efs : this . efs ,
1178- dir : this . vaultDataDir ,
1179- gitDir : this . vaultGitDir ,
1180- wants : [ startId ] ,
1181- haves : [ stopId ] ,
1182- } ) ;
1197+ const objects = await gitUtils . listObjects (
1198+ {
1199+ efs : this . efs ,
1200+ dir : this . vaultDataDir ,
1201+ gitDir : this . vaultGitDir ,
1202+ wants : [ startId ] ,
1203+ haves : [ stopId ] ,
1204+ } ,
1205+ ctx ,
1206+ ) ;
11831207 const deletePs : Array < Promise < void > > = [ ] ;
11841208 for ( const objectId of objects ) {
11851209 deletePs . push (
0 commit comments