mirror of
https://git.robbyzambito.me/zits
synced 2026-02-04 03:34:48 +00:00
Support queue groups
This commit is contained in:
@@ -26,6 +26,7 @@ pub const Subscription = struct {
|
|||||||
subject: []const u8,
|
subject: []const u8,
|
||||||
client_id: usize,
|
client_id: usize,
|
||||||
sid: []const u8,
|
sid: []const u8,
|
||||||
|
queue_group: ?[]const u8,
|
||||||
queue: *Queue(Msgs),
|
queue: *Queue(Msgs),
|
||||||
// used to alloc messages in the queue
|
// used to alloc messages in the queue
|
||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
@@ -33,6 +34,7 @@ pub const Subscription = struct {
|
|||||||
fn deinit(self: Subscription, alloc: Allocator) void {
|
fn deinit(self: Subscription, alloc: Allocator) void {
|
||||||
alloc.free(self.subject);
|
alloc.free(self.subject);
|
||||||
alloc.free(self.sid);
|
alloc.free(self.sid);
|
||||||
|
if (self.queue_group) |g| alloc.free(g);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -201,12 +203,12 @@ fn handleConnection(
|
|||||||
.PUB => |pb| {
|
.PUB => |pb| {
|
||||||
@branchHint(.likely);
|
@branchHint(.likely);
|
||||||
defer pb.deinit(server_allocator);
|
defer pb.deinit(server_allocator);
|
||||||
try server.publishMessage(io, &client, msg);
|
try server.publishMessage(io, server_allocator, &client, msg);
|
||||||
},
|
},
|
||||||
.HPUB => |hp| {
|
.HPUB => |hp| {
|
||||||
@branchHint(.likely);
|
@branchHint(.likely);
|
||||||
defer hp.deinit(server_allocator);
|
defer hp.deinit(server_allocator);
|
||||||
try server.publishMessage(io, &client, msg);
|
try server.publishMessage(io, server_allocator, &client, msg);
|
||||||
},
|
},
|
||||||
.SUB => |sub| {
|
.SUB => |sub| {
|
||||||
defer sub.deinit(server_allocator);
|
defer sub.deinit(server_allocator);
|
||||||
@@ -270,7 +272,13 @@ test subjectMatches {
|
|||||||
try expect(subjectMatches("foo.>", "foo.bar.baz"));
|
try expect(subjectMatches("foo.>", "foo.bar.baz"));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn publishMessage(server: *Server, io: Io, source_client: *Client, msg: Message) !void {
|
fn publishMessage(
|
||||||
|
server: *Server,
|
||||||
|
io: Io,
|
||||||
|
alloc: Allocator,
|
||||||
|
source_client: *Client,
|
||||||
|
msg: Message,
|
||||||
|
) !void {
|
||||||
defer if (source_client.connect) |c| {
|
defer if (source_client.connect) |c| {
|
||||||
if (c.verbose) {
|
if (c.verbose) {
|
||||||
source_client.send(io, .@"+OK") catch {};
|
source_client.send(io, .@"+OK") catch {};
|
||||||
@@ -284,8 +292,26 @@ fn publishMessage(server: *Server, io: Io, source_client: *Client, msg: Message)
|
|||||||
};
|
};
|
||||||
try server.subs_lock.lock(io);
|
try server.subs_lock.lock(io);
|
||||||
defer server.subs_lock.unlock(io);
|
defer server.subs_lock.unlock(io);
|
||||||
for (server.subscriptions.items) |subscription| {
|
var published_queue_groups: ArrayList([]const u8) = .empty;
|
||||||
|
defer published_queue_groups.deinit(alloc);
|
||||||
|
var published_queue_sub_idxs: ArrayList(usize) = .empty;
|
||||||
|
defer published_queue_sub_idxs.deinit(alloc);
|
||||||
|
|
||||||
|
subs: for (0..server.subscriptions.items.len) |i| {
|
||||||
|
const subscription = server.subscriptions.items[i];
|
||||||
if (subjectMatches(subscription.subject, subject)) {
|
if (subjectMatches(subscription.subject, subject)) {
|
||||||
|
if (subscription.queue_group) |sg| {
|
||||||
|
for (published_queue_groups.items) |g| {
|
||||||
|
if (eql(u8, g, sg)) {
|
||||||
|
continue :subs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Don't republish to the same queue
|
||||||
|
try published_queue_groups.append(alloc, sg);
|
||||||
|
// Move this index to the end of the subscription list,
|
||||||
|
// to prioritize other subscriptions in the queue next time.
|
||||||
|
try published_queue_sub_idxs.append(alloc, i);
|
||||||
|
}
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
.PUB => |pb| {
|
.PUB => |pb| {
|
||||||
try subscription.queue.putOne(io, .{
|
try subscription.queue.putOne(io, .{
|
||||||
@@ -301,6 +327,11 @@ fn publishMessage(server: *Server, io: Io, source_client: *Client, msg: Message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (0..published_queue_sub_idxs.items.len) |from_end| {
|
||||||
|
const i = published_queue_sub_idxs.items.len - from_end - 1;
|
||||||
|
server.subscriptions.appendAssumeCapacity(server.subscriptions.orderedRemove(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subscribe(
|
fn subscribe(
|
||||||
@@ -317,10 +348,13 @@ fn subscribe(
|
|||||||
errdefer gpa.free(subject);
|
errdefer gpa.free(subject);
|
||||||
const sid = try gpa.dupe(u8, msg.sid);
|
const sid = try gpa.dupe(u8, msg.sid);
|
||||||
errdefer gpa.free(sid);
|
errdefer gpa.free(sid);
|
||||||
|
const queue_group = if (msg.queue_group) |q| try gpa.dupe(u8, q) else null;
|
||||||
|
errdefer if (queue_group) |q| gpa.free(q);
|
||||||
try server.subscriptions.append(gpa, .{
|
try server.subscriptions.append(gpa, .{
|
||||||
.subject = subject,
|
.subject = subject,
|
||||||
.client_id = id,
|
.client_id = id,
|
||||||
.sid = sid,
|
.sid = sid,
|
||||||
|
.queue_group = queue_group,
|
||||||
.queue = client.msg_queue,
|
.queue = client.msg_queue,
|
||||||
.alloc = client.alloc,
|
.alloc = client.alloc,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user