Skip to content

Commit

Permalink
[PB-1919] feat: override files on .tmp renamed (#476)
Browse files Browse the repository at this point in the history
  • Loading branch information
JoanVicens authored Mar 27, 2024
1 parent f9f753a commit 2f3a28c
Show file tree
Hide file tree
Showing 42 changed files with 494 additions and 93 deletions.
25 changes: 25 additions & 0 deletions src/apps/fuse/AsyncFunctionQueue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export class AsyncFunctionQueue {
private readonly queue = new Map<string, Promise<void>>();

constructor(
private readonly asyncFunction: (...params: any[]) => Promise<void>
) {}

async enqueue(...params: any[]): Promise<void> {
const key = params[0];

if (this.queue.has(key)) {
const promise = this.queue.get(key);
await promise;
}

const added = this.asyncFunction(...params);
this.queue.set(key, added);

try {
await added;
} finally {
this.queue.delete(key);
}
}
}
11 changes: 8 additions & 3 deletions src/apps/fuse/FuseApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,17 @@ export class FuseApp {

private async getOpt() {
const readdir = new ReaddirCallback(
this.fuseContainer.virtualDriveContainer
this.fuseContainer.virtualDriveContainer,
this.fuseContainer.offlineDriveContainer
);
const getattr = new GetAttributesCallback(
this.fuseContainer.virtualDriveContainer,
this.fuseContainer.offlineDriveContainer
);
const open = new OpenCallback(this.fuseContainer.virtualDriveContainer);
const open = new OpenCallback(
this.fuseContainer.virtualDriveContainer,
this.fuseContainer.offlineDriveContainer
);
const read = new ReadCallback(
this.fuseContainer.virtualDriveContainer,
this.fuseContainer.offlineDriveContainer
Expand All @@ -51,7 +55,8 @@ export class FuseApp {
this.fuseContainer.virtualDriveContainer
);
const trashFile = new TrashFileCallback(
this.fuseContainer.virtualDriveContainer
this.fuseContainer.virtualDriveContainer,
this.fuseContainer.offlineDriveContainer
);
const trashFolder = new TrashFolderCallback(
this.fuseContainer.virtualDriveContainer
Expand Down
11 changes: 11 additions & 0 deletions src/apps/fuse/callbacks/AccessCallback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { NotifyFuseCallback } from './FuseCallback';

export class AccessCallback extends NotifyFuseCallback {
constructor() {
super('Access', { input: true, output: true });
}

async execute() {
return this.right();
}
}
11 changes: 11 additions & 0 deletions src/apps/fuse/callbacks/ChownCallback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { NotifyFuseCallback } from './FuseCallback';

export class ChownCallback extends NotifyFuseCallback {
constructor() {
super('Chown', { input: true, output: true });
}

async execute(_path: string, _uid: number, _gid: number) {
return this.right();
}
}
2 changes: 1 addition & 1 deletion src/apps/fuse/callbacks/FuseCallback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export abstract class NotifyFuseCallback extends FuseCallback<undefined> {
}

if (this.debug.output) {
Logger.debug(`${this.name} completed successfully`);
Logger.debug(`${this.name} completed successfully ${params[0]}`);
}

callback(NotifyFuseCallback.OK);
Expand Down
12 changes: 10 additions & 2 deletions src/apps/fuse/callbacks/GetAttributesCallback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import { OfflineDriveDependencyContainer } from '../dependency-injection/offline
import { VirtualDriveDependencyContainer } from '../dependency-injection/virtual-drive/VirtualDriveDependencyContainer';
import { FuseCallback } from './FuseCallback';
import { FuseError, FuseNoSuchFileOrDirectoryError } from './FuseErrors';
import Logger from 'electron-log';

type GetAttributesCallbackData = {
mode: number;
size: number;
mtime: Date;
ctime: Date;
atime?: Date;
uid: number;
gid: number;
};

export class GetAttributesCallback extends FuseCallback<GetAttributesCallbackData> {
Expand All @@ -30,7 +31,6 @@ export class GetAttributesCallback extends FuseCallback<GetAttributesCallbackDat
): Either<FuseError, GetAttributesCallbackData> {
// When the OS wants to check if a node exists will try to get the attributes of it
// so not founding them is not an error
Logger.info(`No attributes found for ${error.path}`);
return left(error);
}

Expand All @@ -42,6 +42,8 @@ export class GetAttributesCallback extends FuseCallback<GetAttributesCallbackDat
mtime: new Date(),
ctime: new Date(),
atime: undefined,
uid: process.getuid(),
gid: process.getgid(),
});
}

Expand All @@ -57,6 +59,8 @@ export class GetAttributesCallback extends FuseCallback<GetAttributesCallbackDat
ctime: file.createdAt,
mtime: file.updatedAt,
atime: new Date(),
uid: process.getuid(),
gid: process.getgid(),
});
}

