Skip to content

Commit 482ccd3

Browse files
committed
Add primary node discovery
Early versions of tests always first node as a primary in a cluster. With automated leader election leader can be on any node in clustera, so discovery of primary instance has been added. It consists of SQL function `_LEADER()` implemented in Lua, ``` unix/:/var/run/tarantool/jepsen.control> box.execute([[SELECT _LEADER()]]) --- - metadata: - name: COLUMN_1 type: string rows: - ['89.208.84.154'] ... ``` `primary` function that connects to desired node and gets IP address of primary instance using `_LEADER()` function and `primaries` function that gather information about primaries on every node in a cluster. Closes #34 Closes #16 (kill) Closes #17 (partition) Closes #21 (pause)
1 parent 219b347 commit 482ccd3

File tree

4 files changed

+69
-2
lines changed

4 files changed

+69
-2
lines changed

resources/tarantool/jepsen.lua

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ single_mode = %TARANTOOL_SINGLE_MODE%
22

33
if single_mode then
44
box.cfg {
5-
listen = 3301;
5+
listen = '%TARANTOOL_IP_ADDRESS%:3301';
66
log_level = 6;
77
log_nonblock = false;
88
too_long_threshold = 0.5;
@@ -12,7 +12,7 @@ box.cfg {
1212
}
1313
else
1414
box.cfg {
15-
listen = 3301;
15+
listen = '%TARANTOOL_IP_ADDRESS%:3301';
1616
replication = { %TARANTOOL_REPLICATION% };
1717
read_only = %TARANTOOL_IS_READ_ONLY%;
1818
replication_synchro_quorum = 2;
@@ -76,6 +76,31 @@ box.schema.func.create('_UPSERT',
7676
param_list = {'integer', 'integer', 'string'},
7777
exports = {'LUA', 'SQL'},
7878
is_deterministic = true})
79+
80+
--[[ Function returns IP address of a node where current leader
81+
of synchronous cluster with enabled Raft consensus protocol is started.
82+
Returns nil when Raft is disabled. Example: SELECT _LEADER()
83+
]]
84+
box.schema.func.create('_LEADER',
85+
{language = 'LUA',
86+
returns = 'string',
87+
body = [[function()
88+
local leader_id = box.info.election.leader
89+
if leader_id == 0 or leader_id == nil then
90+
return nil
91+
end
92+
local leader_upstream = box.info.replication[leader_id].upstream
93+
if leader_upstream == nil then
94+
return string.match(box.info.listen, '(.+):[0-9]+')
95+
end
96+
local leader_ip_address = string.match(leader_upstream.peer, '[A-z]+@(.+):[0-9]+')
97+
98+
return leader_ip_address
99+
end]],
100+
is_sandboxed = false,
101+
param_list = {},
102+
exports = {'LUA', 'SQL'},
103+
is_deterministic = true})
79104
end
80105

81106
box.once('jepsen', bootstrap)

src/tarantool/client.clj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
(:require [clojure.string :as str]
44
[clojure.tools.logging :refer [info warn]]
55
[next.jdbc :as j]
6+
[next.jdbc.sql :as sql]
67
[dom-top.core :as dt]
78
[next.jdbc.connection :as connection]))
89

@@ -56,6 +57,13 @@
5657
(info :caught-cause (.cause (:rollback (ex-data e#))))
5758
(throw e#))))))
5859

60+
(defn primary
61+
[node]
62+
(let [conn (open node test)
63+
leader (:COLUMN_1 (first (sql/query conn ["SELECT _LEADER()"])))]
64+
;(assert leader)
65+
leader))
66+
5967
(defmacro with-txn-aborts
6068
"Aborts body on rollbacks."
6169
[op & body]

src/tarantool/db.clj

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
[clojure.java.io :as io]
55
[next.jdbc :as j]
66
[next.jdbc.connection :as connection]
7+
[tarantool.client :as cl]
78
[jepsen.os.debian :as debian]
89
[jepsen.control.util :as cu]
910
[jepsen [core :as jepsen]
@@ -203,6 +204,16 @@
203204
(= n 1) true
204205
:else false)))
205206

207+
(defn primaries
208+
"Return a seq of primaries in a cluster."
209+
[test]
210+
(if (= 1 (count (:nodes test)))
211+
(:nodes test)
212+
(->> (pmap cl/primary (:nodes test))
213+
(set)
214+
(into [])
215+
(remove nil?))))
216+
206217
(defn configure!
207218
"Configure instance"
208219
[test node]
@@ -212,6 +223,7 @@
212223
(c/exec :mkdir :-p "/etc/tarantool/instances.enabled")
213224
(c/exec :usermod :-a :-G :tarantool :ubuntu)
214225
(c/exec :echo (-> "tarantool/jepsen.lua" io/resource slurp
226+
(str/replace #"%TARANTOOL_IP_ADDRESS%" node)
215227
(str/replace #"%TARANTOOL_REPLICATION%" (replica-set test))
216228
(str/replace #"%TARANTOOL_IS_READ_ONLY%" (boolean-to-str read-only))
217229
(str/replace #"%TARANTOOL_MVCC%" (boolean-to-str (:mvcc test)))
@@ -247,6 +259,27 @@
247259
(stop! test node)
248260
(wipe! test node))
249261

262+
db/Primary
263+
(setup-primary! [_ test node])
264+
265+
(primaries [_ test]
266+
(primaries test))
267+
268+
db/Process
269+
(start! [_ test node]
270+
(c/su
271+
(info node :starting :tarantool)
272+
(start! test node)))
273+
274+
(kill! [_ test node]
275+
(c/su
276+
(info node :stopping :tarantool)
277+
(stop! test node)))
278+
279+
db/Pause
280+
(pause! [_ test node] (c/su (cu/grepkill! :stop "tarantool")))
281+
(resume! [_ test node] (c/su (cu/grepkill! :cont "tarantool")))
282+
250283
db/LogFiles
251284
(log-files [_ test node]
252285
[logfile])))

src/tarantool/register.clj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
(setup! [this test node]
3838
(let [conn (cl/open node test)]
3939
(assert conn)
40+
(info (cl/primary node))
4041
(if (= node (jepsen/primary test))
4142
(cl/with-conn-failure-retry conn
4243
(j/execute! conn [(str "CREATE TABLE IF NOT EXISTS " table-name

0 commit comments

Comments
 (0)