ΠΠ°ΠΊΠΎΠ΅-ΡΠΎ Π²ΡΠ΅ΠΌΡ Π½Π°Π·Π°Π΄ ΠΏΠ΅ΡΠ΅Π΄ Π½Π°ΠΌΠΈ Π²ΡΡΠ°Π»Π° ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° ΡΠΈΡΡΠΊΠΈ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ Π² ΡΠΏΠ΅ΠΉΡΠ°Ρ
Π₯ΠΎΡΠΎΡΠΈΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠΎΠΌ Π½Π°ΠΌ ΠΏΠΎΡΠ»ΡΠΆΠΈΠ» ΠΌΠΎΠ΄ΡΠ»Ρ tarantool ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ
ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅
Π Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ ΠΊ tarantool Π΅ΡΡΡ ΠΎΡΠ΅Π½Ρ Ρ
ΠΎΡΠΎΡΠΈΠΉ
ΠΠ°Π²Π°ΠΉΡΠ΅ Π½Π°ΡΠ½Π΅ΠΌ ΠΈΠ·Π΄Π°Π»Π΅ΠΊΠ° ΠΈ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ Π½Π° ΡΠΎ, ΠΊΠ°ΠΊ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ capped expirationd ΠΌΠΎΠ΄ΡΠ»Ρ ΡΠ½Π°ΡΡΠΆΠΈ:
fiber = require('fiber')
net_box = require('net.box')
box.cfg{listen = 3300}
box.schema.func.create('libcapped-expirationd.start', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.start')
box.schema.func.create('libcapped-expirationd.kill', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.kill')
box.schema.space.create('tester')
box.space.tester:create_index('primary', {unique = true, parts = {1, 'unsigned'}})
capped_connection = net_box:new(3300)
ΠΠ»Ρ ΠΏΡΠΎΡΡΠΎΡΡ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌ tarantool Π² ΠΊΠ°ΡΠ°Π»ΠΎΠ³Π΅, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π½Π°ΡΠ° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° libcapped-expirationd.so. ΠΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ ΡΠΊΡΠΏΠΎΡΡΠΈΡΡΡΡΡΡ Π΄Π²Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ: start ΠΈ kill. ΠΠ½Π°ΡΠ°Π»Π΅ ΡΠ°ΠΌΠΎΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π΄ΠΎΡΡΡΠΏΠ½ΡΠΌΠΈ ΠΈΠ· Lua Ρ ΠΏΠΎΠΌΠΎΡΡΡ box.schema.func.create ΠΈ box.schema.user.grant. ΠΠ°ΡΠ΅ΠΌ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠΏΠ΅ΠΉΡ, ΠΊΠΎΡΡΠ΅ΠΆΠΈ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π±ΡΠ΄ΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ Π²ΡΠ΅Π³ΠΎ ΡΡΠΈ ΠΏΠΎΠ»Ρ: ΠΏΠ΅ΡΠ²ΠΎΠ΅ β ΡΡΠΎ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΠΉ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ, Π²ΡΠΎΡΠΎΠ΅ β ΡΠ»Π΅ΠΊΡΡΠΎΠ½Π½Π°Ρ ΠΏΠΎΡΡΠ°, ΡΡΠ΅ΡΡΠ΅ β Π²ΡΠ΅ΠΌΡ ΠΆΠΈΠ·Π½ΠΈ ΠΊΠΎΡΡΠ΅ΠΆΠ°. ΠΠΎΠ²Π΅ΡΡ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ»Ρ ΡΡΡΠΎΠΈΠΌ tree-ΠΈΠ½Π΄Π΅ΠΊΡ ΠΈ Π½Π°Π·ΡΠ²Π°Π΅ΠΌ Π΅Π³ΠΎ primary. ΠΠ°Π»Π΅Π΅ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΊ Π½Π°ΡΠ΅ΠΉ Π½Π°ΡΠΈΠ²Π½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ΅.
ΠΠΎΡΠ»Π΅ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΡΠ°Π±ΠΎΡ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ start:
capped_connection:call('libcapped-expirationd.start', {'non-indexed', box.space.tester.id, box.space.tester.index.primary, box.space.tester.index.primary, 3, 1024, 3600})
ΠΡΠΎΡ ΠΏΡΠΈΠΌΠ΅Ρ Π±ΡΠ΄Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΏΡΠΈ ΡΠΊΠ°Π½ΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ ΡΠΎΠ²Π½ΠΎ ΡΠ°ΠΊΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ ΠΌΠΎΠ΄ΡΠ»Ρ expirationd, ΠΊΠΎΡΠΎΡΡΠΉ Π½Π°ΠΏΠΈΡΠ°Π½ Π½Π° Lua. ΠΠ΅ΡΠ²ΡΠΌ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠΌ Π² ΡΡΠ½ΠΊΡΠΈΡ start ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΡΡ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΠΎΠ΅ ΠΈΠΌΡ ΡΠ°ΡΠΊΠ°. ΠΡΠΎΡΡΠΌ β ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΡΠΏΠ΅ΠΉΡΠ°. Π’ΡΠ΅ΡΡΠΈΠΌ β ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΠΉ ΠΈΠ½Π΄Π΅ΠΊΡ, ΠΏΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌΡ Π±ΡΠ΄Π΅Ρ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡΡΡ ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ. Π§Π΅ΡΠ²Π΅ΡΡΡΠΌ β ΠΈΠ½Π΄Π΅ΠΊΡ, ΠΏΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌΡ Π±ΡΠ΄Π΅Ρ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡΡΡ ΠΎΠ±Ρ ΠΎΠ΄ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ. ΠΡΡΡΠΌ β Π½ΠΎΠΌΠ΅Ρ ΠΏΠΎΠ»Ρ ΠΊΠΎΡΡΠ΅ΠΆΠ° Ρ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ (Π½ΡΠΌΠ΅ΡΠ°ΡΠΈΡ ΠΈΠ΄Π΅Ρ ΠΎΡ 1, Π° Π½Π΅ 0!). Π¨Π΅ΡΡΡΠΌ ΠΈ ΡΠ΅Π΄ΡΠΌΡΠΌ β Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΡΠΊΠ°Π½ΠΈΡΠΎΠ²Π°Π½ΠΈΡ. 1024 β ΡΡΠΎ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΡΠΎΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅ΡΡΡ Π² ΡΠ°ΠΌΠΊΠ°Ρ ΠΎΠ΄Π½ΠΎΠΉ ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΠΈ. 3600 β Π²ΡΠ΅ΠΌΡ ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ ΡΠΊΠ°Π½ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π² ΡΠ΅ΠΊΡΠ½Π΄Π°Ρ .
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ Π΄Π»Ρ ΠΎΠ±Ρ ΠΎΠ΄Π° ΠΈ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈ ΡΠΎΡ ΠΆΠ΅ ΠΈΠ½Π΄Π΅ΠΊΡ. ΠΡΠ»ΠΈ ΡΡΠΎ tree-ΠΈΠ½Π΄Π΅ΠΊΡ, ΡΠΎ ΠΎΠ±Ρ ΠΎΠ΄ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΡΡΡ ΠΎΡ ΠΌΠ΅Π½ΡΡΠ΅Π³ΠΎ ΠΊΠ»ΡΡΠ° ΠΊ Π±ΠΎΠ»ΡΡΠ΅ΠΌΡ. ΠΡΠ»ΠΈ ΠΊΠ°ΠΊΠΎΠΉ-ΡΠΎ Π΄ΡΡΠ³ΠΎΠΉ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, hash-ΠΈΠ½Π΄Π΅ΠΊΡ, ΡΠΎ ΠΎΠ±Ρ ΠΎΠ΄ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΡΡΡ, ΠΊΠ°ΠΊ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ, Π² ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΠΎΠΌ ΠΏΠΎΡΡΠ΄ΠΊΠ΅. ΠΠ° ΠΎΠ΄Π½ΠΎ ΡΠΊΠ°Π½ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡΠΎΡΠΌΠ°ΡΡΠΈΠ²Π°ΡΡΡΡ Π²ΡΠ΅ ΠΊΠΎΡΡΠ΅ΠΆΠΈ ΡΠΏΠ΅ΠΉΡΠ°.
ΠΠ°Π²Π°ΠΉΡΠ΅ ΡΠ΄Π΅Π»Π°Π΅ΠΌ Π²ΡΡΠ°Π²ΠΊΡ Π² ΡΠΏΠ΅ΠΉΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ Ρ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ 60 ΡΠ΅ΠΊΡΠ½Π΄:
box.space.tester:insert{0, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{1, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{2, '[email protected]', math.floor(fiber.time()) + 60}
ΠΡΠΎΠ²Π΅ΡΠΈΠΌ, ΡΡΠΎ Π²ΡΡΠ°Π²ΠΊΠ° ΠΏΡΠΎΡΠ»Π° ΡΡΠΏΠ΅ΡΠ½ΠΎ:
tarantool> box.space.tester.index.primary:select()
---
- - [0, '[email protected]', 1576418976]
- [1, '[email protected]', 1576418976]
- [2, '[email protected]', 1576418976]
...
ΠΠΎΠ²ΡΠΎΡΠΈΠΌ select ΡΠ΅ΡΠ΅Π· 60+ ΡΠ΅ΠΊΡΠ½Π΄ (ΡΡΠΈΡΠ°Π΅ΠΌ ΠΎΡ Π½Π°ΡΠ°Π»Π° Π²ΡΡΠ°Π²ΠΊΠΈ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΊΠΎΡΡΠ΅ΠΆΠ°) ΠΈ ΡΠ²ΠΈΠ΄ΠΈΠΌ, ΡΡΠΎ ΠΌΠΎΠ΄ΡΠ»Ρ capped expirationd ΡΠΆΠ΅ ΠΎΡΡΠ°Π±ΠΎΡΠ°Π»:
tarantool> box.space.tester.index.primary:select()
---
- []
...
ΠΡΡΠ°Π½ΠΎΠ²ΠΈΠΌ ΡΠ°ΡΠΊ:
capped_connection:call('libcapped-expirationd.kill', {'non-indexed'})
ΠΠ°Π²Π°ΠΉΡΠ΅ ΡΠ°ΡΡΠΌΠΎΡΡΠΈΠΌ Π²ΡΠΎΡΠΎΠΉ ΠΏΡΠΈΠΌΠ΅Ρ, ΠΊΠΎΠ³Π΄Π° Π΄Π»Ρ ΠΎΠ±Ρ ΠΎΠ΄Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΠΈΠ½Π΄Π΅ΠΊΡ:
fiber = require('fiber')
net_box = require('net.box')
box.cfg{listen = 3300}
box.schema.func.create('libcapped-expirationd.start', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.start')
box.schema.func.create('libcapped-expirationd.kill', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.kill')
box.schema.space.create('tester')
box.space.tester:create_index('primary', {unique = true, parts = {1, 'unsigned'}})
box.space.tester:create_index('exp', {unique = false, parts = {3, 'unsigned'}})
capped_connection = net_box:new(3300)
ΠΠ΄Π΅ΡΡ Π²ΡΠ΅ ΡΠΎ ΠΆΠ΅ ΡΠ°ΠΌΠΎΠ΅, ΡΡΠΎ ΠΈ Π² ΠΏΠ΅ΡΠ²ΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅, Π·Π° ΠΌΠ°Π»ΡΠΌ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ. ΠΠΎΠ²Π΅ΡΡ ΡΡΠ΅ΡΡΠ΅Π³ΠΎ ΠΏΠΎΠ»Ρ ΡΡΡΠΎΠΈΠΌ tree-ΠΈΠ½Π΄Π΅ΠΊΡ ΠΈ Π½Π°Π·ΡΠ²Π°Π΅ΠΌ Π΅Π³ΠΎ exp. ΠΡΠΎΡ ΠΈΠ½Π΄Π΅ΠΊΡ Π½Π΅ ΠΎΠ±ΡΠ·Π°Π½ Π±ΡΡΡ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΠΌ, Π² ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ ΠΈΠ½Π΄Π΅ΠΊΡΠ° ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ primary. ΠΠ±Ρ ΠΎΠ΄ Π±ΡΠ΄Π΅Ρ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡΡΡ ΠΏΠΎ exp ΠΈΠ½Π΄Π΅ΠΊΡΡ, Π° ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎ primary. ΠΡ ΠΏΠΎΠΌΠ½ΠΈΠΌ, ΡΡΠΎ ΡΠ°Π½Π΅Π΅ ΠΈ ΡΠΎ, ΠΈ Π΄ΡΡΠ³ΠΎΠ΅ Π΄Π΅Π»Π°Π»ΠΎΡΡ ΡΠΎΠ»ΡΠΊΠΎ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ primary ΠΈΠ½Π΄Π΅ΠΊΡΠ°.
ΠΠΎΡΠ»Π΅ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΡΠ°Π±ΠΎΡ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ start Ρ Π½ΠΎΠ²ΡΠΌΠΈ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°ΠΌΠΈ:
capped_connection:call('libcapped-expirationd.start', {'indexed', box.space.tester.id, box.space.tester.index.primary, box.space.tester.index.exp, 3, 1024, 3600})
Π‘Π½ΠΎΠ²Π° ΡΠ΄Π΅Π»Π°Π΅ΠΌ Π²ΡΡΠ°Π²ΠΊΡ Π² ΡΠΏΠ΅ΠΉΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ Ρ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ 60 ΡΠ΅ΠΊΡΠ½Π΄:
box.space.tester:insert{0, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{1, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{2, '[email protected]', math.floor(fiber.time()) + 60}
Π§Π΅ΡΠ΅Π· 30 ΡΠ΅ΠΊΡΠ½Π΄ ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π΅ΡΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ:
box.space.tester:insert{3, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{4, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{5, '[email protected]', math.floor(fiber.time()) + 60}
ΠΡΠΎΠ²Π΅ΡΠΈΠΌ, ΡΡΠΎ Π²ΡΡΠ°Π²ΠΊΠ° ΠΏΡΠΎΡΠ»Π° ΡΡΠΏΠ΅ΡΠ½ΠΎ:
tarantool> box.space.tester.index.primary:select()
---
- - [0, '[email protected]', 1576421257]
- [1, '[email protected]', 1576421257]
- [2, '[email protected]', 1576421257]
- [3, '[email protected]', 1576421287]
- [4, '[email protected]', 1576421287]
- [5, '[email protected]', 1576421287]
...
ΠΠΎΠ²ΡΠΎΡΠΈΠΌ select ΡΠ΅ΡΠ΅Π· 60+ ΡΠ΅ΠΊΡΠ½Π΄ (ΡΡΠΈΡΠ°Π΅ΠΌ ΠΎΡ Π½Π°ΡΠ°Π»Π° Π²ΡΡΠ°Π²ΠΊΠΈ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΊΠΎΡΡΠ΅ΠΆΠ°) ΠΈ ΡΠ²ΠΈΠ΄ΠΈΠΌ, ΡΡΠΎ ΠΌΠΎΠ΄ΡΠ»Ρ capped expirationd ΡΠΆΠ΅ ΠΎΡΡΠ°Π±ΠΎΡΠ°Π»:
tarantool> box.space.tester.index.primary:select()
---
- - [3, '[email protected]', 1576421287]
- [4, '[email protected]', 1576421287]
- [5, '[email protected]', 1576421287]
...
Π ΡΠΏΠ΅ΠΉΡΠ΅ ΠΎΡΡΠ°Π»ΠΈΡΡ ΠΊΠΎΡΡΠ΅ΠΆΠΈ, ΠΊΠΎΡΠΎΡΡΠΌ ΠΆΠΈΡΡ Π΅ΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ 30 ΡΠ΅ΠΊΡΠ½Π΄. ΠΠΎΠ»Π΅Π΅ ΡΠΎΠ³ΠΎ, ΡΠΊΠ°Π½ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΠ»ΠΎΡΡ ΠΏΡΠΈ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄Π΅ ΠΎΡ ΠΊΠΎΡΡΠ΅ΠΆΠ° Ρ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ 2 ΠΈ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ 1576421257 ΠΊ ΠΊΠΎΡΡΠ΅ΠΆΡ Ρ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ 3 ΠΈ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ 1576421287. ΠΠΎΡΡΠ΅ΠΆΠΈ Ρ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ 1576421287 ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΏΡΠΎΡΠΌΠΎΡΡΠ΅Π½Ρ Π½Π΅ Π±ΡΠ»ΠΈ Π·Π° ΡΡΠ΅Ρ ΡΠΏΠΎΡΡΠ΄ΠΎΡΠ΅Π½Π½ΠΎΡΡΠΈ ΠΊΠ»ΡΡΠ΅ΠΉ exp ΠΈΠ½Π΄Π΅ΠΊΡΠ°. ΠΡΠ° ΠΈ Π΅ΡΡΡ ΡΠ° ΡΠΊΠΎΠ½ΠΎΠΌΠΈΡ, ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΌΡ Ρ ΠΎΡΠ΅Π»ΠΈ Π΄ΠΎΠ±ΠΈΡΡΡΡ Π² ΡΠ°ΠΌΠΎΠΌ Π½Π°ΡΠ°Π»Π΅.
ΠΡΡΠ°Π½ΠΎΠ²ΠΈΠΌ ΡΠ°ΡΠΊ:
capped_connection:call('libcapped-expirationd.kill', {'indexed'})
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ
ΠΡΡΡΠ΅ Π²ΡΠ΅Π³ΠΎ ΠΎ Π²ΡΠ΅Ρ
ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΡΡ
ΠΏΡΠΎΠ΅ΠΊΡΠ° Π²ΡΠ΅Π³Π΄Π° ΡΠ°ΡΡΠΊΠ°ΠΆΠ΅Ρ Π΅Π³ΠΎ ΠΈΡΡ
ΠΎΠ΄Π½ΡΠΉ
ΠΡΠ³ΡΠΌΠ΅Π½ΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΠΌ Π² ΠΌΠ΅ΡΠΎΠ΄ start, ΡΠΎΡ ΡΠ°Π½ΡΡΡΡΡ Π² ΡΡΡΡΠΊΡΡΡΠ΅ ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ expirationd_task:
struct expirationd_task
{
char name[256];
uint32_t space_id;
uint32_t rm_index_id;
uint32_t it_index_id;
uint32_t it_index_type;
uint32_t field_no;
uint32_t scan_size;
uint32_t scan_time;
};
ΠΡΡΠΈΠ±ΡΡ name β ΡΡΠΎ ΠΈΠΌΡ ΡΠ°ΡΠΊΠ°. ΠΡΡΠΈΠ±ΡΡ space_id β ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΡΠΏΠ΅ΠΉΡΠ°. ΠΡΡΠΈΠ±ΡΡ rm_index_id β ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΈΠ½Π΄Π΅ΠΊΡΠ°, ΠΏΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌΡ Π±ΡΠ΄Π΅Ρ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡΡΡ ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ. ΠΡΡΠΈΠ±ΡΡ it_index_id β ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΠΈΠ½Π΄Π΅ΠΊΡΠ°, ΠΏΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌΡ Π±ΡΠ΄Π΅Ρ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡΡΡ ΠΎΠ±Ρ ΠΎΠ΄ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ. ΠΡΡΠΈΠ±ΡΡ it_index_type β ΡΠΈΠΏ ΠΈΠ½Π΄Π΅ΠΊΡΠ°, ΠΏΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌΡ Π±ΡΠ΄Π΅Ρ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡΡΡ ΠΎΠ±Ρ ΠΎΠ΄ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ. ΠΡΡΠΈΠ±ΡΡ filed_no β Π½ΠΎΠΌΠ΅Ρ ΠΏΠΎΠ»Ρ ΠΊΠΎΡΡΠ΅ΠΆΠ° Ρ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ. ΠΡΡΠΈΠ±ΡΡ scan_size β ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΡΠΎΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅ΡΡΡ Π² ΡΠ°ΠΌΠΊΠ°Ρ ΠΎΠ΄Π½ΠΎΠΉ ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΠΈ. ΠΡΡΠΈΠ±ΡΡ scan_time β Π²ΡΠ΅ΠΌΡ ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ ΡΠΊΠ°Π½ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π² ΡΠ΅ΠΊΡΠ½Π΄Π°Ρ .
ΠΠ°ΡΡΠΈΠ½Π³ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ² ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°ΡΡ Π½Π΅ Π±ΡΠ΄Π΅ΠΌ. ΠΡΠΎ ΠΊΡΠΎΠΏΠΎΡΠ»ΠΈΠ²Π°Ρ, Π½ΠΎ Π½Π΅ΡΠ»ΠΎΠΆΠ½Π°Ρ ΡΠ°Π±ΠΎΡΠ°, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ Π²Π°ΠΌ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°
ΠΠ΅ΡΠ΅ΡΠΈΡΠ»ΠΈΠΌ ΠΏΡΠΎΡΠΎΡΠΈΠΏΡ Π²ΡΠ΅Ρ ΡΡΠ½ΠΊΡΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π΄Π»Ρ ΠΏΠ°ΡΡΠΈΠ½Π³Π°:
bool expirationd_parse_name(struct expirationd_task *task, const char **pos);
bool expirationd_parse_space_id(struct expirationd_task *task, const char **pos);
bool expirationd_parse_rm_index_id(struct expirationd_task *task, const char **pos);
bool expirationd_parse_rm_index_unique(struct expirationd_task *task, const char **pos);
bool expirationd_parse_rm_index(struct expirationd_task *task, const char **pos);
bool expirationd_parse_it_index_id(struct expirationd_task *task, const char **pos);
bool expirationd_parse_it_index_type(struct expirationd_task *task, const char **pos);
bool expirationd_parse_it_index(struct expirationd_task *task, const char **pos);
bool expirationd_parse_field_no(struct expirationd_task *task, const char **pos);
bool expirationd_parse_scan_size(struct expirationd_task *task, const char **pos);
bool expirationd_parse_scan_time(struct expirationd_task *task, const char **pos);
Π ΡΠ΅ΠΏΠ΅ΡΡ ΠΏΠ΅ΡΠ΅ΠΉΠ΄Π΅ΠΌ ΠΊ ΡΠ°ΠΌΠΎΠΌΡ Π³Π»Π°Π²Π½ΠΎΠΌΡ β ΠΊ Π»ΠΎΠ³ΠΈΠΊΠ΅ ΠΎΠ±Ρ ΠΎΠ΄Π° ΡΠΏΠ΅ΠΉΡΠ° ΠΈ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ. ΠΠ°ΠΆΠ΄ΡΠΉ Π±Π»ΠΎΠΊ ΠΊΠΎΡΡΠ΅ΠΆΠ΅ΠΉ ΡΠ°Π·ΠΌΠ΅ΡΠΎΠΌ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ scan_size ΠΏΡΠΎΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅ΡΡΡ ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΡΡΡ ΠΏΠΎΠ΄ ΠΎΠ΄Π½ΠΎΠΉ ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΠ΅ΠΉ. Π ΡΠ»ΡΡΠ°Π΅ ΡΡΠΏΠ΅Ρ Π° ΡΡΠ° ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΡ ΠΊΠΎΠΌΠΌΠΈΡΠΈΡΡΡ, Π² ΡΠ»ΡΡΠ°Π΅ ΠΎΡΠΈΠ±ΠΊΠΈ β ΠΎΡΠΊΠ°ΡΡΠ²Π°Π΅ΡΡΡ. ΠΠΎΡΠ»Π΅Π΄Π½ΠΈΠΌ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠΌ Π² ΡΡΠ½ΠΊΡΠΈΡ expirationd_iterate ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΠΈΡΠ΅ΡΠ°ΡΠΎΡ, Ρ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π½Π°ΡΠΈΠ½Π°Π΅ΡΡΡ ΠΈΠ»ΠΈ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅ΡΡΡ ΡΠΊΠ°Π½ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅. ΠΡΠΎΡ ΠΈΡΠ΅ΡΠ°ΡΠΎΡ ΠΈΠ½ΠΊΡΠ΅ΠΌΠ΅Π½ΡΠΈΡΡΠ΅ΡΡΡ Π²Π½ΡΡΡΠΈ ΠΏΠΎΠΊΠ° Π½Π΅ ΠΏΡΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ ΠΎΡΠΈΠ±ΠΊΠ°, Π½Π΅ Π·Π°ΠΊΠΎΠ½ΡΠΈΡΡΡ ΡΠΏΠ΅ΠΉΡ, Π»ΠΈΠ±ΠΎ Π½Π΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²ΠΈΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ Π·Π°ΡΠ°Π½Π΅Π΅ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΏΡΠΎΡΠ΅ΡΡ. Π€ΡΠ½ΠΊΡΠΈΡ expirationd_expired ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ Π²ΡΠ΅ΠΌΡ ΠΆΠΈΠ·Π½ΠΈ ΠΊΠΎΡΡΠ΅ΠΆΠ°, expirationd_delete β ΡΠ΄Π°Π»ΡΠ΅Ρ ΠΊΠΎΡΡΠ΅ΠΆ, expirationd_breakable β ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ, Π½ΡΠΆΠ½ΠΎ Π»ΠΈ Π½Π°ΠΌ Π΄Π²ΠΈΠ³Π°ΡΡΡΡ Π΄Π°Π»ΡΡΠ΅.
ΠΠΎΠ΄ ΡΡΠ½ΠΊΡΠΈΠΈ expirationd_iterate:
static bool
expirationd_iterate(struct expirationd_task *task, box_iterator_t **iterp)
{
box_iterator_t *iter = *iterp;
box_txn_begin();
for (uint32_t i = 0; i < task->scan_size; ++i) {
box_tuple_t *tuple = NULL;
if (box_iterator_next(iter, &tuple) < 0) {
box_iterator_free(iter);
*iterp = NULL;
box_txn_rollback();
return false;
}
if (!tuple) {
box_iterator_free(iter);
*iterp = NULL;
box_txn_commit();
return true;
}
if (expirationd_expired(task, tuple))
expirationd_delete(task, tuple);
else if (expirationd_breakable(task))
break;
}
box_txn_commit();
return true;
}
ΠΠΎΠ΄ ΡΡΠ½ΠΊΡΠΈΠΈ expirationd_expired:
static bool
expirationd_expired(struct expirationd_task *task, box_tuple_t *tuple)
{
const char *buf = box_tuple_field(tuple, task->field_no - 1);
if (!buf || mp_typeof(*buf) != MP_UINT)
return false;
uint64_t val = mp_decode_uint(&buf);
if (val > fiber_time64() / 1000000)
return false;
return true;
}
ΠΠΎΠ΄ ΡΡΠΊΠ½ΡΠΈΠΈ expirationd_delete:
static void
expirationd_delete(struct expirationd_task *task, box_tuple_t *tuple)
{
uint32_t len;
const char *str = box_tuple_extract_key(tuple, task->space_id, task->rm_index_id, &len);
box_delete(task->space_id, task->rm_index_id, str, str + len, NULL);
}
ΠΠΎΠ΄ ΡΡΠ½ΠΊΡΠΈΠΈ expirationd_breakable:
static bool
expirationd_breakable(struct expirationd_task *task)
{
return task->it_index_id != task->rm_index_id && task->it_index_type == ITER_GT;
}
ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
ΠΠ·Π½Π°ΠΊΠΎΠΌΠΈΡΡΡΡ Ρ ΠΈΡΡ
ΠΎΠ΄Π½ΡΠΌ ΠΊΠΎΠ΄ΠΎΠΌ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com