refactor: improve redis client and publisher

- Refactor the redis client to use a mutex for thread safety.
- Improve error handling in context and playbook factory.
- Remove the play_mdbook command and associated tests.
- Add play_publisher command and tests for publishing books.
- Update the repository cache to use a reference to the redis client.

Co-authored-by: mahmmoud.hassanein <mahmmoud.hassanein@gmail.com>
This commit is contained in:
2025-01-13 16:52:21 +02:00
parent da2881f973
commit 91f8520229
15 changed files with 478 additions and 244 deletions

View File

@@ -3,11 +3,11 @@ module redisclient
// original code see https://github.com/patrickpissurno/vredis/blob/master/vredis_test.v
// credits see there as well (-:
import net
// import sync
import sync
// import strconv
__global (
redis_connections []Redis
redis_connections []&Redis
)
const default_read_timeout = net.infinite_timeout
@@ -18,15 +18,16 @@ pub:
addr string
mut:
socket net.TcpConn
mtx sync.RwMutex
}
// https://redis.io/topics/protocol
// examples:
// localhost:6379
// /tmp/redis-default.sock
pub fn new(addr string) !Redis {
// lock redis_connections {
for mut conn in redis_connections {
pub fn new(addr string) !&Redis {
// lock redis_cowritennections {
for conn in redis_connections {
if conn.addr == addr {
return conn
}
@@ -34,10 +35,13 @@ pub fn new(addr string) !Redis {
// means there is no connection yet
mut r := Redis{
addr: addr
mtx: sync.RwMutex{}
}
r.mtx.init()
r.socket_connect()!
redis_connections << r
return r
redis_connections << &r
return &r
//}
// panic("bug")
}
@@ -47,7 +51,7 @@ pub fn reset() ! {
for mut conn in redis_connections {
conn.disconnect()
}
redis_connections = []Redis{}
redis_connections = []&Redis{}
//}
}

View File

@@ -18,7 +18,7 @@ pub fn get_redis_url(url string) !RedisURL {
}
}
pub fn core_get(url RedisURL) !Redis {
pub fn core_get(url RedisURL) !&Redis {
mut r := new('${url.address}:${url.port}')!
return r
}

View File

@@ -2,7 +2,7 @@ module redisclient
import freeflowuniverse.herolib.data.resp
pub fn (mut r Redis) get_response() !resp.RValue {
fn (mut r Redis) get_response() !resp.RValue {
line := r.read_line()!
if line.starts_with('-') {
@@ -63,7 +63,7 @@ pub fn (mut r Redis) get_response() !resp.RValue {
// TODO: needs to use the resp library
pub fn (mut r Redis) get_int() !int {
fn (mut r Redis) get_int() !int {
line := r.read_line()!
if line.starts_with(':') {
return line[1..].int()
@@ -72,7 +72,7 @@ pub fn (mut r Redis) get_int() !int {
}
}
pub fn (mut r Redis) get_list_int() ![]int {
fn (mut r Redis) get_list_int() ![]int {
line := r.read_line()!
mut res := []int{}
@@ -89,7 +89,7 @@ pub fn (mut r Redis) get_list_int() ![]int {
}
}
pub fn (mut r Redis) get_list_str() ![]string {
fn (mut r Redis) get_list_str() ![]string {
line := r.read_line()!
mut res := []string{}
@@ -106,7 +106,7 @@ pub fn (mut r Redis) get_list_str() ![]string {
}
}
pub fn (mut r Redis) get_string() !string {
fn (mut r Redis) get_string() !string {
line := r.read_line()!
if line.starts_with('+') {
// console.print_debug("getstring:'${line[1..]}'")
@@ -120,12 +120,12 @@ pub fn (mut r Redis) get_string() !string {
}
}
pub fn (mut r Redis) get_string_nil() !string {
fn (mut r Redis) get_string_nil() !string {
r2 := r.get_bytes_nil()!
return r2.bytestr()
}
pub fn (mut r Redis) get_bytes_nil() ![]u8 {
fn (mut r Redis) get_bytes_nil() ![]u8 {
line := r.read_line()!
if line.starts_with('+') {
return line[1..].bytes()
@@ -140,12 +140,12 @@ pub fn (mut r Redis) get_bytes_nil() ![]u8 {
}
}
pub fn (mut r Redis) get_bool() !bool {
fn (mut r Redis) get_bool() !bool {
i := r.get_int()!
return i == 1
}
pub fn (mut r Redis) get_bytes() ![]u8 {
fn (mut r Redis) get_bytes() ![]u8 {
line := r.read_line()!
if line.starts_with('$') {
return r.get_bytes_from_line(line)

View File

@@ -53,7 +53,7 @@ fn (mut r Redis) socket_check() ! {
}
}
pub fn (mut r Redis) read_line() !string {
fn (mut r Redis) read_line() !string {
return r.socket.read_line().trim_right('\r\n')
}
@@ -99,7 +99,7 @@ fn (mut r Redis) write_line(data []u8) ! {
}
// write resp value to the redis channel
pub fn (mut r Redis) write_rval(val resp.RValue) ! {
fn (mut r Redis) write_rval(val resp.RValue) ! {
r.write(val.encode())!
}

View File

@@ -5,6 +5,10 @@ import freeflowuniverse.herolib.ui.console
// send list of strings, expect OK back
pub fn (mut r Redis) send_expect_ok(items []string) ! {
r.mtx.lock()
defer {
r.mtx.unlock()
}
r.write_cmds(items)!
res := r.get_string()!
if res != 'OK' {
@@ -15,23 +19,39 @@ pub fn (mut r Redis) send_expect_ok(items []string) ! {
// send list of strings, expect int back
pub fn (mut r Redis) send_expect_int(items []string) !int {
r.mtx.lock()
defer {
r.mtx.unlock()
}
r.write_cmds(items)!
return r.get_int()
}
pub fn (mut r Redis) send_expect_bool(items []string) !bool {
r.mtx.lock()
defer {
r.mtx.unlock()
}
r.write_cmds(items)!
return r.get_bool()
}
// send list of strings, expect string back
pub fn (mut r Redis) send_expect_str(items []string) !string {
r.mtx.lock()
defer {
r.mtx.unlock()
}
r.write_cmds(items)!
return r.get_string()
}
// send list of strings, expect string or nil back
pub fn (mut r Redis) send_expect_strnil(items []string) !string {
r.mtx.lock()
defer {
r.mtx.unlock()
}
r.write_cmds(items)!
d := r.get_string_nil()!
return d
@@ -39,16 +59,28 @@ pub fn (mut r Redis) send_expect_strnil(items []string) !string {
// send list of strings, expect list of strings back
pub fn (mut r Redis) send_expect_list_str(items []string) ![]string {
r.mtx.lock()
defer {
r.mtx.unlock()
}
r.write_cmds(items)!
return r.get_list_str()
}
pub fn (mut r Redis) send_expect_list_int(items []string) ![]int {
r.mtx.lock()
defer {
r.mtx.unlock()
}
r.write_cmds(items)!
return r.get_list_int()
}
pub fn (mut r Redis) send_expect_list(items []string) ![]resp.RValue {
r.mtx.lock()
defer {
r.mtx.unlock()
}
r.write_cmds(items)!
res := r.get_response()!
return resp.get_redis_array(res)