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();
@ -111,15 +115,24 @@ test "nats.Subscription (async)" {
defer message.destroy(); defer message.destroy();
{ {
const count: u32 = 0; var closed: []const u8 = "test";
const subscription = try connection.subscribe(*const u32, message_subject, onMessage, &count); {
defer subscription.destroy(); const count: u32 = 0;
const subscription = try connection.subscribe(*const u32, message_subject, onMessage, &count);
defer subscription.destroy();
const response = try connection.requestMessage(message, 1000); try subscription.setCompletionCallback(*[]const u8, onClose, &closed);
try std.testing.expectEqualStrings(
"greetings", const response = try connection.requestMessage(message, 1000);
response.getData() orelse return error.TestUnexpectedResult, try std.testing.expectEqualStrings(
); "greetings",
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);
} }
{ {