in src/brpc/global.cpp [322:629]
static void GlobalInitializeOrDieImpl() {
//////////////////////////////////////////////////////////////////
// Be careful about usages of gflags inside this function which //
// may be called before main() only seeing gflags with default //
// values even if the gflags will be set after main(). //
//////////////////////////////////////////////////////////////////
// Ignore SIGPIPE.
struct sigaction oldact;
if (sigaction(SIGPIPE, NULL, &oldact) != 0 ||
(oldact.sa_handler == NULL && oldact.sa_sigaction == NULL)) {
CHECK(SIG_ERR != signal(SIGPIPE, SIG_IGN));
}
#if GOOGLE_PROTOBUF_VERSION < 3022000
// Make GOOGLE_LOG print to comlog device
SetLogHandler(&BaiduStreamingLogHandler);
#endif
// Set bthread create span function
bthread_set_create_span_func(CreateBthreadSpan);
// Setting the variable here does not work, the profiler probably check
// the variable before main() for only once.
// setenv("TCMALLOC_SAMPLE_PARAMETER", "524288", 0);
// Initialize openssl library
SSL_library_init();
// RPC doesn't require openssl.cnf, users can load it by themselves if needed
SSL_load_error_strings();
if (SSLThreadInit() != 0 || SSLDHInit() != 0) {
exit(1);
}
// Defined in http_rpc_protocol.cpp
InitCommonStrings();
// Leave memory of these extensions to process's clean up.
g_ext = new(std::nothrow) GlobalExtensions();
if (NULL == g_ext) {
exit(1);
}
// Naming Services
#ifdef BAIDU_INTERNAL
NamingServiceExtension()->RegisterOrDie("bns", &g_ext->bns);
#endif
NamingServiceExtension()->RegisterOrDie("file", &g_ext->fns);
NamingServiceExtension()->RegisterOrDie("list", &g_ext->lns);
NamingServiceExtension()->RegisterOrDie("dlist", &g_ext->dlns);
NamingServiceExtension()->RegisterOrDie("http", &g_ext->dns);
NamingServiceExtension()->RegisterOrDie("https", &g_ext->dns_with_ssl);
NamingServiceExtension()->RegisterOrDie("redis", &g_ext->dns);
NamingServiceExtension()->RegisterOrDie("remotefile", &g_ext->rfns);
NamingServiceExtension()->RegisterOrDie("consul", &g_ext->cns);
NamingServiceExtension()->RegisterOrDie("discovery", &g_ext->dcns);
NamingServiceExtension()->RegisterOrDie("nacos", &g_ext->nns);
// Load Balancers
LoadBalancerExtension()->RegisterOrDie("rr", &g_ext->rr_lb);
LoadBalancerExtension()->RegisterOrDie("wrr", &g_ext->wrr_lb);
LoadBalancerExtension()->RegisterOrDie("random", &g_ext->randomized_lb);
LoadBalancerExtension()->RegisterOrDie("wr", &g_ext->wr_lb);
LoadBalancerExtension()->RegisterOrDie("la", &g_ext->la_lb);
LoadBalancerExtension()->RegisterOrDie("c_murmurhash", &g_ext->ch_mh_lb);
LoadBalancerExtension()->RegisterOrDie("c_md5", &g_ext->ch_md5_lb);
LoadBalancerExtension()->RegisterOrDie("c_ketama", &g_ext->ch_ketama_lb);
LoadBalancerExtension()->RegisterOrDie("_dynpart", &g_ext->dynpart_lb);
// Compress Handlers
CompressHandler gzip_compress = { GzipCompress, GzipDecompress, "gzip" };
if (RegisterCompressHandler(COMPRESS_TYPE_GZIP, gzip_compress) != 0) {
exit(1);
}
CompressHandler zlib_compress = { ZlibCompress, ZlibDecompress, "zlib" };
if (RegisterCompressHandler(COMPRESS_TYPE_ZLIB, zlib_compress) != 0) {
exit(1);
}
CompressHandler snappy_compress = { SnappyCompress, SnappyDecompress, "snappy" };
if (RegisterCompressHandler(COMPRESS_TYPE_SNAPPY, snappy_compress) != 0) {
exit(1);
}
// Protocols
Protocol baidu_protocol = { ParseRpcMessage,
SerializeRpcRequest, PackRpcRequest,
ProcessRpcRequest, ProcessRpcResponse,
VerifyRpcRequest, NULL, NULL,
CONNECTION_TYPE_ALL, "baidu_std" };
if (RegisterProtocol(PROTOCOL_BAIDU_STD, baidu_protocol) != 0) {
exit(1);
}
Protocol streaming_protocol = { ParseStreamingMessage,
NULL, NULL, ProcessStreamingMessage,
ProcessStreamingMessage,
NULL, NULL, NULL,
CONNECTION_TYPE_SINGLE, "streaming_rpc" };
if (RegisterProtocol(PROTOCOL_STREAMING_RPC, streaming_protocol) != 0) {
exit(1);
}
Protocol http_protocol = { ParseHttpMessage,
SerializeHttpRequest, PackHttpRequest,
ProcessHttpRequest, ProcessHttpResponse,
VerifyHttpRequest, ParseHttpServerAddress,
GetHttpMethodName,
CONNECTION_TYPE_POOLED_AND_SHORT,
"http" };
if (RegisterProtocol(PROTOCOL_HTTP, http_protocol) != 0) {
exit(1);
}
Protocol http2_protocol = { ParseH2Message,
SerializeHttpRequest, PackH2Request,
ProcessHttpRequest, ProcessHttpResponse,
VerifyHttpRequest, ParseHttpServerAddress,
GetHttpMethodName,
CONNECTION_TYPE_SINGLE,
"h2" };
if (RegisterProtocol(PROTOCOL_H2, http2_protocol) != 0) {
exit(1);
}
Protocol hulu_protocol = { ParseHuluMessage,
SerializeRequestDefault, PackHuluRequest,
ProcessHuluRequest, ProcessHuluResponse,
VerifyHuluRequest, NULL, NULL,
CONNECTION_TYPE_ALL, "hulu_pbrpc" };
if (RegisterProtocol(PROTOCOL_HULU_PBRPC, hulu_protocol) != 0) {
exit(1);
}
// Only valid at client side
Protocol nova_protocol = { ParseNsheadMessage,
SerializeNovaRequest, PackNovaRequest,
NULL, ProcessNovaResponse,
NULL, NULL, NULL,
CONNECTION_TYPE_POOLED_AND_SHORT, "nova_pbrpc" };
if (RegisterProtocol(PROTOCOL_NOVA_PBRPC, nova_protocol) != 0) {
exit(1);
}
// Only valid at client side
Protocol public_pbrpc_protocol = { ParseNsheadMessage,
SerializePublicPbrpcRequest,
PackPublicPbrpcRequest,
NULL, ProcessPublicPbrpcResponse,
NULL, NULL, NULL,
// public_pbrpc server implementation
// doesn't support full duplex
CONNECTION_TYPE_POOLED_AND_SHORT,
"public_pbrpc" };
if (RegisterProtocol(PROTOCOL_PUBLIC_PBRPC, public_pbrpc_protocol) != 0) {
exit(1);
}
Protocol sofa_protocol = { ParseSofaMessage,
SerializeRequestDefault, PackSofaRequest,
ProcessSofaRequest, ProcessSofaResponse,
VerifySofaRequest, NULL, NULL,
CONNECTION_TYPE_ALL, "sofa_pbrpc" };
if (RegisterProtocol(PROTOCOL_SOFA_PBRPC, sofa_protocol) != 0) {
exit(1);
}
// Only valid at server side. We generalize all the protocols that
// prefixes with nshead as `nshead_protocol' and specify the content
// parsing after nshead by ServerOptions.nshead_service.
Protocol nshead_protocol = { ParseNsheadMessage,
SerializeNsheadRequest, PackNsheadRequest,
ProcessNsheadRequest, ProcessNsheadResponse,
VerifyNsheadRequest, NULL, NULL,
CONNECTION_TYPE_POOLED_AND_SHORT, "nshead" };
if (RegisterProtocol(PROTOCOL_NSHEAD, nshead_protocol) != 0) {
exit(1);
}
Protocol mc_binary_protocol = { ParseMemcacheMessage,
SerializeMemcacheRequest,
PackMemcacheRequest,
NULL, ProcessMemcacheResponse,
NULL, NULL, GetMemcacheMethodName,
CONNECTION_TYPE_ALL, "memcache" };
if (RegisterProtocol(PROTOCOL_MEMCACHE, mc_binary_protocol) != 0) {
exit(1);
}
Protocol redis_protocol = { ParseRedisMessage,
SerializeRedisRequest,
PackRedisRequest,
ProcessRedisRequest, ProcessRedisResponse,
NULL, NULL, GetRedisMethodName,
CONNECTION_TYPE_ALL, "redis" };
if (RegisterProtocol(PROTOCOL_REDIS, redis_protocol) != 0) {
exit(1);
}
Protocol mongo_protocol = { ParseMongoMessage,
NULL, NULL,
ProcessMongoRequest, NULL,
NULL, NULL, NULL,
CONNECTION_TYPE_POOLED, "mongo" };
if (RegisterProtocol(PROTOCOL_MONGO, mongo_protocol) != 0) {
exit(1);
}
// Use Macro is more straight forward than weak link technology(becasue of static link issue)
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
Protocol thrift_binary_protocol = {
policy::ParseThriftMessage,
policy::SerializeThriftRequest, policy::PackThriftRequest,
policy::ProcessThriftRequest, policy::ProcessThriftResponse,
policy::VerifyThriftRequest, NULL, NULL,
CONNECTION_TYPE_POOLED_AND_SHORT, "thrift" };
if (RegisterProtocol(PROTOCOL_THRIFT, thrift_binary_protocol) != 0) {
exit(1);
}
#endif
// Only valid at client side
Protocol ubrpc_compack_protocol = {
ParseNsheadMessage,
SerializeUbrpcCompackRequest, PackUbrpcRequest,
NULL, ProcessUbrpcResponse,
NULL, NULL, NULL,
CONNECTION_TYPE_POOLED_AND_SHORT, "ubrpc_compack" };
if (RegisterProtocol(PROTOCOL_UBRPC_COMPACK, ubrpc_compack_protocol) != 0) {
exit(1);
}
Protocol ubrpc_mcpack2_protocol = {
ParseNsheadMessage,
SerializeUbrpcMcpack2Request, PackUbrpcRequest,
NULL, ProcessUbrpcResponse,
NULL, NULL, NULL,
CONNECTION_TYPE_POOLED_AND_SHORT, "ubrpc_mcpack2" };
if (RegisterProtocol(PROTOCOL_UBRPC_MCPACK2, ubrpc_mcpack2_protocol) != 0) {
exit(1);
}
// Only valid at client side
Protocol nshead_mcpack_protocol = {
ParseNsheadMessage,
SerializeNsheadMcpackRequest, PackNsheadMcpackRequest,
NULL, ProcessNsheadMcpackResponse,
NULL, NULL, NULL,
CONNECTION_TYPE_POOLED_AND_SHORT, "nshead_mcpack" };
if (RegisterProtocol(PROTOCOL_NSHEAD_MCPACK, nshead_mcpack_protocol) != 0) {
exit(1);
}
Protocol rtmp_protocol = {
ParseRtmpMessage,
SerializeRtmpRequest, PackRtmpRequest,
ProcessRtmpMessage, ProcessRtmpMessage,
NULL, NULL, NULL,
(ConnectionType)(CONNECTION_TYPE_SINGLE|CONNECTION_TYPE_SHORT),
"rtmp" };
if (RegisterProtocol(PROTOCOL_RTMP, rtmp_protocol) != 0) {
exit(1);
}
Protocol esp_protocol = {
ParseEspMessage,
SerializeEspRequest, PackEspRequest,
NULL, ProcessEspResponse,
NULL, NULL, NULL,
CONNECTION_TYPE_POOLED_AND_SHORT, "esp"};
if (RegisterProtocol(PROTOCOL_ESP, esp_protocol) != 0) {
exit(1);
}
std::vector<Protocol> protocols;
ListProtocols(&protocols);
for (size_t i = 0; i < protocols.size(); ++i) {
if (protocols[i].process_response) {
InputMessageHandler handler;
// `process_response' is required at client side
handler.parse = protocols[i].parse;
handler.process = protocols[i].process_response;
// No need to verify at client side
handler.verify = NULL;
handler.arg = NULL;
handler.name = protocols[i].name;
if (get_or_new_client_side_messenger()->AddHandler(handler) != 0) {
exit(1);
}
}
}
// Concurrency Limiters
ConcurrencyLimiterExtension()->RegisterOrDie("auto", &g_ext->auto_cl);
ConcurrencyLimiterExtension()->RegisterOrDie("constant", &g_ext->constant_cl);
ConcurrencyLimiterExtension()->RegisterOrDie("timeout", &g_ext->timeout_cl);
if (FLAGS_usercode_in_pthread) {
// Optional. If channel/server are initialized before main(), this
// flag may be false at here even if it will be set to true after
// main(). In which case, the usercode pool will not be initialized
// until the pool is used.
InitUserCodeBackupPoolOnceOrDie();
}
// We never join GlobalUpdate, let it quit with the process.
bthread_t th;
CHECK(bthread_start_background(&th, NULL, GlobalUpdate, NULL) == 0)
<< "Fail to start GlobalUpdate";
}