Skip to content

Commit 5815667

Browse files
author
Artem
committed
#RI-1977 avoid blocking of main thread using I/O sync commands
1 parent 2484eb1 commit 5815667

File tree

4 files changed

+27
-32
lines changed

4 files changed

+27
-32
lines changed

redisinsight/api/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"class-transformer": "^0.2.3",
4949
"class-validator": "^0.12.2",
5050
"express": "^4.17.1",
51+
"fs-extra": "^10.0.0",
5152
"ioredis": "^4.27.1",
5253
"is-glob": "^4.0.1",
5354
"jsonpath": "^1.1.1",

redisinsight/api/src/modules/commands/commands-json.provider.spec.ts

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import axios from 'axios';
2-
import * as fs from 'fs';
2+
import * as fs from 'fs-extra';
33
import { Test, TestingModule } from '@nestjs/testing';
44
import {
55
mockMainCommands,
@@ -10,18 +10,15 @@ import { CommandsJsonProvider } from 'src/modules/commands/commands-json.provide
1010
jest.mock('axios');
1111
const mockedAxios = axios as jest.Mocked<typeof axios>;
1212

13-
jest.mock('fs');
13+
jest.mock('fs-extra');
1414
const mockedFs = fs as jest.Mocked<typeof fs>;
1515

1616
describe('CommandsJsonProvider', () => {
1717
let service: CommandsJsonProvider;
1818

1919
beforeEach(async () => {
20-
jest.mock('fs', () => mockedFs);
20+
jest.mock('fs-extra', () => mockedFs);
2121

22-
mockedFs.existsSync.mockReturnValue(true);
23-
mockedFs.mkdirSync.mockReturnValue('');
24-
mockedFs.writeFileSync.mockReturnValue(undefined);
2522
mockedAxios.get.mockResolvedValue({ data: JSON.stringify(mockMainCommands) });
2623

2724
const module: TestingModule = await Test.createTestingModule({
@@ -37,57 +34,47 @@ describe('CommandsJsonProvider', () => {
3734
});
3835

3936
describe('updateLatestJson', () => {
40-
it('Should create dir and save proper json', async () => {
41-
mockedFs.existsSync.mockReturnValueOnce(false);
42-
43-
await service.updateLatestJson();
44-
45-
// todo: uncomment after enable esModuleInterop in the tsconfig
46-
// expect(mockedFs.mkdirSync).toHaveBeenCalled();
47-
// expect(mockedFs.writeFileSync).toHaveBeenCalled();
48-
});
4937
it('should not fail when incorrect data retrieved', async () => {
5038
mockedAxios.get.mockResolvedValueOnce('json');
5139
await service.updateLatestJson();
5240

53-
// todo: uncomment after enable esModuleInterop in the tsconfig
54-
// expect(mockedFs.writeFileSync).not.toHaveBeenCalled();
41+
expect(mockedFs.writeFile).not.toHaveBeenCalled();
5542
});
5643
});
5744

5845
describe('getCommands', () => {
5946
it('should return default config when file was not found', async () => {
60-
mockedFs.readFileSync.mockImplementationOnce(() => { throw new Error('No file'); });
61-
mockedFs.readFileSync.mockReturnValueOnce(JSON.stringify(mockMainCommands));
47+
mockedFs.readFile.mockRejectedValueOnce(new Error('No file'));
48+
mockedFs.readFile.mockResolvedValueOnce(Buffer.from(JSON.stringify(mockMainCommands)));
6249

6350
expect(await service.getCommands()).toEqual(mockMainCommands);
6451
});
6552
it('should return default config when incorrect json received from file', async () => {
66-
mockedFs.readFileSync.mockReturnValueOnce('incorrect json');
67-
mockedFs.readFileSync.mockReturnValueOnce(JSON.stringify(mockMainCommands));
53+
mockedFs.readFile.mockResolvedValueOnce(Buffer.from('incorrect json'));
54+
mockedFs.readFile.mockResolvedValueOnce(Buffer.from(JSON.stringify(mockMainCommands)));
6855

6956
expect(await service.getCommands()).toEqual(mockMainCommands);
7057
});
7158
it('should return latest commands', async () => {
72-
mockedFs.readFileSync.mockReturnValueOnce(JSON.stringify(mockRedijsonCommands));
59+
mockedFs.readFile.mockResolvedValue(Buffer.from(JSON.stringify(mockRedijsonCommands)));
7360

7461
expect(await service.getCommands()).toEqual(mockRedijsonCommands);
7562
});
7663
});
7764

7865
describe('getDefaultCommands', () => {
7966
it('should return empty object when file was not found', async () => {
80-
mockedFs.readFileSync.mockImplementationOnce(() => { throw new Error('No file'); });
67+
mockedFs.readFile.mockRejectedValue(new Error('No file'));
8168

8269
expect(await service.getDefaultCommands()).toEqual({});
8370
});
8471
it('should return empty object when incorrect json received from file', async () => {
85-
mockedFs.readFileSync.mockReturnValue('incorrect json');
72+
mockedFs.readFile.mockResolvedValue(Buffer.from('incorrect json'));
8673

8774
expect(await service.getDefaultCommands()).toEqual({});
8875
});
8976
it('should return default commands', async () => {
90-
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockRedijsonCommands));
77+
mockedFs.readFile.mockResolvedValue(Buffer.from(JSON.stringify(mockRedijsonCommands)));
9178

9279
expect(await service.getDefaultCommands()).toEqual(mockRedijsonCommands);
9380
});

redisinsight/api/src/modules/commands/commands-json.provider.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Injectable, Logger } from '@nestjs/common';
22
import axios from 'axios';
3-
import * as fs from 'fs';
3+
import * as fs from 'fs-extra';
44
import * as path from 'path';
55
import config from 'src/utils/config';
66

@@ -31,11 +31,9 @@ export class CommandsJsonProvider {
3131
transformResponse: [(raw) => raw],
3232
});
3333

34-
if (!fs.existsSync(PATH_CONFIG.commands)) {
35-
fs.mkdirSync(PATH_CONFIG.commands);
36-
}
34+
await fs.ensureDir(PATH_CONFIG.commands);
3735

38-
fs.writeFileSync(
36+
await fs.writeFile(
3937
path.join(PATH_CONFIG.commands, `${this.name}.json`),
4038
JSON.stringify(JSON.parse(data)), // check that we received proper json object
4139
);
@@ -51,7 +49,7 @@ export class CommandsJsonProvider {
5149
*/
5250
async getCommands() {
5351
try {
54-
return JSON.parse(fs.readFileSync(
52+
return JSON.parse(await fs.readFile(
5553
path.join(PATH_CONFIG.commands, `${this.name}.json`),
5654
'utf8',
5755
));
@@ -67,7 +65,7 @@ export class CommandsJsonProvider {
6765
*/
6866
async getDefaultCommands() {
6967
try {
70-
return JSON.parse(fs.readFileSync(
68+
return JSON.parse(await fs.readFile(
7169
path.join(PATH_CONFIG.defaultCommandsDir, `${this.name}.json`),
7270
'utf8',
7371
));

redisinsight/api/yarn.lock

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3686,6 +3686,15 @@ [email protected], fs-extra@^9.0.0:
36863686
jsonfile "^6.0.1"
36873687
universalify "^2.0.0"
36883688

3689+
fs-extra@^10.0.0:
3690+
version "10.0.0"
3691+
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1"
3692+
integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==
3693+
dependencies:
3694+
graceful-fs "^4.2.0"
3695+
jsonfile "^6.0.1"
3696+
universalify "^2.0.0"
3697+
36893698
fs-minipass@^1.2.7:
36903699
version "1.2.7"
36913700
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"

0 commit comments

Comments
 (0)