Read complete bounded Memcached responses

This commit is contained in:
root
2026-07-20 23:24:57 +00:00
parent 0c75703186
commit 10e6565037
7 changed files with 263 additions and 19 deletions
+43 -4
View File
@@ -395,10 +395,9 @@ static u64 wasm_socket_connect_bounded(const String& host, u16 port, u64 timeout
return((u64)fd);
}
static bool wasm_socket_write_bounded(u64 socket_fd, const String& data, u64 timeout_ms)
static bool wasm_socket_write_until(u64 socket_fd, const String& data, u64 deadline)
{
int fd = (int)socket_fd;
u64 deadline = wasm_deadline_after_ms(timeout_ms);
size_t offset = 0;
while(offset < data.size())
{
@@ -413,6 +412,11 @@ static bool wasm_socket_write_bounded(u64 socket_fd, const String& data, u64 tim
return(true);
}
static bool wasm_socket_write_bounded(u64 socket_fd, const String& data, u64 timeout_ms)
{
return(wasm_socket_write_until(socket_fd, data, wasm_deadline_after_ms(timeout_ms)));
}
static String wasm_socket_read_bounded(u64 socket_fd, u32 max_length, u64 timeout_ms)
{
if(max_length == 0 || !wasm_socket_wait((int)socket_fd, POLLIN, wasm_deadline_after_ms(timeout_ms)))
@@ -422,6 +426,42 @@ static String wasm_socket_read_bounded(u64 socket_fd, u32 max_length, u64 timeou
return(count > 0 ? String(buffer.data(), (size_t)count) : String(""));
}
static String wasm_memcache_exchange(u64 socket_fd, const String& command, u64 timeout_ms)
{
static constexpr size_t max_response = 8 * 1024 * 1024;
int fd = (int)socket_fd;
u64 deadline = wasm_deadline_after_ms(timeout_ms);
if(!wasm_socket_write_until(socket_fd, command + "\r\n", deadline))
{
shutdown(fd, SHUT_RDWR);
return("");
}
if(uce_memcache_command_has_no_reply(command))
return("");
String response;
response.reserve(16 * 1024);
MemcacheResponseParser parser;
while(response.size() < max_response)
{
MemcacheResponseState state = uce_memcache_response_advance(command, response, parser);
if(state == MemcacheResponseState::Complete)
return(response);
if(state == MemcacheResponseState::Malformed || !wasm_socket_wait(fd, POLLIN, deadline))
break;
char buffer[64 * 1024];
size_t remaining = max_response - response.size();
ssize_t count = recv(fd, buffer, std::min(remaining, sizeof(buffer)), MSG_DONTWAIT);
if(count > 0)
response.append(buffer, (size_t)count);
else if(count == 0 || (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK))
break;
}
if(uce_memcache_response_advance(command, response, parser) == MemcacheResponseState::Complete)
return(response);
shutdown(fd, SHUT_RDWR);
return("");
}
static f64 wasm_thread_cpu_time()
{
struct timespec ts;
@@ -4254,8 +4294,7 @@ private:
else
{
u64 socket_fd = (u64)args[0].i64();
wasm_socket_write_bounded(socket_fd, command + "\r\n", self->bounded_hostcall_timeout_ms(1000));
out = wasm_socket_read_bounded(socket_fd, 1024 * 128, self->bounded_hostcall_timeout_ms(1000));
out = wasm_memcache_exchange(socket_fd, command, self->bounded_hostcall_timeout_ms(1000));
if(buf == 0)
{
self->staged_memcache_key = key;