Read complete bounded Memcached responses
This commit is contained in:
+43
-4
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user