subscription: fix setCompletionCallback

This was not being tested, and it was really broken. Now it is being
tested and it is no longer broken.
This commit is contained in:
torque 2024-04-06 15:23:13 -07:00
parent 73fccb4662
commit 7db55e9ac9
Signed by: torque
SSH Key Fingerprint: SHA256:nCrXefBNo6EbjNSQhv0nXmEg/VuNq3sMF5b8zETw3Tk
3 changed files with 25 additions and 12 deletions

View File

@ -174,12 +174,12 @@ pub const Subscription = opaque {
self: *Subscription, self: *Subscription,
comptime T: type, comptime T: type,
comptime callback: *const thunk.SimpleCallbackThunkSignature(T), comptime callback: *const thunk.SimpleCallbackThunkSignature(T),
userdata: *T, userdata: T,
) Error!void { ) Error!void {
return Status.fromInt(nats_c.natsSubscription_SetOnCompleteCB( return Status.fromInt(nats_c.natsSubscription_SetOnCompleteCB(
@ptrCast(self), @ptrCast(self),
thunk.makeSimpleCallbackThunk(callback), thunk.makeSimpleCallbackThunk(T, callback),
@constCast(userdata), @constCast(@ptrCast(userdata)),
)).raise(); )).raise();
} }
}; };

View File

@ -57,7 +57,7 @@ pub fn makeSimpleCallbackThunk(
comptime checkUserDataType(T); comptime checkUserDataType(T);
return struct { return struct {
fn thunk(userdata: ?*anyopaque) callconv(.C) void { fn thunk(userdata: ?*anyopaque) callconv(.C) void {
const data: *T = if (userdata) |u| @alignCast(@ptrCast(u)) else unreachable; const data: T = if (userdata) |u| @alignCast(@ptrCast(u)) else unreachable;
callback(data); callback(data);
} }
}.thunk; }.thunk;

View File

@ -93,6 +93,10 @@ fn onMessage(
} else @panic("HOW"); } else @panic("HOW");
} }
fn onClose(userdata: *[]const u8) void {
userdata.* = "closed";
}
test "nats.Subscription (async)" { test "nats.Subscription (async)" {
var server = try util.TestServer.launch(.{}); var server = try util.TestServer.launch(.{});
defer server.stop(); defer server.stop();
@ -110,17 +114,26 @@ test "nats.Subscription (async)" {
const message = try nats.Message.create(message_subject, message_reply, message_data); const message = try nats.Message.create(message_subject, message_reply, message_data);
defer message.destroy(); defer message.destroy();
{
var closed: []const u8 = "test";
{ {
const count: u32 = 0; const count: u32 = 0;
const subscription = try connection.subscribe(*const u32, message_subject, onMessage, &count); const subscription = try connection.subscribe(*const u32, message_subject, onMessage, &count);
defer subscription.destroy(); defer subscription.destroy();
try subscription.setCompletionCallback(*[]const u8, onClose, &closed);
const response = try connection.requestMessage(message, 1000); const response = try connection.requestMessage(message, 1000);
try std.testing.expectEqualStrings( try std.testing.expectEqualStrings(
"greetings", "greetings",
response.getData() orelse return error.TestUnexpectedResult, response.getData() orelse return error.TestUnexpectedResult,
); );
} }
// we have to sleep to allow the close callback to run. I am worried this may
// still end up being flaky, however.
nats.sleep(1);
try std.testing.expectEqualStrings("closed", closed);
}
{ {
const count: u32 = 0; const count: u32 = 0;