Sawetara wektu kepungkur kita ngadhepi masalah ngresiki tuple ing spasi
Conto sing apik kanggo kita yaiku modul tarantool sing diarani
Description
Dokumentasi kanggo tarantool wis apik banget
Ayo miwiti saka adoh lan ndeleng apa modul kadaluwarsa sing ditutup saka njaba:
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)
Kanggo gamblang, kita miwiti tarantool ing direktori ngendi perpustakaan libcapped-expirationd.so kita dumunung. Rong fungsi diekspor saka perpustakaan: miwiti lan mateni. Langkah pisanan yaiku nggawe fungsi kasebut kasedhiya saka Lua nggunakake box.schema.func.create lan box.schema.user.grant. Banjur gawe spasi sing tuple mung ngemot telung kolom: sing pisanan minangka pengenal unik, sing kapindho yaiku email, lan sing katelu yaiku umur tuple. Kita mbangun indeks wit ing ndhuwur lapangan pisanan lan nyebataken utami. Sabanjure kita entuk obyek sambungan menyang perpustakaan asli kita.
Sawise karya persiapan, jalanake fungsi wiwitan:
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})
Conto iki bakal bisa digunakake nalika mindhai persis padha karo modul kadaluwarsa, sing ditulis ing Lua. Argumentasi pisanan kanggo fungsi wiwitan yaiku jeneng unik saka tugas kasebut. Kapindho yaiku pengenal spasi. Katelu yaiku indeks unik sing tuples bakal dibusak. Ingkang kaping sekawan inggih menika indeks ingkang badhe dipunlampahi tuple. Kalima yaiku nomer lapangan tuple kanthi umur (nomer diwiwiti saka 1, dudu 0!). Sing nomer enem lan kapitu yaiku setelan mindhai. 1024 minangka jumlah maksimum tuple sing bisa dideleng ing siji transaksi. 3600 - wektu scan lengkap ing detik.
Elinga yen conto nggunakake indeks sing padha kanggo crawling lan mbusak. Yen iki minangka indeks wit, mula traversal ditindakake saka kunci sing luwih cilik menyang sing luwih gedhe. Yen ana sawetara liyane, umpamane, indeks hash, banjur traversal ditindakake, minangka aturan, kanthi urutan acak. Kabeh tuple spasi dipindai ing siji scan.
Ayo lebokake sawetara tupel menyang ruang kanthi umur 60 detik:
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}
Ayo priksa manawa sisipan kasebut sukses:
tarantool> box.space.tester.index.primary:select()
---
- - [0, '[email protected]', 1576418976]
- [1, '[email protected]', 1576418976]
- [2, '[email protected]', 1576418976]
...
Ayo baleni pilih sawise 60+ detik (dietung saka wiwitan nglebokake tuple pisanan) lan deleng manawa modul kadaluwarsa sing ditutup wis diproses:
tarantool> box.space.tester.index.primary:select()
---
- []
...
Ayo mungkasi tugas:
capped_connection:call('libcapped-expirationd.kill', {'non-indexed'})
Ayo goleki conto liyane ing ngendi indeks kapisah digunakake kanggo nyusup:
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)
Kabeh ing kene padha karo conto pisanan, kanthi sawetara pangecualian. Kita mbangun indeks wit ing ndhuwur lapangan katelu lan nyebataken exp. Indeks iki ora kudu unik, ora kaya indeks sing diarani primer. Traversal bakal ditindakake kanthi indeks exp, lan pambusakan kanthi utami. Kita elinga yen sadurunge loro-lorone ditindakake mung nggunakake indeks utama.
Sawise karya persiapan, kita mbukak fungsi wiwitan kanthi argumen anyar:
capped_connection:call('libcapped-expirationd.start', {'indexed', box.space.tester.id, box.space.tester.index.primary, box.space.tester.index.exp, 3, 1024, 3600})
Ayo lebokake sawetara tupel menyang spasi maneh kanthi umur 60 detik:
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}
Sawise 30 detik, kanthi analogi, kita bakal nambah sawetara tuple maneh:
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}
Ayo priksa manawa sisipan kasebut sukses:
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]
...
Ayo baleni pilih sawise 60+ detik (dietung saka wiwitan nglebokake tuple pisanan) lan deleng manawa modul kadaluwarsa sing ditutup wis diproses:
tarantool> box.space.tester.index.primary:select()
---
- - [3, '[email protected]', 1576421287]
- [4, '[email protected]', 1576421287]
- [5, '[email protected]', 1576421287]
...
Isih ana sawetara tuple sing isih ana ing papan sing bakal duwe udakara 30 detik maneh. Kajaba iku, pindai mandheg nalika pindhah saka tuple kanthi ID 2 lan umur 1576421257 menyang tuple kanthi ID 3 lan umur 1576421287. Tuple kanthi umur 1576421287 utawa luwih ora dipindai amarga pesenan saka tombol indeks exp. Iki minangka tabungan sing dikarepake ing wiwitan.
Ayo mungkasi tugas:
capped_connection:call('libcapped-expirationd.kill', {'indexed'})
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ
Cara paling apik kanggo nyritakake babagan kabeh fitur proyek yaiku sumber asline.
Argumentasi sing diterusake menyang metode wiwitan disimpen ing struktur sing diarani 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;
};
Atribut jeneng yaiku jeneng tugas. Atribut space_id minangka pengenal spasi. Atribut rm_index_id minangka pengenal indeks unik sing tuple bakal dibusak. Atribut it_index_id minangka pengenal indeks sing bakal dilewati tuple. Atribut it_index_type yaiku jinis indeks sing bakal dilewati tuple. Atribut filed_no yaiku nomer kolom tuple kanthi umur. Atribut scan_size yaiku jumlah maksimum tuple sing dipindai ing siji transaksi. Atribut scan_time yaiku wektu scan lengkap ing detik.
Kita ora bakal nimbang argumen parsing. Iki minangka proyek sing angel nanging prasaja, sing bakal mbantu sampeyan perpustakaan
Kita dhaptar prototipe kabeh fungsi sing digunakake kanggo parsing:
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);
Saiki ayo pindhah menyang sing paling penting - logika ngliwati spasi lan mbusak tuple. Saben blok tuple ora luwih gedhe tinimbang scan_size dipindai lan diowahi ing siji transaksi. Yen kasil, transaksi iki dileksanakake; yen ana kesalahan, digulung maneh. Argumentasi pungkasan kanggo fungsi expirationd_iterate minangka pointer menyang iterator saka ngendi pemindaian diwiwiti utawa diterusake. iterator iki incremented internal nganti ana kesalahan, spasi entek, utawa ora bisa kanggo mungkasi proses ing advance. Fungsi expirationd_expired mriksa umur tuple, expirationd_delete mbusak tuple, expirationd_breakable mriksa apa kita kudu nerusake.
Kode fungsi 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;
}
Kode fungsi 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;
}
Kode fungsi 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);
}
Kode fungsi 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;
}
Aplikasi
Sampeyan bisa ndeleng kode sumber ing
Source: www.habr.com