async: remove useless http.zig

Replace it with a tested sample implementation
This commit is contained in:
Pierre Tachoire
2024-01-31 09:58:16 +01:00
parent 2b79a65d6d
commit af20584ff2
2 changed files with 76 additions and 81 deletions

View File

@@ -1,74 +0,0 @@
const std = @import("std");
const http = std.http;
const stdcli = @import("Client.zig");
pub const Loop = @import("jsruntime").Loop;
const YieldImpl = Loop.Yield(Request);
pub const Client = struct {
cli: stdcli,
pub fn init(alloc: std.mem.Allocator, loop: *Loop) Client {
return .{
.cli = .{
.allocator = alloc,
.loop = loop,
},
};
}
pub fn deinit(self: *Client) void {
self.cli.deinit();
}
pub fn create(self: *Client, uri: std.Uri) !*Request {
var req = try self.cli.allocator.create(Request);
req.* = Request{
.impl = undefined,
.cli = &self.cli,
.uri = uri,
.headers = .{ .allocator = self.cli.allocator, .owned = false },
};
req.impl = YieldImpl.init(self.cli.loop, req);
return req;
}
};
pub const Request = struct {
cli: *stdcli,
uri: std.Uri,
headers: std.http.Headers,
impl: YieldImpl,
done: bool = false,
err: ?anyerror = null,
pub fn deinit(self: *Request) void {
self.headers.deinit();
self.cli.allocator.destroy(self);
}
pub fn fetch(self: *Request) void {
return self.impl.yield();
}
fn onerr(self: *Request, err: anyerror) void {
self.err = err;
}
pub fn onYield(self: *Request, err: ?anyerror) void {
defer self.done = true;
if (err) |e| return self.onerr(e);
var req = self.cli.open(.GET, self.uri, self.headers, .{}) catch |e| return self.onerr(e);
defer req.deinit();
req.send(.{}) catch |e| return self.onerr(e);
req.finish() catch |e| return self.onerr(e);
req.wait() catch |e| return self.onerr(e);
}
pub fn wait(self: *Request) !void {
while (!self.done) try self.impl.tick();
if (self.err) |err| return err;
}
};

View File

@@ -1,8 +1,7 @@
const std = @import("std");
const http = std.http;
const StdClient = @import("Client.zig");
const AsyncClient = @import("http.zig").Client;
const AsyncRequest = @import("http.zig").Request;
const Client = @import("Client.zig");
const Request = @import("Client.zig").Request;
pub const Loop = @import("jsruntime").Loop;
@@ -16,7 +15,7 @@ test "blocking mode fetch API" {
var loop = try Loop.init(alloc);
defer loop.deinit();
var client: StdClient = .{
var client: Client = .{
.allocator = alloc,
.loop = &loop,
};
@@ -40,7 +39,7 @@ test "blocking mode open/send/wait API" {
var loop = try Loop.init(alloc);
defer loop.deinit();
var client: StdClient = .{
var client: Client = .{
.allocator = alloc,
.loop = &loop,
};
@@ -62,7 +61,77 @@ test "blocking mode open/send/wait API" {
try std.testing.expect(req.response.status == .ok);
}
test "non blocking mode API" {
// Example how to write an async http client using the modified standard client.
const AsyncClient = struct {
cli: Client,
const YieldImpl = Loop.Yield(AsyncRequest);
const AsyncRequest = struct {
cli: *Client,
uri: std.Uri,
headers: std.http.Headers,
impl: YieldImpl,
done: bool = false,
err: ?anyerror = null,
pub fn deinit(self: *AsyncRequest) void {
self.headers.deinit();
self.cli.allocator.destroy(self);
}
pub fn fetch(self: *AsyncRequest) void {
return self.impl.yield();
}
fn onerr(self: *AsyncRequest, err: anyerror) void {
self.err = err;
}
pub fn onYield(self: *AsyncRequest, err: ?anyerror) void {
defer self.done = true;
if (err) |e| return self.onerr(e);
var req = self.cli.open(.GET, self.uri, self.headers, .{}) catch |e| return self.onerr(e);
defer req.deinit();
req.send(.{}) catch |e| return self.onerr(e);
req.finish() catch |e| return self.onerr(e);
req.wait() catch |e| return self.onerr(e);
}
pub fn wait(self: *AsyncRequest) !void {
while (!self.done) try self.impl.tick();
if (self.err) |err| return err;
}
};
pub fn init(alloc: std.mem.Allocator, loop: *Loop) AsyncClient {
return .{
.cli = .{
.allocator = alloc,
.loop = loop,
},
};
}
pub fn deinit(self: *AsyncClient) void {
self.cli.deinit();
}
pub fn create(self: *AsyncClient, uri: std.Uri) !*AsyncRequest {
var req = try self.cli.allocator.create(AsyncRequest);
req.* = AsyncRequest{
.impl = undefined,
.cli = &self.cli,
.uri = uri,
.headers = .{ .allocator = self.cli.allocator, .owned = false },
};
req.impl = YieldImpl.init(self.cli.loop, req);
return req;
}
};
test "non blocking client" {
const alloc = std.testing.allocator;
var loop = try Loop.init(alloc);
@@ -71,7 +140,7 @@ test "non blocking mode API" {
var client = AsyncClient.init(alloc, &loop);
defer client.deinit();
var reqs: [10]*AsyncRequest = undefined;
var reqs: [10]*AsyncClient.AsyncRequest = undefined;
for (0..reqs.len) |i| {
reqs[i] = try client.create(try std.Uri.parse(url));
reqs[i].fetch();