Skip to content

Commit acf50bb

Browse files
committed
feat: delete unconfirmed users lua doc updates
1 parent f543717 commit acf50bb

3 files changed

Lines changed: 104 additions & 3 deletions

File tree

doc/rfcs/inactive_users_cleanup.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ In order to provide generally better data handling and clean database structure,
99
- `inactive-users`
1010
Redis database sorted set key. Bound to `USER_ACTIVATE` constant.
1111
Record contains `userId` as value and `timestamp` as score.
12-
- `user-audience`
13-
Redis database hash key. Bound to `USERS_AUDIENCE` constant. Stores `userId` to `audience[string]` mapping, contains any audiences used in user's metadata.
12+
- `user-audience` [Described here](user_audience_tracking.md)
1413
- `deleteInactivated` Redis script, handling all cleanup logic
1514

1615

@@ -57,7 +56,7 @@ When script started:
5756
11. Key prefix from `THROTTLE_PREFIX` constant = `local kThrottlePrefix`
5857

5958
### Passed arguments(next `ARG.$ind` used):
60-
1. UserAlias field name from user data `USERs_ALIAS_FIELD`
59+
1. UserAlias field name from user data `USERS_ALIAS_FIELD`
6160
2. UserName field name from data `USERS_USERNAME_FIELD`
6261
3. JSON string based on `SSO_PROVIDERS`
6362
4. JSON string based on `THROTTLE_ACTIONS`
@@ -93,3 +92,11 @@ When script started:
9392
* forms Throttle `key` names from userId, `THROTTLE_PREFIX`(`KEY.11`)
9493
* deletes throttle `key`
9594

95+
96+
## UPD
97+
Script has lots of dependent keys and templates. To lower the amount of passed data and avoid some computations we can try to
98+
generate script on the fly from `template`, as it working in current `utils/updateMetadata` function when updating data with inline scripts.
99+
General script behavior stays unchanged, but the amount of `json.decode`, `KEYS[]` and `ARGS[]` going to be smaller.
100+
101+
To avoid on the fly generation, the `mfleet.plugin:connect:$redisType` event could be used. When service connects to Redis database,
102+
script will be generated from the template and registered in `ioredis`.

doc/rfcs/update_metadata_lua.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# User metadata update rework
2+
## Overview and Motivation
3+
`ms-users` service uses Redis pipeline based javascript script for updating user metadata records.
4+
For audience tracking features, there were some logic changes in `utils/updateMetadata.js`, but this brought
5+
some problems with parallel update requests: Some changes to the user's audience list could be lost.
6+
It's possible to use `dlock` semaphores to block parallel updates: https://github.com/AVVS/distributed-callback-queue#semaphore, but
7+
a better solution is to use Redis LUA script, this guarantees that data is updated and all audiences stay in place.
8+
9+
## utils/updateMetadata.js
10+
Almost all logic presented in this file will be removed and ported into LUA Script.
11+
This Function will check the consistency of the provided `opts`. If `opts.metadata` and `opts.audiences` are objects,
12+
they will be transformed to array. Count of meta operations and audiences checked to equal each other.
13+
14+
After commands execution result returned from the script, decoded from JSON string, all command results that having length == 1
15+
converted from an array to value from array[0].
16+
17+
## script/updateMetadata.lua
18+
Script repeats all logic including custom scripts.
19+
### Script parameters:
20+
1. KEYS[1] - "{ms-users}{userId}!metadata!{audience}"-for proper cluster node handling, and used as metadata template
21+
2. KEYS[2] - Audiences hashset/keyTemplate [Described here](user_audience_tracking.md)
22+
2. ARGV[1] UserId
23+
3. ARGV[2] JSON encoded opts parameter opts.{script, metadata, audiences}
24+
25+
### if Scripts provided
26+
All scripts evaluated before any execution. This protects us from inconsistent data changes.
27+
28+
### Audience list update
29+
For proper audience list handling, script get's current list of user's audiences from hset `KEYS[1].userid`, unions them with
30+
`opts.audiences` and generates full list metadata keys. Iterates over them, to form list of curent user audiences,
31+
and saves data back into HSET `KEYS[1].userid`.
32+
33+
### Depending on metadata or script set:
34+
If `opt.metadata` set:
35+
* Script starts iterating audiences.
36+
* On each audience, creates metadata key from provided template
37+
* Iterates over provided in `opt.metadata` operations, based on index of `opts.audiences`.
38+
```javascript
39+
const opts = {
40+
audiences: ['first', 'second'],
41+
metadata: [{
42+
// first audience commands,
43+
}, {
44+
// second audience commands
45+
}]
46+
}
47+
```
48+
Commands executed in order: `audiences[0]` => `metadata[0]`,`audiences[1]` => `metadata[1]`,
49+
50+
If `opt.script` set:
51+
* Script starts iterating audiences and creates metadata keys from provided template
52+
* Iterates over `opt.script`:
53+
* EVAL's script from `script.lua` and executes with params generated from: metadata keys(generated in previous step)
54+
and passed `script.argv`
55+
* If script evaluation fails, script returns redis.error witch description.
56+
57+
When operations/scripts processed, the script forms json object like
58+
```javascript
59+
const metaResponse = [
60+
//forEach audience
61+
{
62+
'$incr': {
63+
field: 'result', // result returned from HINCRBY command
64+
},
65+
'$remove': intCount, // count of deleted fields
66+
'$set': "OK", // or cmd hset result.
67+
}
68+
];
69+
70+
const scriptResponse = {
71+
'scriptName': [
72+
// values returned from script
73+
]
74+
};
75+
```
76+
and returns as encoded json string.
77+

doc/rfcs/user_audience_tracking.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# User's Audience tracking
2+
## Overview and Motivation
3+
At present time, the user's assigned audiences not tracking. When you need to get all available metadata assigned,
4+
you must have hardcoded or predefined list of audiences.
5+
6+
## Audience tracking(single hashset) -- OUTDATED
7+
To store user audiences used in metadata, add Redis database hash key. Bound to `USERS_AUDIENCE` constant(eg: `{ms-users}user-audiences`).
8+
Stores `userId` to `audience[string]` mapping, contains any audiences used in user's metadata.
9+
Data in this key stored as JSON encoded array.
10+
This saves us from polluting Database keysSpace.
11+
12+
## Audience tracking(multiple sets)
13+
Audiences stored in sets formed from `USERS_AUDIENCE` constant and `userId`(eg: `{ms-users}10110110111!audiences`).
14+
This option saves us from encoding and decoding JSON strings, but producing some KeySpace pollution,
15+
because each user record will have an additional key with dependent data.
16+
Brings easier navigation and atomic updates(#IHOPE).
17+

0 commit comments

Comments
 (0)