Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Exception Handling to File Name for Telemetry Caching #1267

Merged
merged 9 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 30 additions & 15 deletions Library/FileSystemHelper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as fs from "fs";
import path = require("path");
import { promisify } from "util";
import Logging = require("./Logging");

export const statAsync = promisify(fs.stat);
export const lstatAsync = promisify(fs.lstat);
Expand Down Expand Up @@ -39,38 +40,52 @@ export const confirmDirExists = async (directory: string): Promise<void> => {
* Computes the size (in bytes) of all files in a directory at the root level. Asynchronously.
*/
export const getShallowDirectorySize = async (directory: string): Promise<number> => {
// Get the directory listing
const files = await readdirAsync(directory);
let totalSize = 0;
// Query all file sizes
for (const file of files) {
const fileStats = await statAsync(path.join(directory, file));
if (fileStats.isFile()) {
totalSize += fileStats.size;
try {
// Get the directory listing
const files = await readdirAsync(directory);
// Query all file sizes
for (const file of files) {
const fileStats = await statAsync(path.join(directory, file));
if (fileStats.isFile()) {
totalSize += fileStats.size;
}
}
return totalSize;
} catch {
Logging.warn(`Failed to get directory size for ${directory}`);
return totalSize;
}
return totalSize;
JacksonWeber marked this conversation as resolved.
Show resolved Hide resolved
};

/**
* Computes the size (in bytes) of all files in a directory at the root level. Synchronously.
*/
export const getShallowDirectorySizeSync = (directory: string): number => {
let files = fs.readdirSync(directory);
let totalSize = 0;
for (let i = 0; i < files.length; i++) {
totalSize += fs.statSync(path.join(directory, files[i])).size;
try {
let files = fs.readdirSync(directory);
for (let i = 0; i < files.length; i++) {
totalSize += fs.statSync(path.join(directory, files[i])).size;
}
return totalSize;
} catch {
Logging.warn(`Failed to get directory size synchronously for ${directory}`)
return totalSize;
}
return totalSize;
JacksonWeber marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Computes the size (in bytes) of a file asynchronously.
*/
export const getShallowFileSize = async (filePath: string): Promise<number> => {
const fileStats = await statAsync(filePath);
if (fileStats.isFile()) {
return fileStats.size;
try {
const fileStats = await statAsync(filePath);
if (fileStats.isFile()) {
return fileStats.size;
}
} catch {
Logging.warn(`Failed to get file size for ${filePath}`);
}
JacksonWeber marked this conversation as resolved.
Show resolved Hide resolved
}

11 changes: 6 additions & 5 deletions Library/Sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Sender {
private _fileCleanupTimer: NodeJS.Timer;
private _redirectedHost: string = null;
private _tempDir: string;
private _processId: number = process.pid;
private _requestTimedOut: boolean;
protected _resendInterval: number;
protected _maxBytesOnDisk: number;
Expand Down Expand Up @@ -428,7 +429,7 @@ class Sender {
try {
//create file - file name for now is the timestamp, a better approach would be a UUID but that
//would require an external dependency
var fileName = new Date().getTime() + ".ai.json";
var fileName = `${new Date().getTime()}.${this._processId}.ai.json`;
JacksonWeber marked this conversation as resolved.
Show resolved Hide resolved
var fileFullPath = path.join(this._tempDir, fileName);

// Mode 600 is w/r for creator and no read access for others (only applies on *nix)
Expand Down Expand Up @@ -465,7 +466,7 @@ class Sender {

//create file - file name for now is the timestamp, a better approach would be a UUID but that
//would require an external dependency
var fileName = new Date().getTime() + ".ai.json";
var fileName = `${new Date().getTime()}.${this._processId}.ai.json`;
var fileFullPath = path.join(this._tempDir, fileName);

// Mode 600 is w/r for creator and no access for anyone else (only applies on *nix)
Expand All @@ -485,7 +486,7 @@ class Sender {
private async _sendFirstFileOnDisk(): Promise<void> {
try {
let files = await FileSystemHelper.readdirAsync(this._tempDir);
files = files.filter(f => path.basename(f).indexOf(".ai.json") > -1);
files = files.filter(f => path.basename(f).indexOf(`${process.pid}.ai.json`) > -1);
if (files.length > 0) {
var firstFile = files[0];
var filePath = path.join(this._tempDir, firstFile);
Expand All @@ -510,11 +511,11 @@ class Sender {
private async _fileCleanupTask(): Promise<void> {
try {
let files = await FileSystemHelper.readdirAsync(this._tempDir);
files = files.filter(f => path.basename(f).indexOf(".ai.json") > -1);
files = files.filter(f => path.basename(f).indexOf(`${this._processId}.ai.json`) > -1);
if (files.length > 0) {
for (let i = 0; i < files.length; i++) {
// Check expiration
let fileCreationDate: Date = new Date(parseInt(files[i].split(".ai.json")[0]));
let fileCreationDate: Date = new Date(parseInt(files[i].split(`${this._processId}.ai.json`)[0]));
let expired = new Date(+(new Date()) - Sender.FILE_RETEMPTION_PERIOD) > fileCreationDate;
if (expired) {
var filePath = path.join(this._tempDir, files[i]);
Expand Down
5 changes: 2 additions & 3 deletions Tests/EndToEnd.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { JsonConfig } from "../Library/JsonConfig";
import { FileAccessControl } from "../Library/FileAccessControl";
import FileSystemHelper = require("../Library/FileSystemHelper");
import AutoCollectHttpRequests = require("../AutoCollection/HttpRequests");

/**
* A fake response class that passes by default
*/
Expand Down Expand Up @@ -484,8 +483,8 @@ describe("EndToEnd", () => {
writeFile = sandbox.stub(FileSystemHelper, 'writeFileAsync');
writeFileSync = sandbox.stub(fs, 'writeFileSync');
existsSync = sandbox.stub(fs, 'existsSync').returns(true);
readdir = sandbox.stub(FileSystemHelper, 'readdirAsync').returns(['1.ai.json']);
readdirSync = sandbox.stub(fs, 'readdirSync').returns(['1.ai.json']);
readdir = sandbox.stub(FileSystemHelper, 'readdirAsync').returns([`${process.pid}.ai.json`]);
readdirSync = sandbox.stub(fs, 'readdirSync').returns([`${process.pid}.ai.json`]);
stat = sandbox.stub(FileSystemHelper, 'statAsync').returns({ isFile: () => true, size: 8000 });
statSync = sandbox.stub(fs, 'statSync').returns({ isFile: () => true, size: 8000 });
lstat = sandbox.stub(FileSystemHelper, 'lstatAsync').returns({ isDirectory: () => true });
Expand Down
83 changes: 49 additions & 34 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading