-
Notifications
You must be signed in to change notification settings - Fork 1
Basic JetStream API support #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
372d074
436def8
aa2fc1e
3ee8278
42652ff
48b8bed
f4a5df0
f06196b
1dd1b8c
be8806e
ca037e0
335367e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,120 @@ | ||||||||||||||||||||||
| const std = @import("std"); | ||||||||||||||||||||||
| const Message = @import("message.zig").Message; | ||||||||||||||||||||||
| const Connection = @import("connection.zig").Connection; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const log = std.log.scoped(.jetstream); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const default_api_prefix = "$JS.API."; | ||||||||||||||||||||||
| const default_request_timeout_ms = 5000; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const ErrorResponse = struct { | ||||||||||||||||||||||
| @"error": ?struct { | ||||||||||||||||||||||
| /// HTTP like error code in the 300 to 500 range | ||||||||||||||||||||||
| code: u16, | ||||||||||||||||||||||
| /// A human friendly description of the error | ||||||||||||||||||||||
| description: []const u8 = "", | ||||||||||||||||||||||
| /// The NATS error code unique to each kind of error | ||||||||||||||||||||||
| err_code: u16 = 0, | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const AccountInfoResponse = struct { | ||||||||||||||||||||||
| /// Memory Storage being used for Stream Message storage | ||||||||||||||||||||||
| memory: u64, | ||||||||||||||||||||||
| /// File Storage being used for Stream Message storage | ||||||||||||||||||||||
| storage: u64, | ||||||||||||||||||||||
| // Number of active Streams | ||||||||||||||||||||||
| streams: u32, | ||||||||||||||||||||||
| /// Number of active Consumers | ||||||||||||||||||||||
| consumers: u32, | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Response from $JS.API.STREAM.NAMES | ||||||||||||||||||||||
| const StreamNamesResponse = struct { | ||||||||||||||||||||||
| total: u64, | ||||||||||||||||||||||
| offset: u64, | ||||||||||||||||||||||
| limit: u64, | ||||||||||||||||||||||
| streams: ?[]const []const u8, | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| pub const JetStreamOptions = struct { | ||||||||||||||||||||||
| request_timeout_ms: u64 = default_request_timeout_ms, | ||||||||||||||||||||||
| // Add options here | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| pub const Result = std.json.Parsed; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| pub const JetStream = struct { | ||||||||||||||||||||||
| allocator: std.mem.Allocator, | ||||||||||||||||||||||
| nc: *Connection, | ||||||||||||||||||||||
| opts: JetStreamOptions, | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| pub fn init(allocator: std.mem.Allocator, nc: *Connection, options: JetStreamOptions) JetStream { | ||||||||||||||||||||||
| return .{ | ||||||||||||||||||||||
| .allocator = allocator, | ||||||||||||||||||||||
| .nc = nc, | ||||||||||||||||||||||
| .opts = options, | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| pub fn deinit(self: *JetStream) void { | ||||||||||||||||||||||
| _ = self; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| fn sendRequest(self: *JetStream, comptime method: []const u8, payload: []const u8) !*Message { | ||||||||||||||||||||||
| return try self.nc.request(default_api_prefix ++ method, payload, self.opts.request_timeout_ms) orelse { | ||||||||||||||||||||||
| return error.NoResponse; | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
||||||||||||||||||||||
| fn sendRequest(self: *JetStream, comptime method: []const u8, payload: []const u8) !*Message { | |
| return try self.nc.request(default_api_prefix ++ method, payload, self.opts.request_timeout_ms) orelse { | |
| return error.NoResponse; | |
| }; | |
| } | |
| fn sendRequest(self: *JetStream, comptime method: []const u8, payload: []const u8) !*Message { | |
| const msg = try self.nc.request(default_api_prefix ++ method, payload, self.opts.request_timeout_ms) | |
| orelse return JetStreamError.NoResponse; | |
| return msg; | |
| } |
🤖 Prompt for AI Agents
In src/jetstream.zig around lines 64 to 68, the function currently returns the
anonymous error.NoResponse; change it to return the exported
JetStreamError.NoResponse instead for consistent public error handling. Modify
the orelse branch to return JetStreamError.NoResponse (ensure JetStreamError is
in scope or fully qualify it) so callers can match against the public error set.
lalinsky marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assertion is incorrect for paginated responses; will fail with valid server data.
total is the total number of streams across all pages, whereas streams.len is the count on the current page. On page 1 of N, total != streams.len.
Change the assertion to reflect the documented invariant: offset + streams.len <= total. Or drop the assert until pagination is implemented.
Apply this diff:
- std.debug.assert(page_result.value.total == streams.len);
+ std.debug.assert(page_result.value.offset + streams.len <= page_result.value.total);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // TODO: handle pagination | |
| const streams = page_result.value.streams orelse &[_][]const u8{}; | |
| std.debug.assert(page_result.value.total == streams.len); | |
| // TODO: handle pagination | |
| const streams = page_result.value.streams orelse &[_][]const u8{}; | |
| std.debug.assert(page_result.value.offset + streams.len <= page_result.value.total); |
🤖 Prompt for AI Agents
In src/jetstream.zig around lines 110 to 113, the assertion compares
page_result.value.total to streams.len which is wrong for paginated responses;
replace it with an assertion that enforces the documented invariant using the
page offset (e.g. page_result.value.offset + streams.len <=
page_result.value.total) or simply remove the assertion until pagination is
implemented so valid multi-page responses won't fail.
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -12,6 +12,16 @@ pub const ServerPool = @import("server_pool.zig").ServerPool; | |||
| pub const Server = @import("server_pool.zig").Server; | ||||
| pub const inbox = @import("inbox.zig"); | ||||
|
|
||||
| // JetStream types | ||||
| pub const JetStream = @import("jetstream.zig").JetStream; | ||||
| pub const JetStreamOptions = @import("jetstream.zig").JetStreamOptions; | ||||
| pub const StreamConfig = @import("jetstream.zig").StreamConfig; | ||||
| pub const StreamInfo = @import("jetstream.zig").StreamInfo; | ||||
| pub const Stream = @import("jetstream.zig").Stream; | ||||
| pub const PubAck = @import("jetstream.zig").PubAck; | ||||
| pub const AccountInfo = @import("jetstream.zig").AccountInfo; | ||||
| pub const JetStreamError = @import("jetstream.zig").JetStreamError; | ||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Broken re-export: JetStreamError is not defined in jetstream.zig. This will not compile as Apply this minimal fix (option A: remove the re-export for now): - pub const JetStreamError = @import("jetstream.zig").JetStreamError;Alternatively (option B: preferred), add and export a concrete error set from 📝 Committable suggestion
Suggested change
|
||||
|
|
||||
| // Removed top-level connect functions - use Connection.init() and Connection.connect() directly | ||||
|
|
||||
| // Test basic functionality | ||||
|
|
||||
Uh oh!
There was an error while loading. Please reload this page.