Skip to content

Commit e29c773

Browse files
Merge pull request #19 from express-rate-limit/feat/improve-scalability
Feat/improve scalability
2 parents cdb48dd + e762d5c commit e29c773

28 files changed

+641
-631
lines changed

.github/workflows/cicd.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
runs-on: ubuntu-latest
1111
strategy:
1212
matrix:
13-
node-version: [16.x, 18.x]
13+
node-version: [16.x, lts/*, latest]
1414
steps:
1515
- uses: actions/checkout@v3
1616
- name: Use Node.js ${{ matrix.node-version }}

.mocharc.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
{
22
"extension": ["ts"],
3+
"loader": "ts-node/esm",
34
"spec": "test/**/*.spec.ts",
4-
"node-option": [
5-
"experimental-specifier-resolution=node",
6-
"loader=ts-node/esm"
7-
],
85
"recursive": true
96
}

changelog.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to
77
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
88

9+
## [1.4.0](https://github.com/express-rate-limit/express-rate-limit-postgresql/releases/tag/v1.4.0)
10+
11+
### Changed
12+
13+
- Session handling is now done on the database layer to prevent concurrency
14+
issues.
15+
916
## [1.3.2](https://github.com/express-rate-limit/express-rate-limit-postgresql/releases/tag/v1.3.2)
1017

1118
### Added

