1. 程式人生 > >Thrift 異常拋出解決方案

Thrift 異常拋出解決方案

use flags int 機制 signal 斷開 put write 當前

場景

Thrift框架采用了異常處理機制,因此用戶異常斷開連接的情況下,當嘗試發送數據給用戶端的時候,Thrift庫會拋出異常,導致進程中斷。這種情況是非常正常的,服務器端應該捕獲異常的發生,但是不應該異常退出。所以應該當前發送數據失敗,直接返回


修改代碼如下:

uint32_t TSocket::write_partial(const uint8_t* buf, uint32_t len) {

if (socket_ == -1) {

return -1;

throw TTransportException(TTransportException::NOT_OPEN, "Called write on non-open socket");

}


uint32_t sent = 0;


int flags = 0;

#ifdef MSG_NOSIGNAL

// Note the use of MSG_NOSIGNAL to suppress SIGPIPE errors, instead we

// check for the EPIPE return condition and close the socket in that case

flags |= MSG_NOSIGNAL;

#endif // ifdef MSG_NOSIGNAL


int b = send(socket_, const_cast_sockopt(buf + sent), len - sent, flags);

++g_socket_syscalls;


if (b < 0) {

if (errno == EWOULDBLOCK || errno == EAGAIN) {

return 0;

}

// Fail on a send error

int errno_copy = errno;

GlobalOutput.perror("TSocket::write_partial() send() " + getSocketInfo(), errno_copy);


if (errno_copy == EPIPE || errno_copy == ECONNRESET || errno_copy == ENOTCONN) {

//修改的第一個地方,直接返回-1,不拋出異常

close();

return -1;

//throw TTransportException(TTransportException::NOT_OPEN, "write() send()", errno_copy);

}

//修改的第二個地方,直接返回-1,不拋出異常

close();

return -1;

throw TTransportException(TTransportException::UNKNOWN, "write() send()", errno_copy);

}


// Fail on blocked send

if (b == 0) {

throw TTransportException(TTransportException::NOT_OPEN, "Socket send returned 0.");

}

return b;

}


Thrift 異常拋出解決方案