Expand All @@ -72,6 +76,8 @@ export class GetAttributesCallback extends FuseCallback<GetAttributesCallbackDat
ctime: folder.createdAt,
mtime: folder.updatedAt,
atime: folder.createdAt,
uid: process.getuid(),
gid: process.getgid(),
});
}

Expand All @@ -85,6 +91,8 @@ export class GetAttributesCallback extends FuseCallback<GetAttributesCallbackDat
mtime: new Date(),
ctime: offlineFile.createdAt,
atime: offlineFile.createdAt,
uid: process.getuid(),
gid: process.getgid(),
});
}

Expand Down
18 changes: 13 additions & 5 deletions src/apps/fuse/callbacks/OpenCallback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,31 @@ import { VirtualDriveDependencyContainer } from '../dependency-injection/virtual
import Logger from 'electron-log';
import { FuseCallback } from './FuseCallback';
import { FuseIOError, FuseNoSuchFileOrDirectoryError } from './FuseErrors';
import { OfflineDriveDependencyContainer } from '../dependency-injection/offline/OfflineDriveDependencyContainer';

export class OpenCallback extends FuseCallback<number> {
constructor(private readonly container: VirtualDriveDependencyContainer) {
constructor(
private readonly virtual: VirtualDriveDependencyContainer,
private readonly offline: OfflineDriveDependencyContainer
) {
super('Open');
}

async execute(path: string, _flags: Array<any>) {
const file = await this.container.filesSearcher.run({ path });
const virtual = await this.virtual.filesSearcher.run({ path });

if (!file) {
if (!virtual) {
const offline = await this.offline.offlineFileSearcher.run({ path });
if (offline) {
return this.right(0);
}
return this.left(new FuseNoSuchFileOrDirectoryError(path));
}

try {
await this.container.downloadContentsToPlainFile.run(file);
await this.virtual.downloadContentsToPlainFile.run(virtual);

return this.right(file.id);
return this.right(0);
} catch (err: unknown) {
Logger.error('Error downloading file: ', err);
if (err instanceof Error) {
Expand Down
41 changes: 36 additions & 5 deletions src/apps/fuse/callbacks/ReadCallback.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Logger from 'electron-log';
import { VirtualDriveDependencyContainer } from '../dependency-injection/virtual-drive/VirtualDriveDependencyContainer';
import { OfflineDriveDependencyContainer } from '../dependency-injection/offline/OfflineDriveDependencyContainer';
import { Optional } from '../../../shared/types/Optional';

// eslint-disable-next-line @typescript-eslint/no-var-requires
const fuse = require('@gcas/fuse');
Expand Down Expand Up @@ -33,6 +34,17 @@ export class ReadCallback {
return chunk.length; // number of bytes read
}

private async copyToBuffer(buffer: Buffer, bufferOptional: Optional<Buffer>) {
if (!bufferOptional.isPresent()) {
return 0;
}

const chunk = bufferOptional.get();

chunk.copy(buffer); // write the result of the read to the result buffer
return chunk.length; // number of bytes read
}

async execute(
path: string,
_fd: any,
Expand All @@ -41,23 +53,42 @@ export class ReadCallback {
pos: number,
cb: (code: number, params?: any) => void
) {
const file = await this.virtualDrive.filesSearcher.run({ path });
const virtualFile = await this.virtualDrive.filesSearcher.run({ path });

if (!virtualFile) {
const offlineFile = await this.offlineDrive.offlineFileSearcher.run({
path,
});

if (!offlineFile) {
Logger.error('READ FILE NOT FOUND', path);
cb(fuse.ENOENT);
return;
}

const chunk =
await this.offlineDrive.auxiliarOfflineContentsChucksReader.run(
offlineFile.id,
len,
pos
);

const result = await this.copyToBuffer(buf, chunk);

if (!file) {
cb(fuse.ENOENT);
cb(result);
return;
}

const filePath = this.virtualDrive.relativePathToAbsoluteConverter.run(
file.contentsId
virtualFile.contentsId
);

try {
const bytesRead = await this.read(filePath, buf, len, pos);
cb(bytesRead);
} catch (err) {
Logger.error(`Error reading file: ${err}`);
cb(fuse.ENOENT);
cb(fuse.EIO);
}
}
}
27 changes: 22 additions & 5 deletions src/apps/fuse/callbacks/ReaddirCallback.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,40 @@
import { OfflineDriveDependencyContainer } from '../dependency-injection/offline/OfflineDriveDependencyContainer';
import { VirtualDriveDependencyContainer } from '../dependency-injection/virtual-drive/VirtualDriveDependencyContainer';
import { FuseCallback } from './FuseCallback';

export class ReaddirCallback extends FuseCallback<Array<string>> {
constructor(private readonly container: VirtualDriveDependencyContainer) {
constructor(
private readonly virtual: VirtualDriveDependencyContainer,
private readonly offline: OfflineDriveDependencyContainer
) {
super('Read Directory');
}

async execute(path: string) {
const filesNamesPromise =
this.container.filesByFolderPathNameLister.run(path);
this.virtual.filesByFolderPathNameLister.run(path);

const folderNamesPromise =
this.container.foldersByParentPathLister.run(path);
const folderNamesPromise = this.virtual.foldersByParentPathLister.run(path);

const offlineFiles = await this.offline.offlineFilesByParentPathLister.run(
path
);

const auxiliaryFileName = offlineFiles
.filter((file) => file.isAuxiliary())
.map((file) => file.name);

const [filesNames, foldersNames] = await Promise.all([
filesNamesPromise,
folderNamesPromise,
]);

return this.right(['.', '..', ...filesNames, ...foldersNames]);
return this.right([
'.',
'..',
...filesNames,
...foldersNames,
...auxiliaryFileName,
]);
}
}
55 changes: 35 additions & 20 deletions src/apps/fuse/callbacks/ReleaseCallback.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { OfflineDriveDependencyContainer } from '../dependency-injection/offline/OfflineDriveDependencyContainer';
import { VirtualDriveDependencyContainer } from '../dependency-injection/virtual-drive/VirtualDriveDependencyContainer';
import { NotifyFuseCallback } from './FuseCallback';
import Logger from 'electron-log';
import { FuseIOError } from './FuseErrors';

export class ReleaseCallback extends NotifyFuseCallback {
constructor(
Expand All @@ -11,31 +13,44 @@ export class ReleaseCallback extends NotifyFuseCallback {
}

async execute(path: string, _fd: number) {
const offlineFile = await this.offlineDrive.offlineFileSearcher.run({
path,
});

if (offlineFile) {
await this.offlineDrive.offlineContentsUploader.run(
offlineFile.id,
offlineFile.path
);
return this.right();
}
try {
const offlineFile = await this.offlineDrive.offlineFileSearcher.run({
path,
});

if (offlineFile) {
if (offlineFile.size.value === 0) {
return this.right();
}

if (offlineFile.isAuxiliary()) {
return this.right();
}

await this.offlineDrive.offlineContentsUploader.run(
offlineFile.id,
offlineFile.path
);
return this.right();
}

const virtualFile = await this.virtualDrive.filesSearcher.run({ path });
const virtualFile = await this.virtualDrive.filesSearcher.run({ path });

if (virtualFile) {
const contentsPath =
this.virtualDrive.relativePathToAbsoluteConverter.run(
virtualFile.contentsId
);
if (virtualFile) {
const contentsPath =
this.virtualDrive.relativePathToAbsoluteConverter.run(
virtualFile.contentsId
);

await this.offlineDrive.offlineContentsCacheCleaner.run(contentsPath);

await this.offlineDrive.offlineContentsCacheCleaner.run(contentsPath);
return this.right();
}

return this.right();
} catch (err: unknown) {
Logger.error('RELEASE', err);
return this.left(new FuseIOError());
}

return this.right();
}
}
Loading

0 comments on commit 2f3a28c

Please sign in to comment.