contributing.md

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Once you have installed the above, follow
2323
to
2424
[`fork`](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks)
2525
and [`clone`](https://github.com/git-guides/git-clone) the repository
26-
(`adrianprelipcean/express-rate-limit-postgresql`).
26+
(`express-rate-limit/rate-limit-postgresql`).
2727

2828
Once you have forked and cloned the repository, you can
2929
[pick out an issue](https://github.com/express-rate-limit/express-rate-limit-postgresql/issues)
@@ -60,7 +60,6 @@ The library is written in
6060
of Node. The code is arranged as follows:
6161

6262
```sh
63-
rate-limit-postgresql
6463
├── changelog.md
6564
├── code_of_conduct.md
6665
├── configs
@@ -71,6 +70,7 @@ rate-limit-postgresql
7170
├── db
7271
│ ├── cli
7372
│ │ ├── apply_all_migrations.sh
73+
│ │ ├── create_migration.sh
7474
│ │ ├── init_db.sh
7575
│ │ └── run_tests.sh
7676
│ ├── linting
@@ -101,23 +101,21 @@ rate-limit-postgresql
101101
│ │ ├── 1-init.sql
102102
│ │ ├── 2-add-db-functions-agg.sql
103103
│ │ ├── 3-add-db-functions-ind.sql
104-
│ │ └── 4-add-db-functions-sessions.sql
105-
│ ├── models
106-
│ │ └── session.ts
104+
│ │ ├── 4-add-db-functions-sessions.sql
105+
│ │ ├── 5-hotfix-update-constraints.sql
106+
│ │ ├── 6-move-session-to-db-agg.sql
107+
│ │ └── 7-move-session-to-db-agg.sql
107108
│ ├── stores
108109
│ │ ├── aggregated_ip
109110
│ │ │ └── store_aggregated_ip.ts
110111
│ │ └── individual_ip
111112
│ │ └── store_individual_ip.ts
112113
│ └── util
113-
│ ├── migration_handler.ts
114-
│ └── session_handler.ts
114+
│ └── migration_handler.ts
115115
├── test
116-
│ ├── stores
117-
│ │ ├── store_aggregated_ip.spec.ts
118-
│ │ └── store_individual_ip.spec.ts
119-
│ └── util
120-
│ └── session_handler.spec.ts
116+
│ └── stores
117+
│ ├── store_aggregated_ip.spec.ts
118+
│ └── store_individual_ip.spec.ts
121119
├── third_party_licenses
122120
│ ├── dev_detailed.json
123121
│ ├── dev_summary.txt
@@ -222,20 +220,19 @@ changes to GitHub) your commits. To push your changes to your fork:
222220
```
223221

224222
If there are changes made to the `master` branch of the
225-
`adrianprelipcean/express-rate-limit-postgresql` repository, you may wish to
223+
`express-rate-limit/rate-limit-postgresql` repository, you may wish to
226224
[`rebase`](https://docs.github.com/en/get-started/using-git/about-git-rebase)
227225
your branch to include those changes. To rebase, or include the changes from the
228-
`master` branch of the `adrianprelipcean/express-rate-limit-postgresql`
229-
repository:
226+
`master` branch of the `express-rate-limit/rate-limit-postgresql` repository:
230227

231228
```
232229
> git fetch upstream master
233230
> git rebase upstream/master
234231
```
235232

236233
This will automatically add the changes from `master` branch of the
237-
`adrianprelipcean/express-rate-limit-postgresql` repository to the current
238-
branch. If you encounter any merge conflicts, follow
234+
`express-rate-limit/rate-limit-postgresql` repository to the current branch. If
235+
you encounter any merge conflicts, follow
239236
[this guide](https://docs.github.com/en/get-started/using-git/resolving-merge-conflicts-after-a-git-rebase)
240237
to resolve them.
241238

db/tests/performance/aggregated_ip.test.sql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,31 @@ VALUES ('test-update', '00000000-0000-0000-0000-000000000000'::uuid, 20),
2828

2929
SELECT performs_ok(
3030
$bd$
31-
SELECT agg_increment as count FROM rate_limit.agg_increment('test-update', '00000000-0000-0000-0000-000000000000');
31+
SELECT * from rate_limit.agg_increment('test-update', 'dedicated-test', 1000) AS (count int, expires_at timestamptz);
3232
$bd$,
3333
250,
3434
'inserting record should execute under 250ms'
3535
);
3636

3737
SELECT performs_ok(
3838
$bd$
39-
SELECT * FROM rate_limit.agg_decrement('test-decrement', '00000000-0000-0000-0000-000000000000');
39+
SELECT * FROM rate_limit.agg_decrement('test-decrement', 'dedicated-test');
4040
$bd$,
4141
250,
4242
'decrementing query execute under 250ms'
4343
);
4444

4545
SELECT performs_ok(
4646
$bd$
47-
SELECT * FROM rate_limit.agg_reset_key('test-reset-key', '00000000-0000-0000-0000-000000000000')
47+
SELECT * FROM rate_limit.agg_reset_key('test-reset-key', 'dedicated-test')
4848
$bd$,
4949
250,
5050
'resetting a key should execute under 250ms'
5151
);
5252

5353
SELECT performs_ok(
5454
$bd$
55-
SELECT * FROM rate_limit.agg_reset_session('00000000-0000-0000-0000-000000000000');
55+
SELECT * FROM rate_limit.agg_reset_session('dedicated-test');
5656
$bd$,
5757
250,
5858
'resetting a session should execute under 250ms'

db/tests/performance/individual_ip.test.sql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,31 @@ VALUES ('test-count', '00000000-0000-0000-0000-000000000000'::uuid),
2828

2929
SELECT performs_ok(
3030
$bd$
31-
SELECT ind_increment as count FROM rate_limit.ind_increment('test-count', '00000000-0000-0000-0000-000000000000')
31+
SELECT * FROM rate_limit.ind_increment('test-count', 'dedicated-test', 1000) AS (count int, expires_at timestamptz);
3232
$bd$,
3333
250,
3434
'inserting record should execute under 250ms'
3535
);
3636

3737
SELECT performs_ok(
3838
$bd$
39-
SELECT * FROM rate_limit.ind_decrement('test-decrement', '00000000-0000-0000-0000-000000000000');
39+
SELECT * FROM rate_limit.ind_decrement('test-decrement', 'dedicated-test');
4040
$bd$,
4141
250,
4242
'decrementing query execute under 250ms'
4343
);
4444

4545
SELECT performs_ok(
4646
$bd$
47-
SELECT * FROM rate_limit.ind_reset_key('test-reset-key', '00000000-0000-0000-0000-000000000000');
47+
SELECT * FROM rate_limit.ind_reset_key('test-reset-key', 'dedicated-test');
4848
$bd$,
4949
250,
5050
'resetting a key should execute under 250ms'
5151
);
5252

5353
SELECT performs_ok(
5454
$bd$
55-
SELECT * FROM rate_limit.ind_reset_session('00000000-0000-0000-0000-000000000000');
55+
SELECT * FROM rate_limit.ind_reset_session('dedicated-test');
5656
$bd$,
5757
250,
5858
'resetting a session should execute under 250ms'

db/tests/unit/agg_decrement.test.sql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ BEGIN;
22
-- Plan the tests.
33
SELECT plan(2);
44

5-
INSERT INTO rate_limit.sessions (id, name_, type_)
5+
INSERT INTO rate_limit.sessions (id, name_, type_, expires_at)
66
SELECT
77
'00000000-0000-0000-0000-000000000000'::uuid AS id,
88
'dedicated-test'::text AS name_,
9-
'aggregated'::text AS type_;
9+
'aggregated'::text AS type_,
10+
'2023-01-01 10:00:00+0' AS expires_at;
1011

1112
INSERT INTO rate_limit.records_aggregated (key, session_id)
1213
SELECT
@@ -15,7 +16,7 @@ SELECT
1516

1617
SELECT lives_ok(
1718
$have$
18-
SELECT * FROM rate_limit.agg_decrement('existing-key', '00000000-0000-0000-0000-000000000000')
19+
SELECT * FROM rate_limit.agg_decrement('existing-key', 'dedicated-test', '2023-01-01 09:00:00+0')
1920
$have$,
2021
'rate_limit.agg_decrement does not throw an error'
2122
);

db/tests/unit/agg_increment.test.sql

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
BEGIN;
22
-- Plan the tests.
3-
SELECT plan(3);
3+
SELECT plan(5);
44

5-
INSERT INTO rate_limit.sessions (id, name_, type_)
5+
INSERT INTO rate_limit.sessions (id, name_, type_, expires_at)
66
SELECT
77
'00000000-0000-0000-0000-000000000000'::uuid AS id,
88
'dedicated-test'::text AS name_,
9-
'aggregated'::text AS type_
9+
'aggregated'::text AS type_,
10+
'2023-01-01 10:00:00+0'::timestamptz AS expires_at
1011
UNION
1112
SELECT
1213
'00000000-1111-1111-1111-000000000000'::uuid AS id,
1314
'dedicated-test-2'::text AS name_,
14-
'aggregated'::text AS type_;;
15+
'aggregated'::text AS type_,
16+
'2023-01-01 10:00:00+0' AS expires_at
17+
UNION
18+
SELECT
19+
'00000000-2222-2222-2222-000000000000'::uuid AS id,
20+
'dedicated-test-expired'::text AS name_,
21+
'aggregated'::text AS type_,
22+
'2023-01-01 08:00:00+0' AS expires_at;
1523

1624
INSERT INTO rate_limit.records_aggregated (key, session_id)
1725
SELECT
@@ -20,34 +28,59 @@ SELECT
2028

2129
SELECT results_eq(
2230
$have$
23-
SELECT agg_increment AS count FROM rate_limit.agg_increment('new-key', '00000000-0000-0000-0000-000000000000')
31+
SELECT * FROM rate_limit.agg_increment('new-key', 'dedicated-test', 1000, '2023-01-01 09:00:00+0') AS (count int, expires_at timestamptz);
2432
$have$,
2533
$want$
26-
SELECT 1::int AS count;
34+
SELECT 1::int AS count, '2023-01-01 10:00:00+0'::timestamptz as expires_at;
2735
$want$,
2836
'rate_limit.agg_increment returns correct count for new key'
2937
);
3038

3139
SELECT results_eq(
3240
$have$
33-
SELECT agg_increment AS count FROM rate_limit.agg_increment('new-key', '00000000-1111-1111-1111-000000000000')
41+
SELECT * FROM rate_limit.agg_increment('new-key', 'dedicated-test-2', 1000, '2023-01-01 09:00:00+0') AS (count int, expires_at timestamptz);
3442
$have$,
3543
$want$
36-
SELECT 1::int AS count;
44+
SELECT 1::int AS count, '2023-01-01 10:00:00+0'::timestamptz as expires_at;
3745
$want$,
3846
'rate_limit.agg_increment returns correct count for new key on different session'
3947
);
4048

4149
SELECT results_eq(
4250
$have$
43-
SELECT agg_increment AS count FROM rate_limit.agg_increment('existing-key', '00000000-0000-0000-0000-000000000000')
51+
SELECT * FROM rate_limit.agg_increment('existing-key', 'dedicated-test', 1000, '2023-01-01 09:00:00+0') AS (count int, expires_at timestamptz);
4452
$have$,
4553
$want$
46-
SELECT 2::int AS count;
54+
SELECT 2::int AS count, '2023-01-01 10:00:00+0'::timestamptz as expires_at;
4755
$want$,
4856
'rate_limit.agg_increment returns correct count for existing key'
4957
);
5058

59+
SELECT results_eq(
60+
$have$
61+
SELECT * FROM rate_limit.agg_increment('existing-key', 'dedicated-test-expired', 1000, '2023-01-01 09:00:00+0') AS (count int, expires_at timestamptz);
62+
$have$,
63+
$want$
64+
SELECT 1::int AS count, '2023-01-01 09:00:01+0'::timestamptz as expires_at;
65+
$want$,
66+
'rate_limit.agg_increment returns correct count for existing key for expired session'
67+
);
68+
69+
SELECT bag_hasnt(
70+
$have$
71+
SELECT id, name_, type_, expires_at FROM rate_limit.sessions
72+
$have$,
73+
$miss$
74+
SELECT
75+
'00000000-2222-2222-2222-000000000000'::uuid AS id,
76+
'dedicated-test-expired'::text AS name_,
77+
'aggregated'::text AS type_,
78+
'2023-01-01 08:00:00+0'::timestamptz as expires_at;
79+
$miss$,
80+
'expired session should not be reset after increment invoke'
81+
);
82+
83+
5184
-- Finish the tests and clean up.
5285
SELECT finish FROM finish();
5386
ROLLBACK;

db/tests/unit/agg_reset_key.test.sql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ BEGIN;
22
-- Plan the tests.
33
SELECT plan(2);
44

5-
INSERT INTO rate_limit.sessions (id, name_, type_)
5+
INSERT INTO rate_limit.sessions (id, name_, type_, expires_at)
66
SELECT
77
'00000000-0000-0000-0000-000000000000'::uuid AS id,
88
'dedicated-test'::text AS name_,
9-
'aggregated'::text AS type_;
9+
'aggregated'::text AS type_,
10+
'2023-01-01 10:00+0'::timestamptz AS expires_at;
1011

1112
INSERT INTO rate_limit.records_aggregated (key, session_id)
1213
SELECT
@@ -15,7 +16,7 @@ SELECT
1516

1617
SELECT lives_ok(
1718
$have$
18-
SELECT * FROM rate_limit.agg_reset_key('existing-key', '00000000-0000-0000-0000-000000000000')
19+
SELECT * FROM rate_limit.agg_reset_key('existing-key', 'dedicated-test', '2023-01-01 09:00+0'::timestamptz )
1920
$have$,
2021
'rate_limit.agg_reset_key does not throw an error'
2122
);

db/tests/unit/agg_reset_session.test.sql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ BEGIN;
22
-- Plan the tests.
33
SELECT plan(2);
44

5-
INSERT INTO rate_limit.sessions (id, name_, type_)
5+
INSERT INTO rate_limit.sessions (id, name_, type_, expires_at)
66
SELECT
77
'00000000-0000-0000-0000-000000000000'::uuid AS id,
88
'dedicated-test'::text AS name_,
9-
'aggregated'::text AS type_;
9+
'aggregated'::text AS type_,
10+
'2023-01-01 10:00+0'::timestamptz AS expires_at;
1011

1112
INSERT INTO rate_limit.records_aggregated (key, session_id)
1213
SELECT
@@ -19,7 +20,7 @@ SELECT
1920

2021
SELECT lives_ok(
2122
$have$
22-
SELECT * FROM rate_limit.agg_reset_session('00000000-0000-0000-0000-000000000000')
23+
SELECT * FROM rate_limit.agg_reset_session('dedicated-test', '2023-01-01 09:00+0')
2324
$have$,
2425
'rate_limit.agg_reset_session does not throw an error'
2526
);

db/tests/unit/ind_decrement.test.sql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ BEGIN;
22
-- Plan the tests.
33
SELECT plan(2);
44

5-
INSERT INTO rate_limit.sessions (id, name_, type_)
5+
INSERT INTO rate_limit.sessions (id, name_, type_, expires_at)
66
SELECT
77
'00000000-0000-0000-0000-000000000000'::uuid AS id,
88
'dedicated-test'::text AS name_,
9-
'individual'::text AS type_;
9+
'individual'::text AS type_,
10+
'2023-01-01 10:00:00+0'::timestamptz AS expires_at;
1011

1112
INSERT INTO rate_limit.individual_records (key, session_id)
1213
SELECT
@@ -23,7 +24,7 @@ SELECT
2324

2425
SELECT lives_ok(
2526
$have$
26-
SELECT * FROM rate_limit.ind_decrement('existing-key', '00000000-0000-0000-0000-000000000000')
27+
SELECT * FROM rate_limit.ind_decrement('existing-key', 'dedicated-test', '2023-01-01 09:00:00+0'::timestamptz)
2728
$have$,
2829
'rate_limit.ind_decrement does not throw an error'
2930
);

0 commit comments

Comments
 (0)