Fix/nodebara compatibility (#2)
This commit is contained in:
@@ -244,6 +244,8 @@ class Client {
|
||||
this.requestId = 0;
|
||||
this._buffer = Buffer.alloc(0);
|
||||
this._pendingResolve = null;
|
||||
this._requestQueue = [];
|
||||
this._requestLock = false;
|
||||
}
|
||||
|
||||
async connect() {
|
||||
@@ -478,8 +480,31 @@ class Client {
|
||||
throw new Error(`Unexpected auth response: 0x${header.kind.toString(16)}`);
|
||||
}
|
||||
|
||||
async _processQueue() {
|
||||
if (this._requestLock || this._requestQueue.length === 0) return;
|
||||
this._requestLock = true;
|
||||
const { task, resolve, reject } = this._requestQueue.shift();
|
||||
try {
|
||||
const result = await task();
|
||||
resolve(result);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
} finally {
|
||||
this._requestLock = false;
|
||||
setImmediate(() => this._processQueue());
|
||||
}
|
||||
}
|
||||
|
||||
_enqueue(task) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._requestQueue.push({ task, resolve, reject });
|
||||
this._processQueue();
|
||||
});
|
||||
}
|
||||
|
||||
async ping() {
|
||||
if (!this.connected) throw new Error('Not connected');
|
||||
return this._enqueue(async () => {
|
||||
const msg = this._build(MsgKind.PING, Buffer.alloc(0));
|
||||
this.socket.write(msg);
|
||||
|
||||
@@ -487,10 +512,12 @@ class Client {
|
||||
if (header.kind === MsgKind.PONG) return true;
|
||||
if (header.kind === MsgKind.ERROR) throw await this._readError(header.length);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
async query(sql) {
|
||||
if (!this.connected) throw new Error('Not connected');
|
||||
return this._enqueue(async () => {
|
||||
const queryBuf = Buffer.from(sql, 'utf-8');
|
||||
const payload = Buffer.alloc(4 + queryBuf.length + 1);
|
||||
payload.writeUInt32BE(queryBuf.length, 0);
|
||||
@@ -510,10 +537,12 @@ class Client {
|
||||
return result;
|
||||
}
|
||||
return new QueryResult();
|
||||
});
|
||||
}
|
||||
|
||||
async queryParams(sql, params = []) {
|
||||
if (!this.connected) throw new Error('Not connected');
|
||||
return this._enqueue(async () => {
|
||||
const queryBuf = Buffer.from(sql, 'utf-8');
|
||||
const paramParts = [];
|
||||
for (const p of params) {
|
||||
@@ -542,6 +571,7 @@ class Client {
|
||||
return result;
|
||||
}
|
||||
return new QueryResult();
|
||||
});
|
||||
}
|
||||
|
||||
async execute(sql) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import std/random
|
||||
import std/monotimes
|
||||
import std/asyncdispatch
|
||||
import std/net
|
||||
import std/asyncnet
|
||||
import std/strutils
|
||||
import std/streams
|
||||
import std/os
|
||||
@@ -36,7 +37,7 @@ type
|
||||
fanout*: int # number of nodes to gossip to per round
|
||||
gossipPort*: int
|
||||
running*: bool
|
||||
sock*: Socket
|
||||
sock*: AsyncSocket
|
||||
onJoin*: proc(node: GossipNode) {.gcsafe.}
|
||||
onLeave*: proc(nodeId: string) {.gcsafe.}
|
||||
onSuspect*: proc(nodeId: string) {.gcsafe.}
|
||||
@@ -305,25 +306,21 @@ proc startGossipRound*(gp: GossipProtocol, intervalMs: int = 2000) {.async.} =
|
||||
gp.broadcastGossip()
|
||||
|
||||
proc startGossipListener*(gp: GossipProtocol) {.async.} =
|
||||
gp.sock = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
||||
gp.sock = newAsyncSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
||||
gp.sock.setSockOpt(OptReuseAddr, true)
|
||||
gp.sock.bindAddr(Port(gp.gossipPort))
|
||||
gp.running = true
|
||||
while gp.running:
|
||||
try:
|
||||
var data = newString(65535)
|
||||
var senderAddr = ""
|
||||
var senderPort: Port
|
||||
let bytesRead = gp.sock.recvFrom(data, 65535, senderAddr, senderPort)
|
||||
if bytesRead > 0:
|
||||
data.setLen(bytesRead)
|
||||
let (data, senderAddr, senderPort) = await gp.sock.recvFrom(65535)
|
||||
if data.len > 0:
|
||||
gp.handleIncomingGossip(data, senderAddr)
|
||||
except:
|
||||
# Small sleep on error to avoid spin
|
||||
gp.sock.close()
|
||||
# Recreate socket for next iteration
|
||||
try:
|
||||
gp.sock = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
||||
gp.sock = newAsyncSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
||||
gp.sock.setSockOpt(OptReuseAddr, true)
|
||||
gp.sock.bindAddr(Port(gp.gossipPort))
|
||||
except:
|
||||
|
||||
@@ -169,12 +169,14 @@ proc serializeValue*(buf: var seq[byte], val: WireValue) =
|
||||
of fkFloat32:
|
||||
var fl = val.float32Val
|
||||
var bytes: array[4, byte]
|
||||
copyMem(addr bytes, unsafeAddr fl, 4)
|
||||
var i32 = cast[int32](fl)
|
||||
bigEndian32(addr bytes, unsafeAddr i32)
|
||||
buf.add(bytes)
|
||||
of fkFloat64:
|
||||
var fl = val.float64Val
|
||||
var bytes: array[8, byte]
|
||||
copyMem(addr bytes, unsafeAddr fl, 8)
|
||||
var i64 = cast[int64](fl)
|
||||
bigEndian64(addr bytes, unsafeAddr i64)
|
||||
buf.add(bytes)
|
||||
of fkString: buf.writeString(val.strVal)
|
||||
of fkBytes: buf.writeBytes(val.bytesVal)
|
||||
@@ -192,7 +194,8 @@ proc serializeValue*(buf: var seq[byte], val: WireValue) =
|
||||
for f in val.vecVal:
|
||||
var fl = f
|
||||
var bytes: array[4, byte]
|
||||
copyMem(addr bytes, unsafeAddr fl, 4)
|
||||
var i32 = cast[int32](fl)
|
||||
bigEndian32(addr bytes, unsafeAddr i32)
|
||||
buf.add(bytes)
|
||||
of fkJson:
|
||||
buf.writeString(val.jsonVal)
|
||||
@@ -227,14 +230,18 @@ proc deserializeValue*(buf: openArray[byte], pos: var int, depth: int = 0): Wire
|
||||
var fl: float32
|
||||
var bytes: array[4, byte]
|
||||
for i in 0..3: bytes[i] = buf[pos + i]
|
||||
copyMem(addr fl, unsafeAddr bytes, 4)
|
||||
var i32: int32
|
||||
bigEndian32(addr i32, unsafeAddr bytes)
|
||||
fl = cast[float32](i32)
|
||||
pos += 4
|
||||
result = WireValue(kind: fkFloat32, float32Val: fl)
|
||||
of fkFloat64:
|
||||
var fl: float64
|
||||
var bytes: array[8, byte]
|
||||
for i in 0..7: bytes[i] = buf[pos + i]
|
||||
copyMem(addr fl, unsafeAddr bytes, 8)
|
||||
var i64: int64
|
||||
bigEndian64(addr i64, unsafeAddr bytes)
|
||||
fl = cast[float64](i64)
|
||||
pos += 8
|
||||
result = WireValue(kind: fkFloat64, float64Val: fl)
|
||||
of fkString:
|
||||
@@ -270,7 +277,9 @@ proc deserializeValue*(buf: openArray[byte], pos: var int, depth: int = 0): Wire
|
||||
var fl: float32
|
||||
var bytes: array[4, byte]
|
||||
for j in 0..3: bytes[j] = buf[pos + j]
|
||||
copyMem(addr fl, unsafeAddr bytes, 4)
|
||||
var i32: int32
|
||||
bigEndian32(addr i32, unsafeAddr bytes)
|
||||
fl = cast[float32](i32)
|
||||
pos += 4
|
||||
vec.add(fl)
|
||||
result = WireValue(kind: fkVector, vecVal: vec)
|
||||
|
||||
Reference in New Issue
Block a user