Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,21 @@ locker.lock('locks:fastlock',5000);
array.push(1);
array.push(2);
locker.unlock();
```

### Using Mock Redis (for development)

You can use a mock Redis instance for development and testing without running a real Redis server:

```[js](js)
const { FastLock } = require('@fastcampus/fastlock');

const locker = FastLock.create({ useMock: true });
const array = [];
await locker.lock('locks:fastlock', 5000);
array.push(1);
array.push(2);
await locker.unlock();
```

## Contributing
Expand All @@ -27,6 +40,12 @@ locker.unlock();
$ npm run ci:test
```

### test with mock Redis

```console
$ npm run test:mock
```

### build

```console
Expand Down
100 changes: 81 additions & 19 deletions example/example.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,92 @@
import { LoggerFactory } from '@day1co/pebbles';
import { FastLock } from '../src/fast-lock';

/**
* FastLock 라이브러리 사용 예제
*
* 이 예제는 분산 락을 사용하여 공유 리소스(배열)에 대한 동시 접근을 제어하는 방법을 보여줍니다.
* 두 개의 프로세스가 동일한 리소스에 접근하려 할 때, FastLock이 어떻게 동작하는지 시연합니다.
*/

const logger = LoggerFactory.getLogger('fastlock:example');
const sleep = async (ms) => new Promise((res) => setTimeout(res, ms));
const sleep = async (ms: number) => new Promise((res) => setTimeout(res, ms));

// 공유 리소스로 사용될 배열
const sharedArray: number[] = [];

const myArray = [];
const anotherProcess = async () => {
/**
* 두 번째 프로세스를 시뮬레이션하는 함수
* 첫 번째 프로세스가 락을 보유하고 있는 동안 리소스 접근을 시도합니다.
*
* @returns Promise<void>
*/
const simulateSecondProcess = async (): Promise<void> => {
const locker = FastLock.create({ redis: { host: 'localhost', port: 6379, db: 0 } });
await locker.lock('locks:example', 2000);
myArray.push(4);
myArray.push(5);
myArray.push(6);
await sleep(2000);
try {
// 2초 동안 유효한 락 획득 시도
await locker.lock('locks:example', 2000);
logger.debug('Second process: Lock acquired');

// 공유 리소스 수정
sharedArray.push(4);
sharedArray.push(5);
sharedArray.push(6);

// 작업 시뮬레이션을 위한 대기
await sleep(2000);

await locker.unlock();
logger.debug('Second process: Lock released');
} catch (err) {
logger.error('Second process error: %o', err);
} finally {
locker.destroy();
}
};

const main = async () => {
/**
* 메인 프로세스 실행 함수
* 첫 번째로 락을 획득하고, 작업 중에 다른 프로세스의 접근을 시도합니다.
*
* 시나리오:
* 1. 첫 번째 프로세스가 락을 획득하고 배열에 1,2,3을 추가
* 2. 100ms 후 두 번째 프로세스가 시작되어 락 획득 시도
* 3. 첫 번째 프로세스가 작업을 완료하고 락을 해제
* 4. 두 번째 프로세스가 락을 획득하고 배열에 4,5,6을 추가
*
* @returns Promise<void>
*/
const demonstrateLocking = async (): Promise<void> => {
const locker = FastLock.create({ redis: { host: 'localhost', port: 6379, db: 0 } });
await locker.lock('locks:example', 2000);
myArray.push(1);
myArray.push(2);
myArray.push(3);
setTimeout(async () => anotherProcess(), 100);
await sleep(2000);
await locker.unlock();
locker.destroy();
logger.debug('%o', myArray);
try {
// 2초 동안 유효한 락 획득
await locker.lock('locks:example', 2000);
logger.debug('Main process: Lock acquired');

// 공유 리소스 수정
sharedArray.push(1);
sharedArray.push(2);
sharedArray.push(3);

// 두 번째 프로세스 시작
setTimeout(async () => simulateSecondProcess(), 100);

// 작업 시뮬레이션을 위한 대기
await sleep(2000);

await locker.unlock();
logger.debug('Main process: Lock released');
} catch (err) {
logger.error('Main process error: %o', err);
} finally {
locker.destroy();
logger.debug('Final shared array state: %o', sharedArray);
}
};

main().then(console.info).catch(console.error);
// 예제 실행
demonstrateLocking().then(() => {
logger.info('Example completed');
}).catch(err => {
logger.error('Example failed: %o', err);
});
9 changes: 5 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
globals: {
'ts-jest': {
tsConfig: 'tsconfig.json',
},
},
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
},
testEnvironment: 'node',
testTimeout: 30000,
verbose: true,
collectCoverage: true,
};
Loading