~bigbes/tarantool-etcd · events

99ucjldio6vte0p8jj4p5e46svrj43nl · 118 rows

idissue_idevent_typeactorold_valuenew_valuecommentcreated_at
6241ce98-aac8-405f-ad11-ea6aebd811e3tarantool-etcd-iijcreatedEugene BlikhNULL2026-05-19T17:54:17Z
6556bcfd-3100-489b-9b92-a73624aaabb7tarantool-etcd-zkgcreatedEugene BlikhNULL2026-05-20T09:45:18Z
6d0d6a46-bde1-4834-8f10-92d250cd196ctarantool-etcd-rzhcreatedEugene BlikhNULL2026-05-19T17:54:32Z
6d474871-ea88-4e46-b8df-4041f608d6ectarantool-etcd-dkrcreatedEugene BlikhNULL2026-05-20T09:55:25Z
7029e6cf-59f7-4c8c-bdfd-55b9721bfdfdtarantool-etcd-4nrcreatedEugene BlikhNULL2026-05-19T17:54:34Z
70edafc2-4689-4668-acad-4ca1fa4c04e5tarantool-etcd-234createdEugene BlikhNULL2026-05-19T16:34:48Z
734b2899-983e-44b5-b584-6ee0707aaa7atarantool-etcd-0gnclosedEugene BlikhImplemented filters (NOPUT/NODELETE), periodic progress_notify, and gRPC fragment; fixed packed repeated-enum decode bug in lib/protobuf; added Lua + Go conformance testsNULL2026-05-20T09:49:57Z
735f864c-3b3d-4297-b6e0-794f09727eeatarantool-etcd-lkocreatedEugene BlikhNULL2026-05-19T16:33:55Z
767c403c-52ae-425f-a006-951eeaf365eftarantool-etcd-97vcreatedEugene BlikhNULL2026-05-19T17:54:39Z
76a08bd8-1e0c-4553-8a75-d034b93d1a6dtarantool-etcd-8sscreatedEugene BlikhNULL2026-05-20T14:16:16Z
776c67d2-8cbe-48ec-b6ef-787be5f368d4tarantool-etcd-nbscreatedEugene BlikhNULL2026-05-20T09:55:22Z
792d9f81-6e4c-4c6f-ba75-cb138eb54414tarantool-etcd-sqvcreatedEugene BlikhNULL2026-05-19T17:54:45Z
7d3e60cb-8582-4958-8d4f-298009a7c532tarantool-etcd-9ljcreatedEugene BlikhNULL2026-05-19T17:54:07Z
81308796-b73c-4206-b890-159e69e50815tarantool-etcd-laccreatedEugene BlikhNULL2026-05-19T16:34:01Z
8151383d-1a68-4d0d-99d2-618e0942ef05tarantool-etcd-8ssupdatedEugene Blikh{"id":"tarantool-etcd-8ss","title":"Example 2: 3-node EE replicaset self-hosting its own etcd config (file → etcd migration)","description":"Add examples/tarantool-ee-self-hosted-etcd: boot a 3-instance EE replicaset (election failover) from a local cluster-config.yaml where every node runs app.roles.etcd (replicated KV store, read_pref=any). Seed the cluster's OWN etcd store with that config, then rolling-restart each instance to bootstrap from TT_CONFIG_ETCD_* (no --config). Document the cold-boot circularity: self-hosted etcd-config is HA under rolling restart but needs the local file retained as a cold-boot seed. Justfile + README + cluster-config.yaml.","notes":"v2: hardened migrate after EE run hit 'etcdserver: no leader' on the 2nd node (election churn from restarting a node that became leader). Fixes: (1) recompute leader each step, always migrate a follower, leader last; (2) _wait-healthy gate (all live nodes agree on one leader) between steps; (3) endpoints peers-first/self-last; (4) append logs not truncate. Rolling-restart pacing + leader-pick logic verified on Community; EE etcd-source fetch still needs an EE re-run to confirm.","status":"in_progress","priority":2,"issue_type":"feature","assignee":"Eugene Blikh","owner":"bigbes@gmail.com","created_at":"2026-05-20T11:16:17Z","created_by":"Eugene Blikh","updated_at":"2026-05-20T11:30:21Z","started_at":"2026-05-20T11:16:28Z"}{"notes":"VERIFIED end-to-end on EE 3.7.0 (up-file/seed/migrate/probe/reload all pass; migrate idempotent). Root cause of the user's failure: EE config.etcd source pins to Endpoints[0] without failover, so endpoints must be LEADER-FIRST (not peers-first). Also fixed: leader-migrated-last via per-step recompute, _wait-healthy gate, and a pipefail bug (grep -vx on last node exited 1 after work was done). Example complete."}NULL2026-05-20T14:38:01Z
883b3e2d-1448-4639-a031-c6fd5acc6c36tarantool-etcd-cnjcreatedEugene BlikhNULL2026-05-20T09:39:58Z
8a94766d-a19a-4201-8fc3-18b0c83ea47atarantool-etcd-9z2updatedEugene Blikh{"id":"tarantool-etcd-9z2","title":"Phase 5f — Watch option coverage","description":"Per-option density on Watch RPCs. Big stream-shaped surface, highest remaining value but also highest effort. Run after Phase 5e.\n\nLikely tests:\n- TestWatchWithFilterPut / TestWatchWithFilterDelete (server-side event filtering)\n- TestWatchProgressNotifyExplicit (RequestProgress on demand vs the implicit 10-minute heartbeat already covered)\n- TestWatchWithFragment (large-response fragmentation — may surface a tarantool-side gap)\n- TestWatchWithPrevKV (per-watcher prev-kv flag, distinct from WithPrevKV on Put/Delete)\n- TestWatchFromCompactedRevision (ErrCompacted returned on the stream, not as a typed gRPC status)","acceptance_criteria":"Each listed test ported, runs on all four cells, passes (or documented as a known gap with cross-reference).","notes":"Source: docs/TODO.md \"Open / Conformance matrix — Phase 5 option coverage\".","status":"open","priority":2,"issue_type":"task","owner":"bigbes@gmail.com","created_at":"2026-05-19T13:34:06Z","created_by":"Eugene Blikh","updated_at":"2026-05-19T13:34:06Z"}{"notes":"Source: docs/TODO.md \"Open / Conformance matrix — Phase 5 option coverage\".\n\nPriority note (TestWatchWithPrevKV): Tarantool EE uses etcd as a centralized-config backend (config.storage / etcd config source in TT 3.x). On boot it reads config from etcd and opens a Watch with prev_kv set to diff old-vs-new config on live reload. So Watch prev_kv is exercised by a first-class ecosystem consumer, not just the conformance suite — it should be treated as the highest-value test in this group for drop-in TT EE compatibility.\n\nImplementation already exists (feature built, conformance assertion missing):\n- app/etcd/watch.lua:83 lookup_prev_kv() walks kv_history backwards (LT on mod_revision) for the prior non-tombstone value\n- app/etcd/watch.lua:268 stores per-watcher flag; propagated via grpc.lua:358, json.lua:205, server.lua:185\n- auth.lua:317 requires READ perm when prev_kv requested\nRemaining work for prev_kv is the TestWatchWithPrevKV conformance case against real etcd 3.6, not the Lua implementation."}NULL2026-05-20T09:34:10Z
8ce5904b-3788-4480-95ba-f0419b7dae79tarantool-etcd-gz4createdEugene BlikhNULL2026-05-19T17:53:52Z
8d49ce84-20c5-4706-8147-6bd291eb742atarantool-etcd-6ljcreatedEugene BlikhNULL2026-05-19T17:53:56Z
8d9d43c2-3fde-477f-909e-6692642d0f7atarantool-etcd-wgxcreatedEugene BlikhNULL2026-05-19T17:54:05Z
91dd9f8a-46c8-4fa9-9990-b5ef64d21db8tarantool-etcd-0uscreatedEugene BlikhNULL2026-05-19T17:54:32Z
95dd1a81-ac4a-443e-9357-0231ae710df4tarantool-etcd-2alcreatedEugene BlikhNULL2026-05-19T17:54:10Z
9942c15d-10dd-4175-b258-d3eac38cbf68tarantool-etcd-sy6createdEugene BlikhNULL2026-05-19T17:53:56Z
999323d2-60cd-4dc1-a096-4e436ea35bc4tarantool-etcd-hx9createdEugene BlikhNULL2026-05-19T17:54:20Z
9d480c92-7d70-47cb-99dc-2aaaadf079adtarantool-etcd-cz5createdEugene BlikhNULL2026-05-19T17:54:41Z
a19c7caf-7c98-4289-86e0-3dd93b81e977tarantool-etcd-ag2createdEugene BlikhNULL2026-05-19T17:54:06Z
aa4111f8-1de1-43bc-a615-93586335d78btarantool-etcd-axscreatedEugene BlikhNULL2026-05-20T09:45:14Z
ad2500dc-5e99-4b7b-b828-7c7be8323f5btarantool-etcd-ak9createdEugene BlikhNULL2026-05-19T17:54:03Z
ae980e19-525b-489c-9824-5dddc5ed8dc9tarantool-etcd-2pacreatedEugene BlikhNULL2026-05-19T17:54:12Z
aedaf13b-63f5-424d-a0e6-6fe22cce2af7tarantool-etcd-q5fcreatedEugene BlikhNULL2026-05-20T09:45:16Z
b0e19218-53ed-4843-ba7d-4462da9c2ae1tarantool-etcd-8ssclosedEugene BlikhExample written and verified end-to-end on Tarantool EE 3.7.0.NULL2026-05-20T14:38:01Z
b159889e-8fec-4a8a-ab60-f55063a86e08tarantool-etcd-ovocreatedEugene BlikhNULL2026-05-20T09:45:16Z
b16d8be3-aaad-4f74-b1c3-d62ddb2be376tarantool-etcd-50gcreatedEugene BlikhNULL2026-05-19T17:54:19Z
b193168a-3a3c-47c0-89a7-049261d601b9tarantool-etcd-umccreatedEugene BlikhNULL2026-05-20T09:45:13Z
b33d558d-b27a-42be-9bcb-c54ff0af7049tarantool-etcd-1twcreatedEugene BlikhNULL2026-05-20T09:55:24Z
b6ab8af9-f3dc-48fe-b30c-223f9fe0fb59tarantool-etcd-w5rcreatedEugene BlikhNULL2026-05-19T17:54:43Z
b8e57f80-deb4-4d00-9e57-85ddef884982tarantool-etcd-0gnclaimedEugene Blikh{"id":"tarantool-etcd-0gn","title":"Implement Watch extras: filters, progress_notify (periodic), fragment","description":"WatchCreateRequest fields filters (NOPUT/NODELETE), progress_notify periodic notify, and fragment (large-response splitting) are declared in pb/defs.lua but ignored by create_watcher/grpc.lua/json.lua. On-demand RequestProgress already works. Implement the missing three.","status":"open","priority":2,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-05-20T06:35:53Z","created_by":"Eugene Blikh","updated_at":"2026-05-20T06:35:53Z"}{"assignee":"Eugene Blikh","status":"in_progress"}NULL2026-05-20T09:35:59Z
ba878427-f6e7-40e5-a96f-0a41c5357472tarantool-etcd-m1ncreatedEugene BlikhNULL2026-05-19T17:54:47Z
c1386207-32df-49c3-b25c-ee876836ea2ftarantool-etcd-buqcreatedEugene BlikhNULL2026-05-19T16:34:52Z
c6b02065-1911-4de5-8c58-703f1b1692a0tarantool-etcd-acpcreatedEugene BlikhNULL2026-05-19T17:53:51Z
cb892177-bcbc-4882-91f0-1785edb94ff0tarantool-etcd-070createdEugene BlikhNULL2026-05-19T17:53:57Z
ccedcf22-e6e2-405a-8858-3f9736f1fa40tarantool-etcd-jg3createdEugene BlikhNULL2026-05-20T09:17:53Z
cec28fbf-5a6f-4db7-b464-7e342c8db297tarantool-etcd-75ucreatedEugene BlikhNULL2026-05-20T09:17:55Z
d03951d3-60b2-45c7-840f-7d0341f72993tarantool-etcd-wqncreatedEugene BlikhNULL2026-05-19T17:54:30Z
d2e53a79-8623-4b49-bb6e-49bbf78e2cectarantool-etcd-584createdEugene BlikhNULL2026-05-19T17:53:53Z
d6b47667-9634-4546-8b96-39a6728f21ddtarantool-etcd-b08createdEugene BlikhNULL2026-05-19T16:34:09Z
daf8dd2b-bb5f-4961-8464-27cd5bddd3f5tarantool-etcd-3spupdatedEugene Blikh{"id":"tarantool-etcd-3sp","title":"LeaseKeepAlive fsyncs WAL on every renew","description":"On btrfs SSD bench (2026-05-19 disk run), LeaseKeepAlive/n_X drops from 4 234 ops/s (tmpfs) to 207 ops/s on tarantool while etcd holds at ~7 400 ops/s in both configs.\n\np50 goes from 224 µs (tmpfs) to 4 548 µs (disk) — exactly one btrfs fsync. Root cause at app/etcd/lease.lua:191:\n\n box.space.leases:update(id, {{'=', 'expiry_time', now + lease.ttl}})\n\nThe leases space is is_sync=true so every keep-alive does a full WAL append + fsync. Etcd's KeepAlive is an in-memory TTL bump with no disk write.\n\nFix sketch: split expiry into an in-memory map (refreshed on every KeepAlive) and persist only on grant/revoke. The expiry fiber should read from the in-memory map. Trade-off: leases may extend further into the future than the on-disk record after a crash, which is fine — clients have to re-keep-alive after reconnect anyway.\n\nSee docs/BENCH.md Linux x86_64 disk section (Open follow-ups).","status":"open","priority":2,"issue_type":"bug","owner":"bigbes@gmail.com","created_at":"2026-05-19T17:33:47Z","created_by":"Eugene Blikh","updated_at":"2026-05-19T17:33:47Z"}{"design":"GOAL: lease keep-alive must not touch the WAL. Mirror etcd's split — durable\nstate = {lease record, granted TTL, attached keys}; ephemeral leader-local\nstate = the expiry deadline (refreshed on every keep-alive, never persisted).\n\n=== STATE MODEL ===\nAdd a module-level in-memory map in app/etcd/lease.lua:\n local deadlines = {} -- [lease_id] = monotonic deadline (clock.monotonic()+ttl)\nThis is leader-local. Followers never keep-alive (the gRPC write gate routes\nLeaseKeepAlive to the leader), and only the leader runs the expiry fiber and\ncan revoke. So the countdown is structurally a leader concern.\n\nThe `leases` space (schema.lua:97-118) stays is_sync=true and keeps its\n{id, ttl, expiry_time, granted_ttl} format. The `expiry_time` FIELD and its\nTREE index (schema.lua:113) become vestigial — written once at grant, never\nthe source of liveness again. Leave them to avoid a space migration; an\noptional follow-up can drop the field+index. Nothing reads expiry_time after\nthis change.\n\n=== HANDLER CHANGES (app/etcd/lease.lua) ===\n1. grant() ~L70: after `box.space.leases:insert(...)`, seed\n `deadlines[id] = now + ttl`. Insert still persists (durable, required).\n2. keepalive() ~L191: REPLACE\n box.space.leases:update(id, {{'=', 'expiry_time', now + lease.ttl}})\n with\n deadlines[id] = clock.monotonic() + lease.ttl\n Keep the `box.space.leases:get(id)` existence check above it (cheap read,\n no fsync) — it supplies lease.ttl and preserves the NOT_FOUND-raises\n contract the gRPC stream handler depends on (see L169-171).\n3. revoke() ~L150: after `box.space.leases:delete(id)`, clear\n `deadlines[id] = nil`.\n4. time_to_live() ~L236: REPLACE `lease.expiry_time` read with `deadlines[id]`.\n If deadlines[id] is nil (lease loaded but not yet rebuilt), fall back to\n `clock.monotonic() + lease.granted_ttl`. remaining = max(0, floor(dl - now)).\n5. expiry_loop() L287-338: REPLACE the `box.space.leases.index.expiry_time`\n scan (L302-309) with a scan of `deadlines`: collect ids where\n `deadline \u003c= now`. Plain full-table scan is fine (numeric compares in Lua,\n runs every 500ms); a min-heap (etcd's leaseExpiredNotifier shape) is the\n optional optimization if lease counts get large. revoke() already nils the\n map entry on success.\n\n=== REBUILD ON PROMOTE ===\nAdd lease.M.rebuild_deadlines():\n clears `deadlines`, then for each tuple in box.space.leases:pairs() sets\n deadlines[tuple.id] = clock.monotonic() + tuple.ttl\nCall it in the RW branch of the box.watch('box.status', ...) callback in\napp/roles/etcd.lua (L341-353), immediately before lease.start_expiry().\nThis resets every inherited lease's deadline to a full-TTL grace period on the\nnew leader — exactly etcd's failover behavior.\n\n=== LATENT BUG THIS ALSO FIXES ===\nexpiry_time is currently computed as clock.monotonic()+ttl and REPLICATED.\nclock.monotonic() is process-local (relative to boot), so the persisted value\nis meaningless on any other node. Today a promoted replica's fiber scans\ninherited expiry_time values from a different monotonic timeline — could\nexpire leases instantly or never. Rebuild-on-promote with the new leader's own\nclock removes this entirely."}NULL2026-05-20T07:39:02Z
dcd911a2-525b-42a5-ba99-d233997fc980tarantool-etcd-kbccreatedEugene BlikhNULL2026-05-19T17:11:01Z
dd019f0d-8692-4c41-8f1b-bb1af4927659tarantool-etcd-8ssupdatedEugene Blikh{"id":"tarantool-etcd-8ss","title":"Example 2: 3-node EE replicaset self-hosting its own etcd config (file → etcd migration)","description":"Add examples/tarantool-ee-self-hosted-etcd: boot a 3-instance EE replicaset (election failover) from a local cluster-config.yaml where every node runs app.roles.etcd (replicated KV store, read_pref=any). Seed the cluster's OWN etcd store with that config, then rolling-restart each instance to bootstrap from TT_CONFIG_ETCD_* (no --config). Document the cold-boot circularity: self-hosted etcd-config is HA under rolling restart but needs the local file retained as a cold-boot seed. Justfile + README + cluster-config.yaml.","status":"in_progress","priority":2,"issue_type":"feature","assignee":"Eugene Blikh","owner":"bigbes@gmail.com","created_at":"2026-05-20T11:16:17Z","created_by":"Eugene Blikh","updated_at":"2026-05-20T11:16:28Z","started_at":"2026-05-20T11:16:28Z"}{"notes":"Files written + phases 1-2 (up-file/seed/probe/config-show) verified on Community Tarantool 3.8. Ports 3501-3503/2382-2482-2582 (distinct from example-1's 3401/2379). migrate+reload need an EE binary (config.etcd source) so were not run here; mechanics mirror the working tarantool-ee-config example. EE guard on migrate verified to fire."}NULL2026-05-20T14:22:44Z
df3a88fb-c2b8-4d6f-9361-b23f36715f46tarantool-etcd-1dkcreatedEugene BlikhNULL2026-05-20T09:55:21Z