From d703c899a79e790a8760140ad315093ad29efff4 Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Fri, 26 Jul 2024 12:20:41 +0300 Subject: Respect request to wait on submitting requests --- src/Bot.zig | 89 ++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 36 deletions(-) (limited to 'src/Bot.zig') diff --git a/src/Bot.zig b/src/Bot.zig index d40a4a0..45717e1 100644 --- a/src/Bot.zig +++ b/src/Bot.zig @@ -116,47 +116,64 @@ fn call( uri: Uri, data: ?[]const u8, ) !Parsed(T) { - var request = try self.http_client.open(method, uri, .{ - .server_header_buffer = &self.server_header_buffer, - }); - defer request.deinit(); - - if (data) |s| { - request.headers.content_type = .{ .override = "application/json" }; - request.transfer_encoding = .{ .content_length = s.len }; - } - try request.send(); - - if (data) |s| { - try request.writeAll(s); - } - try request.finish(); + while (true) { + var request = try self.http_client.open(method, uri, .{ + .server_header_buffer = &self.server_header_buffer, + }); + defer request.deinit(); + + if (data) |s| { + request.headers.content_type = .{ .override = "application/json" }; + request.transfer_encoding = .{ .content_length = s.len }; + } + try request.send(); - try request.wait(); + if (data) |s| { + try request.writeAll(s); + } + try request.finish(); + + try request.wait(); + + var reader = std.json.reader(self.allocator, request.reader()); + defer reader.deinit(); + + const result = try std.json.parseFromTokenSource( + Wrapper(T), + self.allocator, + &reader, + .{ + .ignore_unknown_fields = true, + .allocate = .alloc_always, + }, + ); + errdefer result.deinit(); + + if (result.value.parameters) |params| { + if (params.retry_after) |sleeptime| { + std.log.info("Should sleep for {} seconds", .{sleeptime}); + + var res = @mulWithOverflow(sleeptime, std.time.ns_per_s); + if (res[1] != 0) { + res[0] = std.math.maxInt(u64); + } - var reader = std.json.reader(self.allocator, request.reader()); - defer reader.deinit(); + std.log.info("Will try to sleep for {} seconds", .{res[0] / std.time.ns_per_s}); + std.time.sleep(res[0]); + continue; + } + } - const result = try std.json.parseFromTokenSource( - Wrapper(T), - self.allocator, - &reader, - .{ - .ignore_unknown_fields = true, - .allocate = .alloc_always, - }, - ); - errdefer result.deinit(); + if (!result.value.ok or result.value.result == null) { + std.log.err("Request failed: {any}", .{result.value}); + return error.RequestFailed; + } - if (!result.value.ok or result.value.result == null) { - std.log.err("Request failed: {any}", .{result.value}); - return error.RequestFailed; + return .{ + .arena = result.arena, + .value = result.value.result.?, + }; } - - return .{ - .arena = result.arena, - .value = result.value.result.?, - }; } inline fn isNull(value: anytype) bool { -- cgit v1.2.3