const std = @import("std"); const mem = std.mem; const heap = std.heap; const net = std.net; const Allocator = mem.Allocator; const Stream = net.Stream; const Thread = std.Thread; const Mutex = Thread.Mutex; const Address = net.Address; const FakeStream = @import("helpers").FakeStream; const is_test = @import("builtin").is_test; const testing = std.testing; const expect = testing.expect; pub const ServiceConnectionStatus = enum { closed, disponible, ocuppied }; pub const ServiceConnection = struct { stream: if (is_test) FakeStream else Stream = undefined, status: ServiceConnectionStatus = .closed, pub fn readAsHttp(self: *ServiceConnection, buf: []u8) usize { var res_len: usize = 0; while (true) { // trying clean the stream const aux_len = self.stream.read(buf[res_len..]) catch 0; if (aux_len == 0) { break; } res_len += aux_len; if (res_len > 3 and buf[res_len - 1] == '\n' and buf[res_len - 2] == '\r' and buf[res_len - 3] == '\n' and buf[res_len - 4] == '\r') { break; } } return res_len; } pub fn tryConnect(self: *ServiceConnection, address: *const Address) !void { if (is_test) { const buf = try testing.allocator.alloc(u8, 1024); self.stream = FakeStream.init(buf); } else { self.stream = try net.tcpConnectToAddress(address.*); } } pub fn close(self: *ServiceConnection) void { if (self.status == .closed) { return; } if (is_test) { testing.allocator.free(self.stream.buffer); } else { self.stream.close(); } self.status = .closed; } }; pub const ServiceHealth = enum { available, unavailable }; pub const ServiceError = error{ NotFound, Unreachable, NumConnectionsShouldBeMultipleOfTen } || Allocator.Error; pub const TicketStatus = enum { new, pending, success, try_again, ack }; pub const ServiceTicket = struct { content: []const u8, status: TicketStatus = .ack, conn: *ServiceConnection = undefined, res_buf: [1024]u8 = undefined, service_id: u64 = 0, };