├── .gitignore ├── LICENSE ├── common ├── BUILD ├── base │ ├── BlockingQueue.h │ ├── Exception.cc │ ├── Exception.h │ ├── Likely.h │ ├── StackTrace.cc │ ├── StackTrace.h │ ├── Types.h │ └── WeakCallback.h ├── events │ ├── Channel.cc │ ├── Channel.h │ ├── EventLoop.cc │ ├── EventLoop.h │ ├── EventLoopThread.cc │ ├── EventLoopThread.h │ ├── EventLoopThreadPool.cc │ ├── EventLoopThreadPool.h │ ├── Poller.h │ ├── SignalSet.cc │ ├── SignalSet.h │ ├── TimeoutQueue.cc │ ├── TimeoutQueue.h │ ├── TimerId.h │ └── poller │ │ ├── EPollPoller.cc │ │ └── EPollPoller.h ├── files │ ├── FileUtil.cc │ └── FileUtil.h ├── logging │ ├── LogBuffer.cc │ ├── LogBuffer.h │ ├── LogFile.cc │ ├── LogFile.h │ ├── LogMessage.cc │ ├── LogMessage.h │ ├── LogStream.cc │ ├── LogStream.h │ ├── Logger.cc │ ├── Logger.h │ ├── Logging.cc │ └── Logging.h ├── metrics │ ├── BucketRanges.cc │ ├── BucketRanges.h │ ├── Counter.cc │ ├── Counter.h │ ├── CounterProvider.cc │ ├── CounterProvider.h │ ├── CounterSampler.cc │ ├── CounterSampler.h │ ├── Histogram.cc │ ├── Histogram.h │ ├── HistogramRecorder.cc │ ├── HistogramRecorder.h │ ├── HistogramSamples.cc │ ├── HistogramSamples.h │ ├── SampleVector.cc │ └── SampleVector.h ├── protobuf │ ├── ProtobufIO.cc │ └── ProtobufIO.h ├── strings │ ├── StringPiece.cc │ ├── StringPiece.h │ ├── StringPrintf.cc │ ├── StringPrintf.h │ ├── StringUtil.cc │ ├── StringUtil.h │ ├── UriEscape.cc │ ├── UriEscape.h │ └── generate_escape_tables.py ├── symbolizer │ ├── Dwarf.cc │ ├── Dwarf.h │ ├── Elf.cc │ ├── Elf.h │ ├── Symbolizer.cc │ └── Symbolizer.h ├── system │ ├── ThisProcess.cc │ └── ThisProcess.h ├── tests │ ├── CMakeLists.txt │ ├── Logger_test.cc │ ├── Symbolizer_test.cc │ └── TimeoutQueue_test.cc ├── threading │ ├── Condition.h │ ├── CountDownLatch.h │ ├── Mutex.cc │ ├── Mutex.h │ ├── Singleton.h │ ├── ThisThread.cc │ ├── ThisThread.h │ ├── Thread.cc │ ├── Thread.h │ ├── ThreadPool.cc │ └── ThreadPool.h ├── time │ ├── Timestamp.cc │ └── Timestamp.h └── tracing │ ├── Trace.cc │ ├── Trace.h │ ├── TraceContext.cc │ ├── TraceContext.h │ ├── TraceRecorder.cc │ ├── TraceRecorder.h │ ├── Tracer.h │ ├── Tracing.cc │ └── Tracing.h ├── examples ├── rpcbench │ ├── BUILD │ ├── client.cc │ ├── echo.proto │ └── server.cc └── zipkin │ ├── BUILD │ ├── client.cc │ ├── server.cc │ ├── sort.proto │ ├── sort_client.h │ ├── stdsort_client.h │ └── transfer.cc ├── netty ├── Acceptor.cc ├── Acceptor.h ├── BUILD ├── Buffer.cc ├── Buffer.h ├── Callbacks.h ├── Connector.cc ├── Connector.h ├── Endian.h ├── IOStream.cc ├── IOStream.h ├── InetAddress.cc ├── InetAddress.h ├── Socket.cc ├── Socket.h ├── TcpClient.cc ├── TcpClient.h ├── TcpConnection.cc ├── TcpConnection.h ├── TcpServer.cc ├── TcpServer.h ├── UdpClient.cc ├── UdpClient.h ├── UdpServer.cc ├── UdpServer.h ├── http │ ├── HttpClient.cc │ ├── HttpClient.h │ ├── HttpConnection.cc │ ├── HttpConnection.h │ ├── HttpHeaders.h │ ├── HttpMessage.h │ ├── HttpRequest.cc │ ├── HttpRequest.h │ ├── HttpResponse.cc │ ├── HttpResponse.h │ ├── HttpServer.cc │ ├── HttpServer.h │ ├── MimeType.cc │ ├── MimeType.h │ ├── Uri.cc │ ├── Uri.h │ └── assets │ │ ├── bootstrap │ │ ├── css │ │ │ └── bootstrap-2.2.1.combined.min.css │ │ └── js │ │ │ └── bootstrap-2.2.1.min.js │ │ └── jquery │ │ └── js │ │ ├── jquery-1.10.2.min.js │ │ ├── jquery-1.10.3.ui.min.js │ │ └── jquery.json-2.4.min.js ├── inspect │ ├── FlagsInspector.cc │ ├── FlagsInspector.h │ ├── PProfInspector.cc │ ├── PProfInspector.h │ ├── StatisticsInspector.cc │ ├── StatisticsInspector.h │ └── assets │ │ ├── dygraph-combined.js │ │ ├── dygraph-extra.js │ │ ├── flags.html │ │ ├── flags.js │ │ ├── grapher.js │ │ ├── graphview.html │ │ └── parser.js ├── loadbalancer │ ├── LoadBalancer.h │ ├── LoadBalancerFactory.cc │ ├── LoadBalancerFactory.h │ ├── RandomLoadBalancer.h │ └── RoundRobinLoadBalancer.h ├── resolver │ ├── DnsResolver.cc │ ├── DnsResolver.h │ ├── Resolver.h │ ├── ResolverFactory.cc │ ├── ResolverFactory.h │ ├── StaticAddressResolver.cc │ └── StaticAddressResolver.h └── tests │ ├── CMakeLists.txt │ ├── HttpRequest_unittest.cc │ ├── HttpResponse_unittest.cc │ ├── Uri_unittest.cc │ └── resolver_test.cc ├── protorpc ├── .gitignore ├── BUILD ├── BuiltinService.cc ├── BuiltinService.h ├── README.md ├── RpcChannel.cc ├── RpcChannel.h ├── RpcCodec.cc ├── RpcCodec.h ├── RpcController.cc ├── RpcController.h ├── RpcServer.cc ├── RpcServer.h ├── RpcUtil.cc ├── RpcUtil.h ├── Tutorial.md ├── assets │ ├── forms.html │ ├── forms.js │ └── methods.html ├── builtin_service.proto ├── gen-rpc.sh ├── generator │ ├── cpp_field.h │ ├── cpp_message.h │ ├── cpp_options.h │ ├── cpp_service.h │ └── protoc-gen-rpc.cc ├── rpcmessage.proto └── service.h └── zipkin ├── .gitignore ├── BUILD ├── ScribeClient.cc ├── ScribeClient.h ├── ZipkinTracer.cc ├── ZipkinTracer.h ├── fb303.thrift ├── scribe.thrift └── zipkinCore.thrift /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, robbinfan 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /common/BUILD: -------------------------------------------------------------------------------- 1 | gen_rule( 2 | name = 'gen_escape_table', 3 | cmd = 'python claire/common/strings/generate_escape_tables.py --install_dir=$BUILD_DIR/claire/common', 4 | outs = ['EscapeTables.cc'] 5 | ) 6 | 7 | cc_library( 8 | name = 'claire_common', 9 | srcs = [ 10 | './base/Exception.cc', 11 | './base/StackTrace.cc', 12 | './events/Channel.cc', 13 | './events/EventLoop.cc', 14 | './events/EventLoopThread.cc', 15 | './events/EventLoopThreadPool.cc', 16 | './events/SignalSet.cc', 17 | './events/TimeoutQueue.cc', 18 | './events/poller/EPollPoller.cc', 19 | './files/FileUtil.cc', 20 | './logging/LogBuffer.cc', 21 | './logging/LogFile.cc', 22 | './logging/LogMessage.cc', 23 | './logging/LogStream.cc', 24 | './logging/Logger.cc', 25 | './logging/Logging.cc', 26 | './metrics/BucketRanges.cc', 27 | './metrics/Counter.cc', 28 | './metrics/CounterProvider.cc', 29 | './metrics/CounterSampler.cc', 30 | './metrics/Histogram.cc', 31 | './metrics/HistogramRecorder.cc', 32 | './metrics/HistogramSamples.cc', 33 | './metrics/SampleVector.cc', 34 | './protobuf/ProtobufIO.cc', 35 | './strings/StringPiece.cc', 36 | './strings/StringUtil.cc', 37 | './strings/StringPrintf.cc', 38 | './strings/UriEscape.cc', 39 | './symbolizer/Dwarf.cc', 40 | './symbolizer/Elf.cc', 41 | './symbolizer/Symbolizer.cc', 42 | './system/ThisProcess.cc', 43 | './threading/Mutex.cc', 44 | './threading/ThisThread.cc', 45 | './threading/Thread.cc', 46 | './threading/ThreadPool.cc', 47 | './time/Timestamp.cc', 48 | './tracing/Trace.cc', 49 | './tracing/TraceContext.cc', 50 | './tracing/TraceRecorder.cc', 51 | './tracing/Tracing.cc', 52 | 'EscapeTables.cc', 53 | ], 54 | deps = [ 55 | ':gen_escape_table', 56 | '//thirdparty/protobuf:protobuf', 57 | '#pthread', 58 | '#rt'], 59 | extra_cppflags = '-std=c++0x' 60 | ) 61 | -------------------------------------------------------------------------------- /common/base/BlockingQueue.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_BASE_BLOCKINGQUEUE_H_ 6 | #define _CLAIRE_COMMON_BASE_BLOCKINGQUEUE_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace claire { 16 | 17 | template 18 | class BlockingQueue : boost::noncopyable 19 | { 20 | public: 21 | BlockingQueue() 22 | : mutex_(), 23 | not_empty_(mutex_), 24 | queue_() 25 | {} 26 | 27 | void Put(const T& x) 28 | { 29 | MutexLock lock(mutex_); 30 | queue_.push_back(x); 31 | not_empty_.Notify(); // wait morphing saves us 32 | // http://www.domaigne.com/blog/computing/condvars-signal-with-mutex-locked-or-not/ 33 | } 34 | 35 | T Take() 36 | { 37 | MutexLock lock(mutex_); 38 | // always use a while-loop, due to spurious wakeup 39 | while (queue_.empty()) 40 | { 41 | not_empty_.Wait(); 42 | } 43 | T front(queue_.front()); 44 | queue_.pop_front(); 45 | return front; 46 | } 47 | 48 | size_t size() const 49 | { 50 | MutexLock lock(mutex_); 51 | return queue_.size(); 52 | } 53 | 54 | private: 55 | mutable Mutex mutex_; 56 | Condition not_empty_; 57 | std::deque queue_; 58 | }; 59 | 60 | } // namespace claire 61 | 62 | #endif // _CLAIRE_COMMON_BASE_BLOCKINGQUEUE_H_ 63 | -------------------------------------------------------------------------------- /common/base/Exception.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | #include 7 | 8 | namespace claire { 9 | 10 | Exception::Exception(const char* what__) 11 | : what_(what__), 12 | stack_trace_(GetStackTrace(2)) 13 | {} 14 | 15 | Exception::Exception(const std::string& what__) 16 | : what_(what__), 17 | stack_trace_(GetStackTrace(2)) 18 | {} 19 | 20 | } // namespace claire 21 | 22 | -------------------------------------------------------------------------------- /common/base/Exception.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_BASE_EXCEPTION_H_ 6 | #define _CLAIRE_COMMON_BASE_EXCEPTION_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace claire { 12 | 13 | class Exception : public std::exception 14 | { 15 | public: 16 | explicit Exception(const char* what); 17 | explicit Exception(const std::string& what); 18 | 19 | virtual ~Exception() throw() {} 20 | 21 | virtual const char* what() const throw() 22 | { 23 | return what_.c_str(); 24 | } 25 | 26 | const char* stack_trace() const throw() 27 | { 28 | return stack_trace_.c_str(); 29 | } 30 | 31 | private: 32 | std::string what_; 33 | std::string stack_trace_; 34 | }; 35 | 36 | } // namespace claire 37 | 38 | #endif // _CLAIRE_COMMON_BASE_EXCEPTION_H_ 39 | -------------------------------------------------------------------------------- /common/base/Likely.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_BASE_LIKELY_H_ 6 | #define _CLAIRE_COMMON_BASE_LIKELY_H_ 7 | 8 | #undef LIKELY 9 | #undef UNLIKELY 10 | 11 | #define LIKELY(x) (__builtin_expect(!!(x), 0)) 12 | #define UNLIKELY(x) (__builtin_expect((x), 0)) 13 | 14 | #endif // _CLAIRE_COMMON_BASE_LIKELY_H_ 15 | -------------------------------------------------------------------------------- /common/base/StackTrace.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #undef CLAIRE_DEMANGLE 11 | #if defined(__GNUG__) && __GNUG__ >= 4 12 | #include 13 | #include 14 | #define CLAIRE_DEMANGLE 1 15 | #endif 16 | 17 | namespace claire { 18 | 19 | #ifdef CLAIRE_DEMANGLE 20 | std::string demangle(const char* name) 21 | { 22 | int status; 23 | size_t length = 0; 24 | // malloc() memory for the demangled type name 25 | char* demangled = abi::__cxa_demangle(name, NULL, &length, &status); 26 | if (status != 0) 27 | { 28 | return name; 29 | } 30 | // len is the length of the buffer (including NUL terminator and maybe 31 | // other junk) 32 | 33 | std::string result(demangled, strlen(demangled)); 34 | free(demangled); 35 | return result; 36 | } 37 | 38 | #else 39 | 40 | std::string demangle(const char* name) 41 | { 42 | return name; 43 | } 44 | 45 | #endif // CLAIRE_DEMANGLE 46 | #undef CLAIRE_DEMANGLE 47 | 48 | std::string GetStackTrace(int escape_depth) 49 | { 50 | std::string stack; 51 | 52 | const int length = 200; 53 | void* buffer[length]; 54 | int nptrs = ::backtrace(buffer, length); 55 | char** strings = ::backtrace_symbols(buffer, nptrs); 56 | if (strings) 57 | { 58 | for (int i = escape_depth; i < nptrs; ++i) 59 | { 60 | stack.append(demangle(strings[i])); 61 | stack.append("\r\n"); 62 | } 63 | free(strings); 64 | } 65 | return stack; 66 | } 67 | 68 | } // namespace claire 69 | -------------------------------------------------------------------------------- /common/base/StackTrace.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_BASE_STACKTRACE_H_ 6 | #define _CLAIRE_COMMON_BASE_STACKTRACE_H_ 7 | 8 | #include 9 | 10 | namespace claire { 11 | 12 | std::string demangle(const char* name); 13 | std::string GetStackTrace(int escape_depth); 14 | 15 | } // namespace claire 16 | 17 | #endif // _CLAIRE_COMMON_BASE_STACKTRACE_H_ 18 | -------------------------------------------------------------------------------- /common/base/WeakCallback.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_BASE_WEAKCALLBACK_H_ 6 | #define _CLAIRE_COMMON_BASE_WEAKCALLBACK_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace claire { 13 | 14 | template 15 | class WeakCallback 16 | { 17 | public: 18 | WeakCallback(const boost::function& function, 19 | const boost::weak_ptr& object) 20 | : function_(function), 21 | object_(object) 22 | {} 23 | 24 | void operator()(ARGS&&... args) const 25 | { 26 | auto ptr(object_.lock()); 27 | if (ptr) 28 | { 29 | function_(get_pointer(ptr), std::forward(args)...); 30 | } 31 | } 32 | 33 | private: 34 | boost::function function_; 35 | boost::weak_ptr object_; 36 | }; 37 | 38 | template 39 | WeakCallback MakeWeakCallback(void (CLASS::*function)(ARGS...), 40 | const boost::shared_ptr& object) 41 | { 42 | return WeakCallback(function, object); 43 | } 44 | 45 | template 46 | WeakCallback MakeWeakCallback(void (CLASS::*function)(ARGS...) const, 47 | const boost::shared_ptr& object) 48 | { 49 | return WeakCallback(function, object); 50 | } 51 | 52 | } // namespace claire 53 | 54 | #endif // _CLAIRE_COMMON_BASE_WEAKCALLBACK_H_ 55 | -------------------------------------------------------------------------------- /common/events/Channel.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace claire { 13 | 14 | const int Channel::kNoneEvent = 0; 15 | const int Channel::kReadEvent = POLLIN | POLLPRI; 16 | const int Channel::kWriteEvent = POLLOUT; 17 | 18 | Channel::Channel(EventLoop* loop, int fd__) 19 | : loop_(loop), 20 | fd_(fd__), 21 | events_(0), 22 | revents_(0), 23 | context_(-1), 24 | priority_(Priority::kNormal), 25 | tied_(false), 26 | event_handling_(false) 27 | {} 28 | 29 | Channel::~Channel() { CHECK(!event_handling_); } 30 | 31 | void Channel::tie(const boost::shared_ptr& ptr) 32 | { 33 | tie_ = ptr; 34 | tied_ = true; 35 | } 36 | 37 | void Channel::Update() 38 | { 39 | loop_->UpdateChannel(this); 40 | } 41 | 42 | void Channel::Remove() 43 | { 44 | loop_->RemoveChannel(this); 45 | } 46 | 47 | void Channel::OnEvent() 48 | { 49 | if (tied_) 50 | { 51 | auto guard = tie_.lock(); 52 | if (guard) 53 | { 54 | OnEventWithGuard(); 55 | } 56 | } 57 | else 58 | { 59 | OnEventWithGuard(); 60 | } 61 | } 62 | 63 | void Channel::OnEventWithGuard() 64 | { 65 | event_handling_ = true; 66 | 67 | if ((revents_ & POLLHUP) && !(revents_ & POLLIN)) 68 | { 69 | LOG(WARNING) << "Channel::Handle_event() POLLHUP"; 70 | 71 | if (close_callback_) 72 | { 73 | close_callback_(); 74 | } 75 | } 76 | 77 | if (revents_ & POLLNVAL) 78 | { 79 | LOG(WARNING) << "Channel::OnEvent POLLNVAL"; 80 | } 81 | 82 | if (revents_ & (POLLERR | POLLNVAL)) 83 | { 84 | if (error_callback_) 85 | { 86 | error_callback_(); 87 | } 88 | } 89 | 90 | if (revents_ & (POLLIN | POLLPRI | POLLRDHUP)) 91 | { 92 | if (read_callback_) 93 | { 94 | read_callback_(); 95 | } 96 | } 97 | 98 | if (revents_ & POLLOUT) 99 | { 100 | if (write_callback_) 101 | { 102 | write_callback_(); 103 | } 104 | } 105 | 106 | event_handling_ = false; 107 | } 108 | 109 | } // namespace claire 110 | -------------------------------------------------------------------------------- /common/events/EventLoopThread.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace claire { 13 | 14 | EventLoopThread::EventLoopThread(const ThreadInitCallback& callback) 15 | : loop_(NULL), 16 | thread_(boost::bind(&EventLoopThread::ThreadMain, this), std::string()), 17 | mutex_(), 18 | condition_(mutex_), 19 | callback_(callback) 20 | {} 21 | 22 | EventLoopThread::~EventLoopThread() 23 | { 24 | loop_->quit(); 25 | thread_.Join(); 26 | } 27 | 28 | EventLoop* EventLoopThread::StartLoop() 29 | { 30 | DCHECK(!thread_.started()); 31 | thread_.Start(); 32 | 33 | { 34 | MutexLock lock(mutex_); 35 | while(!loop_) 36 | { 37 | condition_.Wait(); 38 | } 39 | } 40 | 41 | return loop_; 42 | } 43 | 44 | void EventLoopThread::ThreadMain() 45 | { 46 | EventLoop loop; 47 | if (callback_) 48 | { 49 | callback_(&loop); 50 | } 51 | 52 | { 53 | MutexLock lock(mutex_); 54 | loop_ = &loop; 55 | condition_.Notify(); 56 | } 57 | 58 | loop.loop(); 59 | } 60 | 61 | } // namespace claire 62 | -------------------------------------------------------------------------------- /common/events/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_EVENTS_EVENTLOOPTHREAD_H_ 6 | #define _CLAIRE_COMMON_EVENTS_EVENTLOOPTHREAD_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace claire { 16 | 17 | class EventLoop; 18 | 19 | class EventLoopThread : boost::noncopyable 20 | { 21 | public: 22 | typedef boost::function ThreadInitCallback; 23 | 24 | EventLoopThread(const ThreadInitCallback& callback); 25 | ~EventLoopThread(); 26 | 27 | EventLoop* StartLoop(); 28 | 29 | private: 30 | void ThreadMain(); 31 | 32 | EventLoop* loop_; 33 | Thread thread_; 34 | Mutex mutex_; 35 | Condition condition_; 36 | ThreadInitCallback callback_; 37 | }; 38 | 39 | } // namespace claire 40 | 41 | #endif // _CLAIRE_COMMON_EVENTS_EVENTLOOPTHREAD_H_ 42 | -------------------------------------------------------------------------------- /common/events/EventLoopThreadPool.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace claire { 12 | 13 | EventLoopThreadPool::EventLoopThreadPool(EventLoop* loop) 14 | : base_loop_(loop), 15 | started_(false), 16 | num_threads_(0), 17 | next_(0) 18 | {} 19 | 20 | void EventLoopThreadPool::Start() 21 | { 22 | ThreadInitCallback callback; 23 | Start(callback); 24 | } 25 | 26 | void EventLoopThreadPool::Start(const ThreadInitCallback& callback) 27 | { 28 | DCHECK(!started_); 29 | base_loop_->AssertInLoopThread(); 30 | 31 | started_ = true; 32 | for (int i = 0;i < num_threads_; ++i) 33 | { 34 | auto thread = new EventLoopThread(callback); 35 | threads_.push_back(thread); 36 | loops_.push_back(thread->StartLoop()); 37 | } 38 | 39 | if (num_threads_ == 0 && callback) 40 | { 41 | callback(base_loop_); 42 | } 43 | } 44 | 45 | EventLoop* EventLoopThreadPool::NextLoop() 46 | { 47 | base_loop_->AssertInLoopThread(); 48 | 49 | auto loop = base_loop_; 50 | if (!loops_.empty()) 51 | { 52 | // round-robin 53 | loop = loops_[next_++]; 54 | if (next_ >= static_cast(loops_.size())) 55 | { 56 | next_ = 0; 57 | } 58 | } 59 | 60 | return loop; 61 | } 62 | 63 | } // namespace claire 64 | -------------------------------------------------------------------------------- /common/events/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_EVENTS_EVENTLOOPTHREADPOOL_H_ 6 | #define _CLAIRE_COMMON_EVENTS_EVENTLOOPTHREADPOOL_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace claire { 15 | 16 | class EventLoop; 17 | class EventLoopThread; 18 | 19 | class EventLoopThreadPool : boost::noncopyable 20 | { 21 | public: 22 | typedef boost::function ThreadInitCallback; 23 | 24 | EventLoopThreadPool(EventLoop* base_loop); 25 | 26 | void set_num_threads(int num_threads) 27 | { 28 | num_threads_ = num_threads; 29 | } 30 | 31 | void Start(); 32 | void Start(const ThreadInitCallback& callback); 33 | EventLoop* NextLoop(); 34 | 35 | private: 36 | EventLoop* base_loop_; 37 | bool started_; 38 | int num_threads_; 39 | int next_; 40 | boost::ptr_vector threads_; 41 | std::vector loops_; 42 | }; 43 | 44 | } // namespace claire 45 | 46 | #endif // _CLAIRE_COMMON_EVENTS_EVENTLOOPTHREADPOOL_H_ 47 | -------------------------------------------------------------------------------- /common/events/Poller.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_EVENTS_POLLER_H_ 6 | #define _CLAIRE_COMMON_EVENTS_POLLER_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace claire { 15 | 16 | class Poller : boost::noncopyable 17 | { 18 | public: 19 | typedef std::vector ChannelList; 20 | 21 | virtual ~Poller() {} 22 | 23 | /// Polls the I/O events. 24 | /// Must be called in the loop thread. 25 | virtual void poll(int timeout_in_milliseconds, ChannelList* active_channels) = 0; 26 | 27 | /// Changes the interested I/O events. 28 | /// Must be called in the loop thread. 29 | virtual void UpdateChannel(Channel* channel) = 0; 30 | 31 | /// Remove the channel, when it destructs. 32 | /// Must be called in the loop thread. 33 | virtual void RemoveChannel(Channel* channel) = 0; 34 | }; 35 | 36 | } // namespace claire 37 | 38 | #endif // _CLAIRE_COMMON_EVENTS_POLLER_H_ 39 | -------------------------------------------------------------------------------- /common/events/SignalSet.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_EVENTS_SIGNALSET_H_ 6 | #define _CLAIRE_COMMON_EVENTS_SIGNALSET_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace claire { 16 | 17 | class Channel; 18 | class EventLoop; 19 | 20 | class SignalSet : boost::noncopyable 21 | { 22 | public: 23 | typedef boost::function SignalHandler; 24 | 25 | SignalSet(EventLoop* loop); 26 | SignalSet(EventLoop* loop, 27 | int signal_number_1); 28 | SignalSet(EventLoop* loop, 29 | int signal_number_1, 30 | int signal_number_2); 31 | SignalSet(EventLoop* loop, 32 | int signal_number_1, 33 | int signal_number_2, 34 | int signal_number_3); 35 | ~SignalSet(); 36 | 37 | /// Add a signal_number to signalset, it will mask the signal_number in current thread 38 | void Add(int signal_number); 39 | 40 | /// Add a handler to all signals, called when receive any signal in signalset 41 | void Wait(const SignalHandler& handler); 42 | 43 | /// Remove all signals 44 | void Clear(); 45 | 46 | /// Remove all handlers 47 | void Cancel(); 48 | 49 | /// Remove a signal_number from signalset 50 | void Remove(int signal_number); 51 | 52 | private: 53 | void OnSignal(); 54 | 55 | EventLoop* loop_; 56 | std::set signals_; 57 | std::vector handlers_; 58 | 59 | int fd_; 60 | boost::scoped_ptr channel_; 61 | }; 62 | 63 | } // namespace claire 64 | 65 | #endif // _CLAIRE_COMMON_EVENTS_SIGNALSET_H_ 66 | -------------------------------------------------------------------------------- /common/events/TimerId.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_EVENTS_TIMERID_H_ 6 | #define _CLAIRE_COMMON_EVENTS_TIMERID_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace claire { 13 | 14 | class TimerId 15 | { 16 | public: 17 | TimerId() : id_(0) {} 18 | TimerId(int64_t id) : id_(id) {} 19 | 20 | void Reset() { id_ = 0; } 21 | bool Valid() const { return id_ > 0; } 22 | int64_t get() const { return id_; } 23 | 24 | void swap(TimerId& other) 25 | { 26 | std::swap(id_, other.id_); 27 | } 28 | 29 | private: 30 | int64_t id_; 31 | }; 32 | 33 | inline bool operator<(TimerId lhs, TimerId rhs) 34 | { 35 | return lhs.get() < rhs.get(); 36 | } 37 | 38 | inline bool operator==(TimerId lhs, TimerId rhs) 39 | { 40 | return lhs.get() == rhs.get(); 41 | } 42 | 43 | } // namespace claire 44 | 45 | #endif // _CLAIRE_COMMON_EVENTS_TIMERID_H_ 46 | -------------------------------------------------------------------------------- /common/events/poller/EPollPoller.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_EVENTS_POLLER_EPOLLPOLLER_H_ 6 | #define _CLAIRE_COMMON_EVENTS_POLLER_EPOLLPOLLER_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | struct epoll_event; 14 | namespace claire { 15 | 16 | class EPollPoller : public Poller 17 | { 18 | public: 19 | EPollPoller(EventLoop* loop); 20 | virtual ~EPollPoller(); 21 | 22 | virtual void poll(int timeout_in_milliseconds, ChannelList* active_channles); 23 | virtual void UpdateChannel(Channel* channel); 24 | virtual void RemoveChannel(Channel* channel); 25 | 26 | private: 27 | void Update(int operation, Channel* channel); 28 | 29 | EventLoop* loop_; 30 | int epoll_fd_; 31 | std::vector events_; 32 | std::vector channels_; 33 | }; 34 | 35 | } // namespace claire 36 | 37 | #endif // _CLAIRE_COMMON_EVENTS_POLLER_EPOLLPOLLER_H_ 38 | -------------------------------------------------------------------------------- /common/logging/LogBuffer.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | namespace claire { 8 | 9 | template 10 | const char* LogBuffer::DebugString() 11 | { 12 | *current_ = '\0'; 13 | return data_; 14 | } 15 | 16 | template 17 | void LogBuffer::CookieStart() {} 18 | template void LogBuffer::CookieEnd() {} 19 | 20 | template class LogBuffer; 21 | template class LogBuffer; 22 | 23 | } // namespace claire 24 | -------------------------------------------------------------------------------- /common/logging/LogBuffer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_LOGGING_LOGBUFFER_H_ 6 | #define _CLAIRE_COMMON_LOGGING_LOGBUFFER_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | 15 | namespace claire { 16 | 17 | const int kSmallBuffer = 4096; 18 | const int kLargeBuffer = 4096*1000; 19 | 20 | template 21 | class LogBuffer : boost::noncopyable 22 | { 23 | public: 24 | LogBuffer() 25 | : current_(data_) 26 | { 27 | set_cookie(CookieStart); 28 | } 29 | 30 | ~LogBuffer() 31 | { 32 | set_cookie(CookieEnd); 33 | } 34 | 35 | void Append(const char* d, size_t l) 36 | { 37 | // FIXME: use stack vector!!! 38 | if (static_cast(avail()) > l) 39 | { 40 | memcpy(current_, d, l); 41 | current_ += l; 42 | } 43 | else 44 | { 45 | if (avail() > 0) 46 | { 47 | memcpy(current_, d, avail()); 48 | current_ += avail(); 49 | } 50 | } 51 | } 52 | 53 | const char* data() const { return data_; } 54 | char* current() { return current_; } 55 | size_t length() const { return current_ - data_; } 56 | size_t avail() const { return end() - current_; } 57 | 58 | void Add(size_t l) 59 | { 60 | current_ += l; 61 | } 62 | 63 | void Reset() 64 | { 65 | current_ = data_; 66 | } 67 | 68 | void bzero() 69 | { 70 | ::bzero(data_, sizeof data_); 71 | } 72 | 73 | // for used by GDB 74 | const char* DebugString(); 75 | 76 | void set_cookie(void (*cookie)()) 77 | { 78 | cookie_ = cookie; 79 | } 80 | 81 | // for used by unit test 82 | std::string ToString() const 83 | { 84 | return std::string(data_, length()); 85 | } 86 | 87 | private: 88 | const char* end() const 89 | { 90 | return data_ + sizeof data_; 91 | } 92 | 93 | // Must be outline function for cookies. 94 | static void CookieStart(); 95 | static void CookieEnd(); 96 | 97 | void (*cookie_)(); 98 | 99 | char data_[SIZE]; 100 | char* current_; 101 | }; 102 | 103 | } // namespace claire 104 | 105 | #endif // _CLAIRE_COMMON_LOGGING_LOGBUFFER_H_ 106 | -------------------------------------------------------------------------------- /common/logging/LogFile.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_LOGGING_LOGFILE_H_ 6 | #define _CLAIRE_COMMON_LOGGING_LOGFILE_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace claire { 19 | 20 | class LogFile : boost::noncopyable 21 | { 22 | public: 23 | LogFile(bool thread_safe); 24 | ~LogFile(); 25 | 26 | void Append(const char* data, size_t length); 27 | void Flush(); 28 | 29 | private: 30 | void RollFile(); 31 | void DropFileMemory(); 32 | std::string GetLogFileName() const; 33 | std::string GetLinkLogFileName() const; 34 | void AppendUnLocked(const char* data, size_t length); 35 | 36 | const std::string base_name_; 37 | int count_; 38 | boost::scoped_ptr mutex_; 39 | boost::scoped_ptr file_; 40 | time_t last_period_; 41 | time_t last_roll_; 42 | time_t last_flush_; 43 | }; 44 | 45 | } // namespace claire 46 | 47 | #endif // _CLAIRE_COMMON_LOGGING_LOGFILE_H_ 48 | -------------------------------------------------------------------------------- /common/logging/LogStream.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | 9 | const static size_t kMaxNumericSize = 32; 10 | 11 | static_assert(static_cast(kMaxNumericSize - 10) > std::numeric_limits::digits10, 12 | "double limits over kMaxNumericSize"); 13 | static_assert(static_cast(kMaxNumericSize - 10) > std::numeric_limits::digits10, 14 | "long limits over kMaxNumericSize"); 15 | static_assert(static_cast(kMaxNumericSize - 10) > std::numeric_limits::digits10, 16 | "long limits over kMaxNumericSize"); 17 | static_assert(static_cast(kMaxNumericSize - 10) > std::numeric_limits::digits10, 18 | "long long limits over kMaxNumericSize"); 19 | 20 | namespace claire { 21 | 22 | template 23 | void LogStream::FormatInteger(T v) 24 | { 25 | if (buffer_.avail() >= kMaxNumericSize) 26 | { 27 | auto len = IntToBuffer(buffer_.current(), v); 28 | buffer_.Add(len); 29 | } 30 | } 31 | 32 | LogStream& LogStream::operator<<(short v) 33 | { 34 | *this<(v); 35 | return *this; 36 | } 37 | 38 | LogStream& LogStream::operator<<(unsigned short v) 39 | { 40 | *this<(v); 41 | return *this; 42 | } 43 | 44 | LogStream& LogStream::operator<<(int v) 45 | { 46 | FormatInteger(v); 47 | return *this; 48 | } 49 | 50 | LogStream& LogStream::operator<<(unsigned int v) 51 | { 52 | FormatInteger(v); 53 | return *this; 54 | } 55 | 56 | LogStream& LogStream::operator<<(long v) 57 | { 58 | FormatInteger(v); 59 | return *this; 60 | } 61 | 62 | LogStream& LogStream::operator<<(unsigned long v) 63 | { 64 | FormatInteger(v); 65 | return *this; 66 | } 67 | 68 | LogStream& LogStream::operator<<(long long v) 69 | { 70 | FormatInteger(v); 71 | return *this; 72 | } 73 | 74 | LogStream& LogStream::operator<<(unsigned long long v) 75 | { 76 | FormatInteger(v); 77 | return *this; 78 | } 79 | 80 | LogStream& LogStream::operator<<(double v) 81 | { 82 | if (buffer_.avail() >= kMaxNumericSize) 83 | { 84 | char buf[32]; 85 | snprintf(buf, sizeof buf, "%.12g", v); 86 | Append(buf, strlen(buf)); 87 | } 88 | return *this; 89 | } 90 | 91 | LogStream& LogStream::operator<<(const void* p) 92 | { 93 | auto v = reinterpret_cast(p); 94 | if (buffer_.avail() >= kMaxNumericSize) 95 | { 96 | auto current = buffer_.current(); 97 | current[0] = '0'; 98 | current[1] = 'x'; 99 | auto ret = HexToBuffer(current+2, v); 100 | buffer_.Add(ret+2); 101 | } 102 | return *this; 103 | } 104 | 105 | } // namespace claire 106 | -------------------------------------------------------------------------------- /common/logging/Logger.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_LOGGING_LOGGER_H_ 6 | #define _CLAIRE_COMMON_LOGGING_LOGGER_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace claire { 19 | 20 | /// A Logger is the interface used by logging modules to emit entries 21 | /// to a log. A typical implementation will dump formatted data to a 22 | /// sequence of files. We also provide interfaces that will forward 23 | /// the data to another thread so that the invoker never blocks. 24 | /// Implementations is thread-safe since the logging system 25 | /// may write to them from multiple threads. 26 | class Logger : boost::noncopyable 27 | { 28 | public: 29 | Logger(); 30 | 31 | ~Logger() 32 | { 33 | Stop(); 34 | } 35 | 36 | // Writes "message[0,message_len-1]" corresponding to an event that 37 | // occurred at "timestamp". 38 | // 39 | // The input message has already been formatted as deemed 40 | // appropriate by the higher level logging facility. For example, 41 | // textual log messages already contain timestamps, and the 42 | // file:linenumber header. 43 | void Append(const char* data, size_t length); 44 | 45 | void Start() 46 | { 47 | if (!running_) 48 | { 49 | running_ = true; 50 | thread_.Start(); 51 | latch_.Wait(); 52 | } 53 | } 54 | 55 | void Stop() 56 | { 57 | if (running_) 58 | { 59 | running_ = false; 60 | condition_.Notify(); 61 | thread_.Join(); 62 | } 63 | } 64 | 65 | private: 66 | void ThreadMain(); 67 | 68 | // for compiler 69 | Logger(const Logger&) = delete; 70 | void operator=(const Logger&) = delete; 71 | 72 | typedef LogBuffer Buffer; 73 | typedef boost::ptr_vector BufferVector; 74 | typedef BufferVector::auto_type BufferPtr; 75 | 76 | boost::atomic running_; 77 | 78 | Thread thread_; 79 | Mutex mutex_; 80 | Condition condition_; 81 | CountDownLatch latch_; 82 | 83 | BufferPtr current_buffer_; 84 | BufferPtr next_buffer_; 85 | BufferVector buffers_; 86 | }; 87 | 88 | } // namespace claire 89 | 90 | #endif // _CLAIRE_COMMON_LOGGIN_LOGGER_H_ 91 | -------------------------------------------------------------------------------- /common/metrics/BucketRanges.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. 6 | // Use of this source code is governed by a BSD-style license that can be 7 | // found in the LICENSE file. 8 | 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | 15 | namespace claire { 16 | 17 | void BucketRanges::set_range(size_t i, Histogram::Sample value) 18 | { 19 | DCHECK_LT(i, ranges_.size()); 20 | CHECK_GT(value, 0); 21 | ranges_[i] = value; 22 | } 23 | 24 | } // namspace claire 25 | -------------------------------------------------------------------------------- /common/metrics/BucketRanges.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. 6 | // Use of this source code is governed by a BSD-style license that can be 7 | // found in the LICENSE file. 8 | 9 | // BucketRanges stores the vector of ranges that delimit what samples are 10 | // tallied in the corresponding buckets of a histogram. Histograms that have 11 | // same ranges for all their corresponding buckets should share the same 12 | // BucketRanges object. 13 | // 14 | // E.g. A 5 buckets LinearHistogram with 1 as minimal value and 4 as maximal 15 | // value will need a BucketRanges with 6 ranges: 16 | // 0, 1, 2, 3, 4, INT_MAX 17 | // 18 | // TODO(kaiwang): Currently we keep all negative values in 0~1 bucket. Consider 19 | // changing 0 to INT_MIN. 20 | 21 | #ifndef _CLAIRE_COMMON_METRICS_BUCKETRANGES_H_ 22 | #define _CLAIRE_COMMON_METRICS_BUCKETRANGES_H_ 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include 29 | 30 | namespace claire { 31 | 32 | class BucketRanges : boost::noncopyable 33 | { 34 | public: 35 | typedef std::vector Ranges; 36 | 37 | explicit BucketRanges(size_t num_ranges) 38 | : ranges_(num_ranges, 0) {} 39 | 40 | size_t size() const { return ranges_.size(); } 41 | Histogram::Sample range(size_t i) const { return ranges_[i]; } 42 | void set_range(size_t i, Histogram::Sample value); 43 | 44 | // A bucket is defined by a consecutive pair of entries in |ranges|, so there 45 | // is one fewer bucket than there are ranges. For example, if |ranges| is 46 | // [0, 1, 3, 7, INT_MAX], then the buckets in this histogram are 47 | // [0, 1), [1, 3), [3, 7), and [7, INT_MAX). 48 | size_t bucket_count() const { return ranges_.size() - 1; } 49 | 50 | private: 51 | // A monotonically increasing list of values which determine which bucket to 52 | // put a sample into. For each index, show the smallest sample that can be 53 | // added to the corresponding bucket. 54 | Ranges ranges_; 55 | }; 56 | 57 | } // namespace claire 58 | 59 | #endif // _CLAIRE_COMMON_METRICS_BUCKETRANGES_H_ 60 | -------------------------------------------------------------------------------- /common/metrics/Counter.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. 6 | // Use of this source code is governed by a BSD-style license that can be 7 | // found in the LICENSE file. 8 | 9 | #include 10 | #include 11 | 12 | namespace claire { 13 | 14 | void Counter::Set(int value) 15 | { 16 | auto loc = GetPtr(); 17 | if (loc) 18 | { 19 | *loc = value; 20 | } 21 | } 22 | 23 | void Counter::Add(int value) 24 | { 25 | int* loc = GetPtr(); 26 | if (loc) 27 | { 28 | *loc += value; 29 | } 30 | } 31 | 32 | int* Counter::GetPtr() 33 | { 34 | if (counter_id_ == -1) 35 | { 36 | counter_id_ = CounterProvider::instance()->GetCounterId(name_); 37 | } 38 | 39 | if (counter_id_ > 0) 40 | { 41 | return CounterProvider::instance()->GetLocation(counter_id_); 42 | } 43 | 44 | return NULL; 45 | } 46 | 47 | } // namespace claire 48 | -------------------------------------------------------------------------------- /common/metrics/CounterProvider.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. 6 | // Use of this source code is governed by a BSD-style license that can be 7 | // found in the LICENSE file. 8 | 9 | #ifndef _CLAIRE_COMMON_METRICS_COUNTERPROVIDER_H_ 10 | #define _CLAIRE_COMMON_METRICS_COUNTERPROVIDER_H_ 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | namespace claire { 21 | 22 | class CounterProvider : boost::noncopyable 23 | { 24 | public: 25 | // For convenience, we create a singleton provider. This is generally 26 | // used automatically by the counters. 27 | static CounterProvider* instance(); 28 | 29 | // Find a counter in the CounterProvider 30 | // 31 | // Returns an id for the counter which can be used to call GetLocation(). 32 | // If the counter does not exist, attempts to create a row for the new 33 | // counter. If there is no space in the provider for the new counter, 34 | // returns 0. 35 | int GetCounterId(const std::string& name); 36 | 37 | // Gets the location of a particular counter of calling Thread. 38 | int* GetLocation(int counter_id); 39 | 40 | // Gets the sum of the values for a particular counter. If the counter 41 | // does not exist, creates the counter. 42 | int GetCounterValue(const std::string& name); 43 | 44 | // Convenience function to lookup a counter location for a 45 | // counter by name for the calling thread. Will register 46 | // the thread if it is not already registered. 47 | static int* GetLocation(const std::string& name); 48 | 49 | std::unordered_map GetSnapshot(); 50 | 51 | private: 52 | CounterProvider(); 53 | ~CounterProvider(); 54 | 55 | friend class Singleton; 56 | 57 | class Impl; 58 | boost::scoped_ptr impl_; 59 | }; 60 | 61 | } // namespace claire 62 | 63 | #endif // _CLAIRE_COMMON_METRICS_COUNTERPROVIDER_H_ 64 | -------------------------------------------------------------------------------- /common/metrics/CounterSampler.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _CLAIRE_COMMON_METRICS_COUNTERSAMPLER_H_ 6 | #define _CLAIRE_COMMON_METRICS_COUNTERSAMPLER_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | 21 | namespace claire { 22 | 23 | class CounterSampler : boost::noncopyable 24 | { 25 | public: 26 | CounterSampler(EventLoop* loop); 27 | void WriteJson(std::string* output); 28 | void WriteJson(std::string* output, 29 | const std::vector& metrics, 30 | int64_t since); 31 | private: 32 | typedef std::unordered_map SampleEntry; 33 | typedef std::pair Sample; 34 | typedef std::unordered_map Snapshot; 35 | 36 | void DoSample(); 37 | SampleEntry DoSnapshotDiff(const Snapshot& lhs, const Snapshot& rhs); 38 | 39 | EventLoop* loop_; 40 | Mutex mutex_; 41 | boost::circular_buffer samples_; // @GUARDBY mutex_ 42 | Snapshot last_snapshot_; 43 | }; 44 | 45 | } // namespace claire 46 | 47 | #endif // _CLAIRE_COMMON_METRICS_COUNTERSAMPLER_H_ 48 | -------------------------------------------------------------------------------- /common/metrics/HistogramRecorder.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. 6 | // Use of this source code is governed by a BSD-style license that can be 7 | // found in the LICENSE file. 8 | 9 | // HistogramRecorder holds all Histograms that are used in the system. 10 | // It provides a general place for Histograms to register, and supports 11 | // a global API for accessing (i.e., dumping, or graphing) the data. 12 | 13 | #ifndef _CLAIRE_COMMON_METRICS_HISTOGRAMRECORDER_H_ 14 | #define _CLAIRE_COMMON_METRICS_HISTOGRAMRECORDER_H_ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | namespace claire { 26 | 27 | class Histogram; 28 | 29 | class HistogramRecorder : boost::noncopyable 30 | { 31 | public: 32 | typedef std::vector Histograms; 33 | 34 | static HistogramRecorder* instance(); 35 | 36 | // Register, or add a new histogram to the collection of statistics. If an 37 | // identically named histogram is already registered, then the argument 38 | // |histogram| will deleted. The returned value is always the registered 39 | // histogram (either the argument, or the pre-existing registered histogram). 40 | Histogram* RegisterOrDeleteDuplicate(Histogram* histogram); 41 | 42 | // Methods for printing histograms. Only histograms which have query as 43 | // a substring are written to output (an empty string will process all 44 | // registered histograms). 45 | void WriteHTMLGraph(const std::string& query, std::string* output); 46 | void WriteGraph(const std::string& query, std::string* output); 47 | 48 | // Find a histogram by name. It matches the exact name. This method is thread 49 | // safe. It returns NULL if a matching histogram is not found. 50 | Histogram* FindHistogram(const std::string& name); 51 | 52 | // GetSnapshot copies some of the pointers to registered histograms into the 53 | // caller supplied vector (Histograms). Only histograms with names matching 54 | // query are returned. The query must be a substring of histogram name for its 55 | // pointer to be copied. 56 | void GetSnapshot(const std::string& query, Histograms* snapshot); 57 | 58 | private: 59 | // We keep all registered histograms in a map, from name to histogram. 60 | typedef std::map HistogramMap; 61 | 62 | HistogramRecorder() {} 63 | ~HistogramRecorder() {} 64 | 65 | friend class Singleton; 66 | 67 | Mutex mutex_; // Lock protects access to above maps. 68 | HistogramMap histograms_; 69 | }; 70 | 71 | } // namespace claire 72 | 73 | #endif // _CLAIRE_COMMON_METRICS_HISTOGRAMRECORDER_H_ 74 | -------------------------------------------------------------------------------- /common/metrics/HistogramSamples.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. 6 | // Use of this source code is governed by a BSD-style license that can be 7 | // found in the LICENSE file. 8 | 9 | #include 10 | 11 | #include 12 | 13 | namespace claire { 14 | 15 | void HistogramSamples::Add(const HistogramSamples& other) 16 | { 17 | sum_ += other.sum(); 18 | bool success = AddSubtractImpl(other.Iterator().get(), ADD); 19 | DCHECK(success); 20 | } 21 | 22 | void HistogramSamples::Subtract(const HistogramSamples& other) 23 | { 24 | sum_ -= other.sum(); 25 | bool success = AddSubtractImpl(other.Iterator().get(), SUBTRACT); 26 | DCHECK(success); 27 | } 28 | 29 | void HistogramSamples::IncreaseSum(int64_t diff) 30 | { 31 | sum_ += diff; 32 | } 33 | 34 | SampleCountIterator::~SampleCountIterator() {} 35 | 36 | bool SampleCountIterator::GetBucketIndex(size_t* index) const 37 | { 38 | DCHECK(!Done()); 39 | return false; 40 | } 41 | 42 | } // namespace claire 43 | -------------------------------------------------------------------------------- /common/metrics/HistogramSamples.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. 6 | // Use of this source code is governed by a BSD-style license that can be 7 | // found in the LICENSE file. 8 | 9 | #ifndef _CLAIRE_COMMON_METRICS_HISTOGRAMSAMPLES_H_ 10 | #define _CLAIRE_COMMON_METRICS_HISTOGRAMSAMPLES_H_ 11 | 12 | #include 13 | 14 | #include 15 | 16 | namespace claire { 17 | 18 | class SampleCountIterator; 19 | 20 | class HistogramSamples 21 | { 22 | public: 23 | HistogramSamples() 24 | : sum_(0) {} 25 | virtual ~HistogramSamples() {} 26 | 27 | virtual void Accumulate(Histogram::Sample value, 28 | Histogram::Count count) = 0; 29 | virtual Histogram::Count GetCount(Histogram::Sample value) const = 0; 30 | virtual Histogram::Count TotalCount() const = 0; 31 | 32 | virtual void Add(const HistogramSamples& other); 33 | virtual void Subtract(const HistogramSamples& other); 34 | 35 | virtual std::unique_ptr Iterator() const = 0; 36 | 37 | // Accessor fuctions. 38 | int64_t sum() const { return sum_; } 39 | 40 | protected: 41 | // Based on |op| type, add or subtract sample counts data from the iterator. 42 | enum Operator { ADD, SUBTRACT }; 43 | virtual bool AddSubtractImpl(SampleCountIterator* iter, Operator op) = 0; 44 | 45 | void IncreaseSum(int64_t diff); 46 | 47 | private: 48 | int64_t sum_; 49 | }; 50 | 51 | class SampleCountIterator 52 | { 53 | public: 54 | virtual ~SampleCountIterator(); 55 | 56 | virtual bool Done() const = 0; 57 | virtual void Next() = 0; 58 | 59 | // Get the sample and count at current position. 60 | // |min| |max| and |count| can be NULL if the value is not of interest. 61 | // Requires: !Done(); 62 | virtual void Get(Histogram::Sample* min, 63 | Histogram::Sample* max, 64 | Histogram::Count* count) const = 0; 65 | 66 | // Get the index of current histogram bucket. 67 | // For histograms that don't use predefined buckets, it returns false. 68 | // Requires: !Done(); 69 | virtual bool GetBucketIndex(size_t* index) const; 70 | }; 71 | 72 | } // namespace claire 73 | 74 | #endif // _CLAIRE_COMMON_METRICS_HISTOGRAMSAMPLES_H_ 75 | -------------------------------------------------------------------------------- /common/metrics/SampleVector.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. 6 | // Use of this source code is governed by a BSD-style license that can be 7 | // found in the LICENSE file. 8 | 9 | // SampleVector implements HistogramSamples interface. It is used by all 10 | // Histogram based classes to store samples. 11 | 12 | #ifndef _CLAIRE_COMMON_METRICS_SAMPLEVECTOR_H_ 13 | #define _CLAIRE_COMMON_METRICS_SAMPLEVECTOR_H_ 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | namespace claire { 24 | 25 | class BucketRanges; 26 | 27 | class SampleVector : boost::noncopyable, 28 | public HistogramSamples 29 | { 30 | public: 31 | explicit SampleVector(const BucketRanges* bucket_ranges); 32 | virtual ~SampleVector() {} 33 | 34 | // HistogramSamples implementation: 35 | virtual void Accumulate(Histogram::Sample value, 36 | Histogram::Count count); 37 | virtual Histogram::Count GetCount(Histogram::Sample value) const; 38 | virtual Histogram::Count TotalCount() const; 39 | virtual std::unique_ptr Iterator() const; 40 | 41 | // Get count of a specific bucket. 42 | Histogram::Count GetCountAtIndex(size_t index) const; 43 | 44 | protected: 45 | virtual bool AddSubtractImpl( 46 | SampleCountIterator* iter, 47 | HistogramSamples::Operator op); // |op| is ADD or SUBTRACT. 48 | 49 | virtual size_t GetBucketIndex(Histogram::Sample value) const; 50 | 51 | private: 52 | std::vector counts_; 53 | // Shares the same BucketRanges with Histogram object. 54 | const BucketRanges* const bucket_ranges_; 55 | }; 56 | 57 | class SampleVectorIterator : public SampleCountIterator 58 | { 59 | public: 60 | SampleVectorIterator(const std::vector* counts, 61 | const BucketRanges* bucket_ranges); 62 | virtual ~SampleVectorIterator(); 63 | 64 | // SampleCountIterator implementation: 65 | virtual bool Done() const; 66 | virtual void Next(); 67 | virtual void Get(Histogram::Sample* min, 68 | Histogram::Sample* max, 69 | Histogram::Count* count) const; 70 | 71 | // SampleVector uses predefined buckets, so iterator can return bucket index. 72 | virtual bool GetBucketIndex(size_t* index) const; 73 | 74 | private: 75 | void SkipEmptyBuckets(); 76 | 77 | const std::vector* counts_; 78 | const BucketRanges* bucket_ranges_; 79 | 80 | size_t index_; 81 | }; 82 | 83 | } // namespace claire 84 | 85 | #endif // _CLAIRE_COMMON_METRICS_SAMPLEVECTOR_H_ 86 | -------------------------------------------------------------------------------- /common/protobuf/ProtobufIO.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_PROTOBUF_PROTOBUFIO_H_ 6 | #define _CLAIRE_COMMON_PROTOBUF_PROTOBUFIO_H_ 7 | 8 | #include 9 | 10 | namespace google { 11 | namespace protobuf { 12 | 13 | class Message; 14 | } // namespace protobuf 15 | } // namespace google 16 | 17 | namespace claire { 18 | 19 | class StringPiece; 20 | 21 | bool SerializeToJson(const ::google::protobuf::Message& message, 22 | std::string* output); 23 | 24 | bool ParseFromJson(const StringPiece& json, 25 | ::google::protobuf::Message* message); 26 | 27 | 28 | } // namespace claire 29 | 30 | #endif // _CLAIRE_COMMON_PROTOBUF_PROTOBUFIO_H_ 31 | -------------------------------------------------------------------------------- /common/strings/StringPrintf.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | // Copyright 2013 The Chromium Authors. All rights reserved. 6 | // Use of this source code is governed by a BSD-style license that can be 7 | // found in the LICENSE file. 8 | 9 | #ifndef _CLAIRE_COMMON_STRINGS_STRINGPRINTF_H_ 10 | #define _CLAIRE_COMMON_STRINGS_STRINGPRINTF_H_ 11 | 12 | #include // va_list 13 | 14 | #include 15 | 16 | namespace claire { 17 | 18 | // Return a C++ string given printf-like input. 19 | std::string StringPrintf(const char* format, ...) 20 | __attribute__((format(printf, 1, 2))); 21 | 22 | // Return a C++ string given vprintf-like input. 23 | std::string StringPrintV(const char* format, va_list ap) 24 | __attribute__((format(printf, 1, 0))); 25 | 26 | // Store result into a supplied string and return it. 27 | const std::string& SStringPrintf(std::string* dst, 28 | const char* format, ...) 29 | __attribute__((format(printf, 2, 3))); 30 | 31 | // Append result to a supplied string. 32 | void StringAppendF(std::string* dst, const char* format, ...) 33 | __attribute__((format(printf, 2, 3))); 34 | 35 | // Lower-level routine that takes a va_list and appends to a specified 36 | // string. All other routines are just convenience wrappers around it. 37 | void StringAppendV(std::string* dst, const char* format, va_list ap) 38 | __attribute__((format(printf, 2, 0))); 39 | 40 | } // namespace claire 41 | 42 | #endif // _CLAIRE_COMMON_STRINGS_STRINGPRINTF_H_ 43 | -------------------------------------------------------------------------------- /common/strings/StringUtil.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_STRINGS_STRINGUTIL_H_ 6 | #define _CLAIRE_COMMON_STRINGS_STRINGUTIL_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace claire { 12 | 13 | template 14 | size_t IntToBuffer(char buffer[], T value); 15 | size_t HexToBuffer(char buffer[], uintptr_t value); 16 | 17 | size_t HexString(char buffer[], size_t size, 18 | const char *str, size_t length); 19 | 20 | } // namespace claire 21 | 22 | #endif // _CLAIRE_COMMON_STRINGS_STRINGUTIL_H_ 23 | -------------------------------------------------------------------------------- /common/strings/UriEscape.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | // 6 | // Copyright 2013 Facebook, Inc. 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #ifndef _CLAIRE_COMMON_STRINGS_URIESCAPE_H_ 22 | #define _CLAIRE_COMMON_STRINGS_URIESCAPE_H_ 23 | 24 | #include 25 | 26 | #include 27 | 28 | namespace claire { 29 | 30 | enum class EscapeMode : char 31 | { 32 | // The values are meaningful, see generate_escape_tables.py 33 | ALL = 0, 34 | QUERY = 1, 35 | PATH = 2 36 | }; 37 | 38 | /// 39 | /// URI-escape a string. Appends the result to the output string. 40 | /// 41 | /// Alphanumeric characters and other characters marked as "unreserved" in RFC 42 | /// 3986 ( -_.~ ) are left unchanged. In PATH mode, the forward slash (/) is 43 | /// also left unchanged. In QUERY mode, spaces are replaced by '+'. All other 44 | /// characters are percent-encoded. 45 | /// 46 | void UriEscape(const StringPiece& input, 47 | std::string* output, 48 | EscapeMode mode); 49 | 50 | inline std::string UriEscape(const StringPiece& input, EscapeMode mode) 51 | { 52 | std::string output; 53 | UriEscape(input, &output, mode); 54 | return output; 55 | } 56 | 57 | /// 58 | /// URI-unescape a string. Appends the result to the output string. 59 | /// 60 | /// In QUERY mode, '+' are replaced by space. %XX sequences are decoded if 61 | /// XX is a valid hex sequence, otherwise we throw invalid_argument. 62 | /// 63 | void UriUnescape(const StringPiece& input, 64 | std::string* output, 65 | EscapeMode mode); 66 | 67 | inline std::string UriUnescape(const StringPiece& input, EscapeMode mode) 68 | { 69 | std::string output; 70 | UriUnescape(input, &output, mode); 71 | return output; 72 | } 73 | 74 | } // namespace claire 75 | 76 | #endif // _CLAIRE_COMMON_STRINGS_URIESCAPE_H_ 77 | -------------------------------------------------------------------------------- /common/symbolizer/Symbolizer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | // 6 | // Copyright 2013 Facebook, Inc. 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #ifndef _CLAIRE_COMMON_SYMBOLIZER_SYMBOLIZER_H_ 22 | #define _CLAIRE_COMMON_SYMBOLIZER_SYMBOLIZER_H_ 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | namespace claire { 36 | 37 | /// Convert an address to symbol name and source location. 38 | class Symbolizer : boost::noncopyable 39 | { 40 | public: 41 | /// Symbolize an instruction pointer address, returning the symbol name 42 | /// and file/line number information. 43 | /// 44 | /// The returned StringPiece objects are valid for the lifetime of 45 | /// this Symbolizer object. 46 | bool Symbolize(uintptr_t address, 47 | StringPiece* symbol_name, 48 | Dwarf::LocationInfo* location); 49 | 50 | static void Write(std::string* out, 51 | uintptr_t address, 52 | const StringPiece& symbol_name, 53 | const Dwarf::LocationInfo& location); 54 | 55 | private: 56 | ElfFile* GetFile(const std::string& name); 57 | // cache open ELF files 58 | boost::ptr_map elf_files_; 59 | }; 60 | 61 | } // namespace claire 62 | 63 | #endif // _CLAIRE_COMMON_SYMBOLIZER_SYMBOLIZER_H_ 64 | -------------------------------------------------------------------------------- /common/system/ThisProcess.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | #include // snprintf 9 | #include 10 | 11 | namespace claire { 12 | namespace ThisProcess { 13 | 14 | pid_t pid() 15 | { 16 | return ::getpid(); 17 | } 18 | 19 | std::string pid_string() 20 | { 21 | char pid[32]; 22 | snprintf(pid, sizeof pid, "%d", ::getpid()); 23 | return pid; 24 | } 25 | 26 | std::string User() 27 | { 28 | struct passwd pwd; 29 | struct passwd* result = NULL; 30 | char buf[8192]; 31 | const char* user = "unknownuser"; 32 | 33 | ::getpwuid_r(::getuid(), &pwd, buf, sizeof buf, &result); 34 | if (result) 35 | { 36 | user = pwd.pw_name; 37 | } 38 | return user; 39 | } 40 | 41 | std::string Host() 42 | { 43 | char host[64] = "unknownhost"; 44 | host[sizeof(host)-1] = '\0'; 45 | ::gethostname(host, sizeof host); 46 | return host; 47 | } 48 | 49 | } // namespace ThisProcess 50 | } // namespace claire 51 | -------------------------------------------------------------------------------- /common/system/ThisProcess.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_SYSTEM_THISPROCESS_H_ 6 | #define _CLAIRE_COMMON_SYSTEM_THISPROCESS_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace claire { 13 | namespace ThisProcess { 14 | 15 | pid_t pid(); 16 | std::string pid_string(); 17 | 18 | std::string User(); 19 | std::string Host(); 20 | 21 | } // namespace ThisProcess 22 | } // namespace claire 23 | 24 | #endif // _CLAIRE_COMMON_SYSTEM_THISPROCESS_H_ 25 | -------------------------------------------------------------------------------- /common/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(logger_test Logger_test.cc) 2 | target_link_libraries(logger_test claire_common) 3 | 4 | add_executable(timeoutqueue_test TimeoutQueue_test.cc) 5 | target_link_libraries(timeoutqueue_test claire_common) 6 | 7 | add_executable(symbolizer_test Symbolizer_test.cc) 8 | target_link_libraries(symbolizer_test claire_common boost_regex) 9 | -------------------------------------------------------------------------------- /common/tests/Logger_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The Claire Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | void bench() 14 | { 15 | std::string str(150, 'X'); 16 | str += " "; 17 | int cnt = 0; 18 | 19 | for (int i = 0;i < 30; i++) 20 | { 21 | auto start = claire::Timestamp::Now(); 22 | for (int j = 0;j < 1000;j++) 23 | { 24 | LOG(INFO) << "Hello, World" << cnt << str; 25 | cnt++; 26 | } 27 | auto end = claire::Timestamp::Now(); 28 | 29 | printf("tid: %d, %f\n", claire::ThisThread::tid(), static_cast(claire::TimeDifference(end, start)) / 1000) ; 30 | struct timespec ts = {0, 500 * 1000 * 1000}; 31 | nanosleep(&ts, NULL); 32 | } 33 | } 34 | 35 | int main(int argc, char* argv[]) 36 | { 37 | ::google::ParseCommandLineFlags(&argc, &argv, true); 38 | claire::InitClaireLogging(argv[0]); 39 | 40 | sleep(30); 41 | claire::ThreadPool pool("logger_test"); 42 | pool.Start(5); 43 | pool.Run(bench); 44 | pool.Run(bench); 45 | pool.Run(bench); 46 | pool.Run(bench); 47 | pool.Run(bench); 48 | 49 | sleep(6); 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /common/tests/Symbolizer_test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace claire; 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | Symbolizer s; 10 | StringPiece name; 11 | Dwarf::LocationInfo location; 12 | CHECK(s.Symbolize(reinterpret_cast(main), &name, &location)); 13 | LOG(INFO) << name << " " << location.file.ToString() << " " << location.line << " (" 14 | << location.main_file.ToString() << ")"; 15 | return 0; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /common/tests/TimeoutQueue_test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | using namespace claire; 10 | 11 | int cnt = 0; 12 | EventLoop* g_loop; 13 | 14 | void print(const char* msg) 15 | { 16 | printf("msg %s %s\n", Timestamp::Now().ToFormattedString().c_str(), msg); 17 | if (++cnt == 20) 18 | { 19 | g_loop->quit(); 20 | } 21 | } 22 | 23 | void cancel(TimerId timer) 24 | { 25 | g_loop->Cancel(timer); 26 | printf("cancelled at %s\n", Timestamp::Now().ToString().c_str()); 27 | } 28 | 29 | int main() 30 | { 31 | sleep(1); 32 | { 33 | EventLoop loop; 34 | g_loop = &loop; 35 | 36 | loop.RunAfter(1000, boost::bind(print, "once1")); 37 | loop.RunAfter(1500, boost::bind(print, "once1.5")); 38 | loop.RunAfter(2000, boost::bind(print, "once2")); 39 | loop.RunAfter(2500, boost::bind(print, "once2.5")); 40 | auto id = loop.RunAfter(3000, boost::bind(print, "once3")); 41 | loop.RunAfter(2700, boost::bind(cancel, id)); 42 | 43 | auto id2 = loop.RunEvery(4000, boost::bind(print, "every4")); 44 | loop.RunAfter(9000, boost::bind(cancel, id2)); 45 | loop.RunAfter(9500, boost::bind(cancel, id2)); 46 | 47 | loop.RunEvery(2000, boost::bind(print, "every2")); 48 | loop.loop(); 49 | print("main loop exits"); 50 | } 51 | 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /common/threading/Condition.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_THREADING_CONDITION_H_ 6 | #define _CLAIRE_COMMON_THREADING_CONDITION_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace claire { 16 | 17 | class Condition : boost::noncopyable 18 | { 19 | public: 20 | explicit Condition(Mutex& mutex) 21 | : mutex_(mutex) 22 | { 23 | DCHECK_ERR(pthread_cond_init(&pcond_, NULL)); 24 | } 25 | 26 | ~Condition() 27 | { 28 | DCHECK_ERR(pthread_cond_destroy(&pcond_)); 29 | } 30 | 31 | void Wait() 32 | { 33 | Mutex::UnAssignGuard ug(mutex_); 34 | DCHECK_ERR(pthread_cond_wait(&pcond_, &(mutex_.mutex_))); 35 | } 36 | 37 | // return true if timeout, otherwise return false 38 | bool WaitForSeconds(int seconds) 39 | { 40 | struct timespec abstime; 41 | ::clock_gettime(CLOCK_REALTIME, &abstime); 42 | abstime.tv_sec += seconds; 43 | Mutex::UnAssignGuard ug(mutex_); 44 | return ETIMEDOUT == pthread_cond_timedwait(&pcond_, &(mutex_.mutex_), &abstime); 45 | } 46 | 47 | void Notify() 48 | { 49 | DCHECK_ERR(pthread_cond_signal(&pcond_)); 50 | } 51 | 52 | void NotifyAll() 53 | { 54 | DCHECK_ERR(pthread_cond_broadcast(&pcond_)); 55 | } 56 | 57 | private: 58 | Mutex& mutex_; 59 | pthread_cond_t pcond_; 60 | }; 61 | 62 | } // namespace claire 63 | 64 | #endif // _CLAIRE_COMMON_THREADING_CONDITION_H_ 65 | -------------------------------------------------------------------------------- /common/threading/CountDownLatch.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_THREADING_COUNTDOWNLATCH_H_ 6 | #define _CLAIRE_COMMON_THREADING_COUNTDOWNLATCH_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | namespace claire { 14 | 15 | class CountDownLatch : boost::noncopyable 16 | { 17 | public: 18 | explicit CountDownLatch(int c) 19 | : mutex_(), 20 | condition_(mutex_), 21 | count_(c) 22 | {} 23 | 24 | void Wait() 25 | { 26 | MutexLock lock(mutex_); 27 | while (count_ > 0) 28 | { 29 | condition_.Wait(); 30 | } 31 | } 32 | 33 | void CountDown() 34 | { 35 | MutexLock lock(mutex_); 36 | --count_; 37 | if (count_ == 0) 38 | { 39 | condition_.NotifyAll(); 40 | } 41 | } 42 | 43 | int count() const 44 | { 45 | MutexLock lock(mutex_); 46 | return count_; 47 | } 48 | 49 | private: 50 | mutable Mutex mutex_; 51 | Condition condition_; 52 | int count_; 53 | }; 54 | 55 | } // namespace claire 56 | 57 | #endif // _CLAIRE_COMMON_THREADING_COUNTDOWNLATCH_H_ 58 | -------------------------------------------------------------------------------- /common/threading/Mutex.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace claire { 12 | 13 | Mutex::Mutex() 14 | : holder_(0) 15 | { 16 | #ifndef NDEBUG 17 | DCHECK_ERR(pthread_mutexattr_init(&attr_)); 18 | DCHECK_ERR(pthread_mutexattr_settype(&attr_, PTHREAD_MUTEX_ERRORCHECK)); 19 | DCHECK_ERR(pthread_mutex_init(&mutex_, &attr_)); 20 | #else 21 | DCHECK_ERR(pthread_mutex_init(&mutex_, NULL)); 22 | #endif 23 | } 24 | 25 | Mutex::~Mutex() 26 | { 27 | DCHECK_ERR(pthread_mutex_destroy(&mutex_)); 28 | #ifndef NDEBUG 29 | DCHECK_ERR(pthread_mutexattr_destroy(&attr_)); 30 | #endif 31 | } 32 | 33 | void Mutex::Lock() 34 | { 35 | DCHECK_ERR(pthread_mutex_lock(&mutex_)); 36 | AssignHolder(); 37 | } 38 | 39 | void Mutex::Unlock() 40 | { 41 | UnAssignHolder(); 42 | DCHECK_ERR(pthread_mutex_unlock(&mutex_)); 43 | } 44 | 45 | bool Mutex::IsLockedByThisThread() const 46 | { 47 | return holder_ == ThisThread::tid(); 48 | } 49 | 50 | void Mutex::AssertLocked() const 51 | { 52 | assert(IsLockedByThisThread()); 53 | } 54 | 55 | void Mutex::AssignHolder() 56 | { 57 | holder_ = ThisThread::tid(); 58 | } 59 | 60 | void Mutex::UnAssignHolder() 61 | { 62 | holder_ = 0; 63 | } 64 | 65 | } // namespace claire 66 | -------------------------------------------------------------------------------- /common/threading/Mutex.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_THREADING_MUTEX_H_ 6 | #define _CLAIRE_COMMON_THREADING_MUTEX_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace claire { 13 | 14 | class Mutex : boost::noncopyable 15 | { 16 | public: 17 | Mutex(); 18 | ~Mutex(); 19 | 20 | void Lock(); 21 | void Unlock(); 22 | 23 | bool IsLockedByThisThread() const; 24 | void AssertLocked() const; 25 | 26 | private: 27 | friend class Condition; 28 | 29 | class UnAssignGuard 30 | { 31 | public: 32 | UnAssignGuard(Mutex& owner) 33 | : owner_(owner) 34 | { 35 | owner_.UnAssignHolder(); 36 | } 37 | 38 | ~UnAssignGuard() 39 | { 40 | owner_.AssignHolder(); 41 | } 42 | 43 | private: 44 | Mutex& owner_; 45 | }; 46 | 47 | void AssignHolder(); 48 | void UnAssignHolder(); 49 | 50 | pthread_mutex_t mutex_; 51 | #ifndef NDEBUG 52 | pthread_mutexattr_t attr_; 53 | #endif 54 | pid_t holder_; 55 | }; 56 | 57 | class MutexLock : boost::noncopyable 58 | { 59 | public: 60 | explicit MutexLock(Mutex& mutex) 61 | : mutex_(mutex) 62 | { 63 | mutex_.Lock(); 64 | } 65 | 66 | ~MutexLock() 67 | { 68 | mutex_.Unlock(); 69 | } 70 | 71 | private: 72 | Mutex& mutex_; 73 | }; 74 | 75 | } // namespace claire 76 | 77 | #endif // _CLAIRE_COMMON_THREADING_MUTEX_H_ 78 | -------------------------------------------------------------------------------- /common/threading/Singleton.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-comomn Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_THREADING_SINGLETON_H_ 6 | #define _CLAIRE_COMMON_THREADING_SINGLETON_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace claire { 14 | 15 | template 16 | class Singleton : boost::noncopyable 17 | { 18 | public: 19 | static T* instance() 20 | { 21 | pthread_once(&ponce_, &Singleton::Init); 22 | return value_; 23 | } 24 | 25 | private: 26 | Singleton(); 27 | ~Singleton(); 28 | 29 | static void Init() 30 | { 31 | static_assert(sizeof(T) > 0, "T must be complete type"); 32 | value_ = new T(); 33 | ::atexit(Destroy); 34 | } 35 | 36 | static void Destroy() 37 | { 38 | delete value_; 39 | } 40 | 41 | private: 42 | static pthread_once_t ponce_; 43 | static T* value_; 44 | }; 45 | 46 | template 47 | pthread_once_t Singleton::ponce_ = PTHREAD_ONCE_INIT; 48 | 49 | template 50 | T* Singleton::value_ = NULL; 51 | 52 | } // namespace claire 53 | 54 | #endif // _CLAIRE_COMMON_THREADING_SINGLETON_H_ -------------------------------------------------------------------------------- /common/threading/ThisThread.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | namespace claire { 19 | namespace ThisThread { 20 | 21 | namespace { 22 | 23 | pid_t gettid() 24 | { 25 | return static_cast(::syscall(SYS_gettid)); 26 | } 27 | 28 | void after_fork() 29 | { 30 | claire::ThisThread::t_cached_tid = 0; 31 | claire::ThisThread::t_thread_name = "main"; 32 | claire::ThisThread::tid(); 33 | } 34 | 35 | class ThreadNameInitializer 36 | { 37 | public: 38 | ThreadNameInitializer() 39 | { 40 | claire::ThisThread::t_thread_name = "main"; 41 | claire::ThisThread::tid(); 42 | pthread_atfork(NULL, NULL, &after_fork); 43 | } 44 | }; 45 | 46 | ThreadNameInitializer initializer; 47 | 48 | } // namespace 49 | 50 | 51 | __thread int t_cached_tid = 0; 52 | __thread char t_tid_string[32]; 53 | __thread const char* t_thread_name = "unknown"; 54 | 55 | static_assert(boost::is_same::value, "pid_t should equal int"); 56 | 57 | void CacheTid() 58 | { 59 | if (t_cached_tid == 0) 60 | { 61 | t_cached_tid = gettid(); 62 | int n = snprintf(t_tid_string, sizeof t_tid_string, "%5d ", t_cached_tid); 63 | assert(n == 6); 64 | (void) n; 65 | } 66 | } 67 | 68 | bool IsMainThread() 69 | { 70 | return tid() == ::getpid(); 71 | } 72 | 73 | void SleepForMicroSeconds(int64_t microseconds) 74 | { 75 | struct timespec ts = {0, 0}; 76 | ts.tv_sec = static_cast(microseconds/10000000); 77 | ts.tv_nsec = static_cast(microseconds%1000000 * 1000); 78 | ::nanosleep(&ts, NULL); 79 | } 80 | 81 | } // namespace ThisThread 82 | } // namespace claire 83 | -------------------------------------------------------------------------------- /common/threading/ThisThread.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_THREADING_THISTHREAD_H_ 6 | #define _CLAIRE_COMMON_THREADING_THISTHREAD_H_ 7 | 8 | #include 9 | 10 | namespace claire { 11 | namespace ThisThread { 12 | 13 | extern __thread int t_cached_tid; 14 | extern __thread char t_tid_string[32]; 15 | extern __thread const char* t_thread_name; 16 | 17 | void CacheTid(); 18 | bool IsMainThread(); 19 | void SleepForMicroSeconds(int64_t microseconds); 20 | 21 | inline int tid() 22 | { 23 | if (t_cached_tid == 0) 24 | { 25 | CacheTid(); 26 | } 27 | 28 | return t_cached_tid; 29 | } 30 | 31 | inline const char* tid_string() 32 | { 33 | return t_tid_string; 34 | } 35 | 36 | inline const char* thread_name() 37 | { 38 | return t_thread_name; 39 | } 40 | 41 | inline void set_thread_name(const char* thread_name) 42 | { 43 | t_thread_name = thread_name; 44 | } 45 | 46 | } // namespace ThisThread 47 | } // namespace claire 48 | 49 | #endif // _CLAIRE_COMMON_THREADING_THISTHREAD_H_ 50 | -------------------------------------------------------------------------------- /common/threading/Thread.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_THREADING_THREAD_H_ 6 | #define _CLAIRE_COMMON_THREADING_THREAD_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace claire { 17 | 18 | class Thread : boost::noncopyable 19 | { 20 | public: 21 | typedef boost::function ThreadEntry; 22 | 23 | explicit Thread(const ThreadEntry&, const std::string&); 24 | explicit Thread(ThreadEntry&&, const std::string&); 25 | ~Thread(); 26 | 27 | void Start(); 28 | int Join(); 29 | 30 | bool started() const { return started_; } 31 | pid_t tid() const { return *tid_; } 32 | const std::string& name() const { return name_; } 33 | 34 | private: 35 | struct Priv; 36 | 37 | bool started_; 38 | bool joined_; 39 | pthread_t pthread_id_; 40 | boost::shared_ptr tid_; 41 | ThreadEntry entry_; 42 | const std::string name_; 43 | }; 44 | 45 | } // namespace claire 46 | 47 | #endif // _CLAIRE_COMMON_THREAD_THREAD_H_ 48 | -------------------------------------------------------------------------------- /common/threading/ThreadPool.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_THREADING_THREADPOOL_H_ 6 | #define _CLAIRE_COMMON_THREADING_THREADPOOL_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace claire { 21 | 22 | class ThreadPool : boost::noncopyable 23 | { 24 | public: 25 | typedef boost::function Task; 26 | 27 | explicit ThreadPool(const std::string& name); 28 | ~ThreadPool(); 29 | 30 | // must called before Start 31 | void set_max_queue_size(int max_size) { max_queue_size_ = max_size; } 32 | 33 | void Start(int num_threads); 34 | void Stop(); 35 | 36 | void Run(const Task& task); 37 | void Run(Task&& task); 38 | 39 | private: 40 | typedef std::pair Entry; 41 | 42 | bool IsFull() const; 43 | Entry Take(); 44 | void RunInThread(); 45 | 46 | Mutex mutex_; 47 | Condition not_empty_; 48 | Condition not_full_; 49 | 50 | const std::string name_; 51 | boost::ptr_vector threads_; 52 | std::deque queue_; 53 | size_t max_queue_size_; 54 | boost::atomic running_; 55 | }; 56 | 57 | } // namespace claire 58 | 59 | #endif // _CLAIRE_COMMON_THREADING_THREADPOOL_H_ 60 | -------------------------------------------------------------------------------- /common/time/Timestamp.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #define __STDC_FORMAT_MACROS 10 | #include 11 | #undef __STDC_FORMAT_MACROS 12 | 13 | namespace claire { 14 | 15 | static_assert(sizeof(Timestamp) == sizeof(int64_t), "Timestamp size not equal int64_t"); 16 | 17 | std::string Timestamp::ToString() const 18 | { 19 | auto seconds = microseconds_since_epoch_ / kMicroSecondsPerSecond; 20 | auto microseconds = microseconds_since_epoch_ % kMicroSecondsPerSecond; 21 | 22 | char time[32]; 23 | snprintf(time, sizeof(time)-1, "%" PRId64 ".%06" PRId64 "", seconds, microseconds); 24 | return time; 25 | } 26 | 27 | std::string Timestamp::ToFormattedString() const 28 | { 29 | auto seconds = static_cast(microseconds_since_epoch_ / kMicroSecondsPerSecond); 30 | auto microseconds = static_cast(microseconds_since_epoch_ % kMicroSecondsPerSecond); 31 | struct tm tm_time; 32 | ::gmtime_r(&seconds, &tm_time); 33 | 34 | char time[32]; 35 | snprintf(time, sizeof(time), "%4d%02d%02d %02d:%02d:%02d.%06d", 36 | tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday, 37 | tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, 38 | microseconds); 39 | return time; 40 | } 41 | 42 | Timestamp Timestamp::Now() 43 | { 44 | struct timeval tv; 45 | ::gettimeofday(&tv, NULL); 46 | return Timestamp(tv.tv_sec * kMicroSecondsPerSecond + tv.tv_usec); 47 | } 48 | 49 | } // namespace claire 50 | -------------------------------------------------------------------------------- /common/time/Timestamp.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_TIME_TIMESTAMP_H_ 6 | #define _CLAIRE_COMMON_TIME_TIMESTAMP_H_ 7 | 8 | #include 9 | 10 | namespace claire { 11 | 12 | /// 13 | /// Time stamp in UTC, in microseconds resolution. 14 | /// 15 | /// This class is immutable. 16 | /// It's recommended to pass it by value, since it's passed in register on x64. 17 | /// 18 | class Timestamp : boost::less_than_comparable 19 | { 20 | public: 21 | static const int kMicroSecondsPerSecond = 1000 * 1000; 22 | 23 | /// 24 | /// Constucts an invalid Timestamp. 25 | /// 26 | Timestamp() 27 | : microseconds_since_epoch_(0) {} 28 | 29 | /// 30 | /// Constucts a Timestamp at specific time 31 | /// 32 | /// @param microseconds_since_epoch 33 | explicit Timestamp(int64_t microseconds_since_epoch) 34 | : microseconds_since_epoch_(microseconds_since_epoch) {} 35 | 36 | void swap(Timestamp& other) 37 | { 38 | std::swap(microseconds_since_epoch_, other.microseconds_since_epoch_); 39 | } 40 | 41 | std::string ToString() const; 42 | std::string ToFormattedString() const; 43 | 44 | bool Valid() const 45 | { 46 | return microseconds_since_epoch_ > 0; 47 | } 48 | 49 | time_t SecondsSinceEpoch() const 50 | { 51 | return static_cast(microseconds_since_epoch_/kMicroSecondsPerSecond); 52 | } 53 | 54 | int64_t MicroSecondsSinceEpoch() const 55 | { 56 | return microseconds_since_epoch_; 57 | } 58 | 59 | static Timestamp Now(); 60 | static Timestamp Invalid() 61 | { 62 | return Timestamp(); 63 | } 64 | 65 | private: 66 | int64_t microseconds_since_epoch_; 67 | }; 68 | 69 | inline bool operator<(Timestamp lhs, Timestamp rhs) 70 | { 71 | return lhs.MicroSecondsSinceEpoch() < rhs.MicroSecondsSinceEpoch(); 72 | } 73 | 74 | inline bool operator==(Timestamp lhs, Timestamp rhs) 75 | { 76 | return lhs.MicroSecondsSinceEpoch() == rhs.MicroSecondsSinceEpoch(); 77 | } 78 | 79 | /// Gets time difference of two timestamps, result in microseconds 80 | inline int64_t TimeDifference(Timestamp high, Timestamp low) 81 | { 82 | return (high.MicroSecondsSinceEpoch() - low.MicroSecondsSinceEpoch()); 83 | } 84 | 85 | /// @return timestamp + microseconds 86 | inline Timestamp AddTime(Timestamp timestamp, int64_t microseconds) 87 | { 88 | return Timestamp(timestamp.MicroSecondsSinceEpoch() + microseconds); 89 | } 90 | 91 | } // namespace claire 92 | 93 | #endif // _CLAIRE_COMMON_TIME_TIMESTAMP_H_ 94 | -------------------------------------------------------------------------------- /common/tracing/Trace.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | namespace claire { 14 | 15 | namespace { 16 | 17 | int64_t UniqueId() 18 | { 19 | // thread safe 20 | static boost::random::mt19937 generator; 21 | static boost::random::uniform_int_distribution distribution(1, 2L<<56); 22 | return distribution(generator); 23 | } 24 | 25 | } // namespace 26 | 27 | //static 28 | Trace* Trace::FactoryGet(const std::string& name) 29 | { 30 | return FactoryGet(name, UniqueId(), UniqueId(), 0); 31 | } 32 | 33 | Trace* Trace::FactoryGet(const std::string& name, 34 | int64_t trace_id, 35 | int64_t span_id) 36 | { 37 | return FactoryGet(name, trace_id, span_id, 0); 38 | } 39 | 40 | Trace* Trace::FactoryGet(const std::string& name, 41 | int64_t trace_id, 42 | int64_t span_id, 43 | int64_t parent_span_id) 44 | { 45 | auto trace = new Trace(name, trace_id, span_id, parent_span_id); 46 | return TraceRecorder::instance()->RegisterOrDeleteDuplicate(trace); 47 | } 48 | 49 | Trace::Trace(const std::string& name__, 50 | int64_t trace_id__, 51 | int64_t span_id__, 52 | int64_t parent_span_id__) 53 | : name_(name__), 54 | trace_id_(trace_id__), 55 | span_id_(span_id__), 56 | parent_span_id_(parent_span_id__) 57 | {} 58 | 59 | void Trace::Record(const Annotation& annotation) 60 | { 61 | LOG(DEBUG) << "Trace " << trace_id_ << ", " << span_id_ << " " << annotation.value << " at " << annotation.timestamp.MicroSecondsSinceEpoch() 62 | << " for " << host_.service_name; 63 | OutputTrace(*this, annotation); 64 | } 65 | 66 | void Trace::Record(const BinaryAnnotation& annotation) 67 | { 68 | LOG(DEBUG) << "Trace " << trace_id_ << ", " << span_id_ << " " << annotation.value 69 | << " for " << host_.service_name; 70 | OutputTrace(*this, annotation); 71 | } 72 | 73 | Trace* Trace::MakeChild(const std::string& name__) 74 | { 75 | return FactoryGet(name__, trace_id_, span_id_+1, span_id_); 76 | } 77 | 78 | } // namespace claire 79 | -------------------------------------------------------------------------------- /common/tracing/TraceContext.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | namespace claire { 8 | namespace ThisThread { 9 | 10 | __thread int64_t tTraceId = 0; 11 | __thread int64_t tSpanId = 0; 12 | 13 | void SetTraceContext(int64_t trace_id, int64_t span_id) 14 | { 15 | tTraceId = trace_id; 16 | tSpanId = span_id; 17 | } 18 | 19 | void SetTraceContext(const TraceContext& context) 20 | { 21 | tTraceId = context.first; 22 | tSpanId = context.second; 23 | } 24 | 25 | TraceContext GetTraceContext() 26 | { 27 | return std::make_pair(tTraceId, tSpanId); 28 | } 29 | void ResetTraceContext() 30 | { 31 | tTraceId = 0; 32 | tSpanId = 0; 33 | } 34 | 35 | } // namespace ThisThread 36 | } // namespace claire 37 | -------------------------------------------------------------------------------- /common/tracing/TraceContext.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_TRACING_TRACECONTEXT_H_ 6 | #define _CLAIRE_COMMON_TRACING_TRACECONTEXT_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace claire { 13 | 14 | typedef std::pair TraceContext; 15 | 16 | namespace ThisThread { 17 | 18 | void SetTraceContext(int64_t trace_id, int64_t span_id); 19 | void SetTraceContext(const TraceContext& context); 20 | TraceContext GetTraceContext(); 21 | void ResetTraceContext(); 22 | 23 | } // namespace claire 24 | 25 | class TraceContextGuard 26 | { 27 | public: 28 | TraceContextGuard() {} // context has been set 29 | 30 | TraceContextGuard(int64_t trace_id, int64_t span_id) 31 | { 32 | ThisThread::SetTraceContext(trace_id, span_id); 33 | } 34 | 35 | explicit TraceContextGuard(const TraceContext& context) 36 | { 37 | ThisThread::SetTraceContext(context); 38 | } 39 | 40 | ~TraceContextGuard() 41 | { 42 | ThisThread::ResetTraceContext(); 43 | } 44 | }; 45 | 46 | } // namespace claire 47 | 48 | #endif // _CLAIRE_COMMON_TRACING_TRACECONTEXT_H_ 49 | -------------------------------------------------------------------------------- /common/tracing/TraceRecorder.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace claire { 12 | 13 | // static 14 | TraceRecorder* TraceRecorder::instance() 15 | { 16 | return Singleton::instance(); 17 | } 18 | 19 | Trace* TraceRecorder::RegisterOrDeleteDuplicate(Trace* trace) 20 | { 21 | Trace* trace_to_delete = NULL; 22 | Trace* trace_to_return = NULL; 23 | auto id(std::make_pair(trace->trace_id(), trace->span_id())); 24 | 25 | { 26 | MutexLock lock(mutex_); 27 | auto it = traces_.find(id); 28 | if (traces_.end() == it) 29 | { 30 | traces_[id] = trace; 31 | trace_to_return = trace; 32 | } 33 | else if (trace == it->second) 34 | { 35 | // The trace was registered before. 36 | trace_to_return = trace; 37 | } 38 | else 39 | { 40 | // We already have one trace with this ids 41 | trace_to_return = it->second; 42 | trace_to_delete = trace; 43 | } 44 | } 45 | delete trace_to_delete; 46 | return trace_to_return; 47 | } 48 | 49 | Trace* TraceRecorder::Find(int64_t trace_id, int64_t span_id) 50 | { 51 | MutexLock lock(mutex_); 52 | auto it = traces_.find(std::make_pair(trace_id, span_id)); 53 | if (traces_.end() == it) 54 | return NULL; 55 | return it->second; 56 | } 57 | 58 | void TraceRecorder::Erase(int64_t trace_id, int64_t span_id) 59 | { 60 | MutexLock lock(mutex_); 61 | auto it = traces_.find(std::make_pair(trace_id, span_id)); 62 | if (it == traces_.end()) 63 | { 64 | return ; 65 | } 66 | delete it->second; 67 | traces_.erase(it); 68 | } 69 | 70 | } // namespace claire 71 | -------------------------------------------------------------------------------- /common/tracing/TraceRecorder.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _CLAIRE_COMMON_TRACING_TRACERECORDER_H_ 6 | #define _CLAIRE_COMMON_TRACING_TRACERECORDER_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace claire { 18 | 19 | class Trace; 20 | 21 | class TraceRecorder : boost::noncopyable 22 | { 23 | public: 24 | static TraceRecorder* instance(); 25 | 26 | // Register, or add a new trace to the collection of traces. If an 27 | // identically named traces is already registered, then the argument 28 | // |trace| will deleted. The returned value is always the registered 29 | // trace (either the argument, or the pre-existing registered trace). 30 | Trace* RegisterOrDeleteDuplicate(Trace* trace); 31 | 32 | // Find a trace by trace id and span id. This method is thread 33 | // safe. It returns NULL if a matching histogram is not found. 34 | Trace* Find(int64_t trace_id, int64_t span_id); 35 | Trace* Find(const std::pair& context) 36 | { 37 | return Find(context.first, context.second); 38 | } 39 | 40 | // Erase trace from registered collections and release memory 41 | void Erase(int64_t trace_id, int64_t span_id); 42 | void Erase(const std::pair& context) 43 | { 44 | return Erase(context.first, context.second); 45 | } 46 | 47 | private: 48 | // We keep all registered traces in a map, from id to trace 49 | typedef std::pair TraceId; 50 | typedef std::map TraceMap; 51 | 52 | TraceRecorder() {} 53 | ~TraceRecorder() {} 54 | friend class Singleton; 55 | 56 | Mutex mutex_; 57 | TraceMap traces_; 58 | }; 59 | 60 | } // namespace claire 61 | 62 | #endif // _CLAIRE_COMMON_TRACING_TRACERECORDER_H_ 63 | -------------------------------------------------------------------------------- /common/tracing/Tracer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_TRACING_TRACER_H_ 6 | #define _CLAIRE_COMMON_TRACING_TRACER_H_ 7 | 8 | #include 9 | 10 | namespace claire { 11 | 12 | class Tracer 13 | { 14 | public: 15 | virtual ~Tracer() {} 16 | 17 | /// Record one or more annotations. 18 | virtual void Record(const Trace&, const Annotation&) {} 19 | virtual void Record(const Trace&, const BinaryAnnotation&) {} 20 | }; 21 | 22 | } // namespace claire 23 | 24 | #endif // _CLAIRE_COMMON_TRACING_TRACER_H_ 25 | -------------------------------------------------------------------------------- /common/tracing/Tracing.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | #include 7 | 8 | namespace claire { 9 | 10 | static Tracer g_null_tracer; 11 | static Tracer* g_tracer = &g_null_tracer; 12 | 13 | void InstallClaireTracer(Tracer* tracer) 14 | { 15 | g_tracer = tracer; 16 | } 17 | 18 | void OutputTrace(const Trace& trace, const Annotation& annotation) 19 | { 20 | g_tracer->Record(trace, annotation); 21 | } 22 | 23 | void OutputTrace(const Trace& trace, const BinaryAnnotation& annotation) 24 | { 25 | g_tracer->Record(trace, annotation); 26 | } 27 | 28 | } // namespace claire 29 | -------------------------------------------------------------------------------- /common/tracing/Tracing.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_COMMON_TRACING_TRACING_H_ 6 | #define _CLAIRE_COMMON_TRACING_TRACING_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define TRACE_PRINTF(fmt, args...) \ 14 | do { \ 15 | auto trace = claire::TraceRecorder::instance()->Find(claire::ThisThread::GetTraceContext()); \ 16 | if (trace) trace->Record(Annotation(claire::StringPrintf(fmt, ## args))); \ 17 | } while (0) 18 | 19 | #define GET_TRACE_BY_TRACEID(trace_id, span_id) \ 20 | (claire::TraceRecorder::instance()->Find(trace_id, span_id)) 21 | 22 | #define THISTHREAD_TRACE() \ 23 | (claire::TraceRecorder::instance()->Find(claire::ThisThread::GetTraceContext())) 24 | 25 | #define TRACE_ANNOTATION(annotation) \ 26 | do { \ 27 | auto trace = claire::TraceRecorder::instance()->Find(claire::ThisThread::GetTraceContext()); \ 28 | if (trace) trace->Record(annotation); \ 29 | } while (0) 30 | 31 | #define TRACE_SET_HOST(ip, port, service_name) \ 32 | do { \ 33 | auto trace = claire::TraceRecorder::instance()->Find(claire::ThisThread::GetTraceContext()); \ 34 | if (trace) trace->set_host(claire::Endpoint(ip, port, service_name)); \ 35 | } while (0) 36 | 37 | #define ERASE_TRACE() \ 38 | claire::TraceRecorder::instance()->Erase(claire::ThisThread::GetTraceContext()) \ 39 | 40 | namespace claire { 41 | 42 | class Tracer; 43 | void InstallClaireTracer(Tracer* tracer); 44 | void OutputTrace(const Trace&, const Annotation&); 45 | void OutputTrace(const Trace&, const BinaryAnnotation&); 46 | 47 | } // namespace claire 48 | 49 | #endif // _CLAIRE_COMMON_TRACING_TRACING_H_ 50 | -------------------------------------------------------------------------------- /examples/rpcbench/BUILD: -------------------------------------------------------------------------------- 1 | protorpc_library( 2 | name = 'echo', 3 | srcs = 'echo.proto', 4 | ) 5 | 6 | cc_binary( 7 | name = 'echo_client', 8 | srcs = 'client.cc', 9 | deps = ':echo' 10 | ) 11 | 12 | cc_binary( 13 | name = 'echo_server', 14 | srcs = 'server.cc', 15 | deps = ':echo' 16 | ) 17 | -------------------------------------------------------------------------------- /examples/rpcbench/echo.proto: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | option cc_generic_services = true; 4 | 5 | message EchoRequest { 6 | required string str = 1; 7 | } 8 | 9 | message EchoResponse { 10 | required string str = 1; 11 | } 12 | 13 | service EchoService { 14 | rpc Echo (EchoRequest) returns (EchoResponse); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /examples/rpcbench/server.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace claire; 11 | using namespace claire::protorpc; 12 | 13 | DEFINE_int32(num_threads, 4, "num of RpcServer threads"); 14 | 15 | namespace echo 16 | { 17 | 18 | class EchoServiceImpl : public EchoService 19 | { 20 | public: 21 | virtual void Echo(RpcControllerPtr& controller, 22 | const ::echo::EchoRequestPtr& request, 23 | const ::echo::EchoResponse* response_prototype, 24 | const RpcDoneCallback& done) 25 | { 26 | EchoResponse response; 27 | response.set_str(request->str()); 28 | done(controller, &response); 29 | } 30 | }; 31 | 32 | } 33 | 34 | int main(int argc, char* argv[]) 35 | { 36 | ::gflags::ParseCommandLineFlags(&argc, &argv, true); 37 | InitClaireLogging(argv[0]); 38 | 39 | EventLoop loop; 40 | InetAddress listen_address(8080); 41 | echo::EchoServiceImpl impl; 42 | RpcServer server(&loop, listen_address); 43 | server.set_num_threads(FLAGS_num_threads); 44 | server.RegisterService(&impl); 45 | server.Start(); 46 | loop.loop(); 47 | } 48 | 49 | -------------------------------------------------------------------------------- /examples/zipkin/BUILD: -------------------------------------------------------------------------------- 1 | protorpc_library( 2 | name = 'sort', 3 | srcs = 'sort.proto', 4 | ) 5 | 6 | cc_binary( 7 | name = 'sort_client', 8 | srcs = 'client.cc', 9 | deps = [':sort', '//claire/zipkin:claire_zipkin', '#thrift'] 10 | ) 11 | 12 | cc_binary( 13 | name = 'sort_server', 14 | srcs = 'server.cc', 15 | deps = [':sort', '//claire/zipkin:claire_zipkin', '#thrift'] 16 | ) 17 | 18 | cc_binary( 19 | name = 'sort_transfer', 20 | srcs = 'transfer.cc', 21 | deps = [':sort', '//claire/zipkin:claire_zipkin', '#thrift'] 22 | ) 23 | -------------------------------------------------------------------------------- /examples/zipkin/client.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace claire; 9 | using namespace claire::protorpc; 10 | 11 | void OnResult(const std::vector& v) 12 | { 13 | for (size_t i = 0; i < v.size(); i++) 14 | { 15 | LOG(DEBUG) << "v[" << i << "] " << v[i]; 16 | } 17 | } 18 | 19 | int main(int argc, char* argv[]) 20 | { 21 | ::gflags::ParseCommandLineFlags(&argc, &argv, true); 22 | InitClaireLogging(argv[0]); 23 | 24 | ZipkinTracer tracer(InetAddress(9410)); 25 | InstallClaireTracer(&tracer); 26 | 27 | EventLoop loop; 28 | InetAddress server_address(argv[1], 8081); 29 | 30 | SortClient client(&loop, server_address); 31 | std::vector v; 32 | v.push_back(10); 33 | v.push_back(1); 34 | v.push_back(11); 35 | v.push_back(2); 36 | v.push_back(100); 37 | v.push_back(8); 38 | v.push_back(12); 39 | v.push_back(9); 40 | client.SendRequest(v, boost::bind(&OnResult, _1)); 41 | loop.loop(); 42 | return 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /examples/zipkin/server.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | using namespace claire; 14 | using namespace claire::protorpc; 15 | 16 | namespace sort { 17 | 18 | class StdSortServiceImpl : public StdSortService 19 | { 20 | public: 21 | virtual void StdSort(RpcControllerPtr& controller, 22 | const ::sort::SortRequestPtr& request, 23 | const ::sort::SortResponse* response_protoType, 24 | const RpcDoneCallback& done) 25 | { 26 | SortResponse response; 27 | std::vector v; 28 | for (int i = 0;i < request->nums_size(); i++) 29 | { 30 | v.push_back(request->nums(i)); 31 | } 32 | std::sort(v.begin(), v.end()); 33 | 34 | for (auto it = v.cbegin(); it != v.cend(); ++it) 35 | { 36 | response.add_nums(*it); 37 | } 38 | done(controller, &response); 39 | } 40 | }; 41 | 42 | } // namespace sort 43 | 44 | int main(int argc, char* argv[]) 45 | { 46 | ::gflags::ParseCommandLineFlags(&argc, &argv, true); 47 | InitClaireLogging(argv[0]); 48 | 49 | ZipkinTracer tracer(InetAddress(9410)); 50 | InstallClaireTracer(&tracer); 51 | 52 | EventLoop loop; 53 | InetAddress listen_address(8082); 54 | sort::StdSortServiceImpl impl; 55 | RpcServer server(&loop, listen_address); 56 | server.RegisterService(&impl); 57 | server.Start(); 58 | loop.loop(); 59 | } 60 | 61 | -------------------------------------------------------------------------------- /examples/zipkin/sort.proto: -------------------------------------------------------------------------------- 1 | package sort; 2 | 3 | option cc_generic_services = true; 4 | 5 | message SortRequest { 6 | repeated int32 nums = 1; 7 | } 8 | 9 | message SortResponse { 10 | repeated int32 nums = 1; 11 | } 12 | 13 | service SortService { 14 | rpc Sort (SortRequest) returns (SortResponse); 15 | } 16 | 17 | service StdSortService { 18 | rpc StdSort (SortRequest) returns (SortResponse); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /examples/zipkin/sort_client.h: -------------------------------------------------------------------------------- 1 | #ifndef _EXAMPLES_SORT_CLIENT_H_ 2 | #define _EXAMPLES_SORT_CLIENT_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | namespace claire { 20 | 21 | class SortClient : boost::noncopyable 22 | { 23 | public: 24 | typedef boost::function&)> ResultCallback; 25 | SortClient(EventLoop* loop, 26 | const InetAddress& server_address) 27 | : channel_(loop), 28 | stub_(&channel_) 29 | { 30 | channel_.Connect(server_address); 31 | } 32 | 33 | void SendRequest(const std::vector& v, const ResultCallback& done) 34 | { 35 | protorpc::RpcControllerPtr controller(new protorpc::RpcController()); 36 | SendRequest(controller, v, done); 37 | } 38 | 39 | void SendRequest(protorpc::RpcControllerPtr& controller, const std::vector& v, const ResultCallback& done) 40 | { 41 | sort::SortRequest request; 42 | for (auto it = v.cbegin(); it != v.cend(); ++it) 43 | { 44 | request.add_nums(*it); 45 | } 46 | stub_.Sort(controller, request, boost::bind(&SortClient::replied, this, _1, _2, done)); 47 | } 48 | 49 | private: 50 | void replied(protorpc::RpcControllerPtr& controller, const boost::shared_ptr& response, const ResultCallback& done) 51 | { 52 | std::vector v; 53 | if (controller->Failed()) 54 | { 55 | LOG(ERROR) << controller->ErrorText(); 56 | } 57 | else 58 | { 59 | for (int i = 0;i < response->nums_size(); i++) 60 | { 61 | v.push_back(response->nums(i)); 62 | } 63 | } 64 | done(v); 65 | } 66 | 67 | protorpc::RpcChannel channel_; 68 | sort::SortService::Stub stub_; 69 | }; 70 | 71 | } // namespace claire 72 | 73 | #endif // _EXAMPLES_SORT_CLIENT_H_ 74 | -------------------------------------------------------------------------------- /examples/zipkin/stdsort_client.h: -------------------------------------------------------------------------------- 1 | #ifndef _EXAMPLES_STDSORT_CLIENT_H_ 2 | #define _EXAMPLES_STDSORT_CLIENT_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | namespace claire { 20 | 21 | class StdSortClient : boost::noncopyable 22 | { 23 | public: 24 | typedef boost::function&)> ResultCallback; 25 | StdSortClient(EventLoop* loop, const InetAddress& server_address) 26 | : channel_(loop), 27 | stub_(&channel_) 28 | { 29 | channel_.Connect(server_address); 30 | } 31 | 32 | void SendRequest(const std::vector& v, const ResultCallback& done) 33 | { 34 | protorpc::RpcControllerPtr controller(new protorpc::RpcController()); 35 | SendRequest(controller, v, done); 36 | } 37 | 38 | void SendRequest(protorpc::RpcControllerPtr& controller, const std::vector& v, const ResultCallback& done) 39 | { 40 | sort::SortRequest request; 41 | for (auto it = v.cbegin(); it != v.cend(); ++it) 42 | { 43 | request.add_nums(*it); 44 | } 45 | stub_.StdSort(controller, request, boost::bind(&StdSortClient::replied, this, _1, _2, done)); 46 | } 47 | 48 | private: 49 | void replied(protorpc::RpcControllerPtr& controller, const boost::shared_ptr& response, const ResultCallback& done) 50 | { 51 | std::vector v; 52 | if (controller->Failed()) 53 | { 54 | LOG(ERROR) << controller->ErrorText(); 55 | } 56 | else 57 | { 58 | for (int i = 0;i < response->nums_size(); i++) 59 | { 60 | v.push_back(response->nums(i)); 61 | } 62 | } 63 | done(v); 64 | } 65 | 66 | protorpc::RpcChannel channel_; 67 | sort::StdSortService::Stub stub_; 68 | }; 69 | 70 | } // namespace claire 71 | 72 | #endif // _EXAMPLES_STDSORT_CLIENT_H_ 73 | -------------------------------------------------------------------------------- /examples/zipkin/transfer.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | using namespace claire; 15 | using namespace claire::protorpc; 16 | 17 | namespace sort { 18 | 19 | class SortTransferServiceImpl : public SortService 20 | { 21 | public: 22 | SortTransferServiceImpl(EventLoop* loop, const InetAddress& server_address) 23 | : client_(loop, server_address) {} 24 | 25 | virtual void Sort(RpcControllerPtr& controller, 26 | const ::sort::SortRequestPtr& request, 27 | const ::sort::SortResponse* response_prototype, 28 | const RpcDoneCallback& done) 29 | { 30 | if (request->nums_size() == 0) 31 | { 32 | controller->SetFailed("Empty Request"); 33 | done(controller, NULL); 34 | return ; 35 | } 36 | 37 | std::vector v; 38 | for (int i = 0;i < request->nums_size(); i++) 39 | { 40 | v.push_back(request->nums(i)); 41 | } 42 | 43 | RpcControllerPtr sub_controller(new RpcController()); 44 | sub_controller->set_parent(controller); 45 | client_.SendRequest(sub_controller, v, boost::bind(&SortTransferServiceImpl::OnResponse, this, _1, controller, done)); 46 | } 47 | 48 | private: 49 | void OnResponse(const std::vector& v, RpcControllerPtr& controller, const RpcDoneCallback& done) 50 | { 51 | if (v.empty()) 52 | { 53 | controller->SetFailed("Empty Response"); 54 | done(controller, NULL); 55 | return ; 56 | } 57 | 58 | SortResponse response; 59 | for (auto it = v.cbegin(); it != v.cend(); ++it) 60 | { 61 | response.add_nums(*it); 62 | } 63 | done(controller, &response); 64 | } 65 | 66 | StdSortClient client_; 67 | }; 68 | 69 | } // namespace sort 70 | 71 | int main(int argc, char* argv[]) 72 | { 73 | ::gflags::ParseCommandLineFlags(&argc, &argv, true); 74 | InitClaireLogging(argv[0]); 75 | 76 | ZipkinTracer tracer(InetAddress(9410)); 77 | InstallClaireTracer(&tracer); 78 | 79 | EventLoop loop; 80 | InetAddress listen_address(8081); 81 | InetAddress server_address(8082); 82 | 83 | sort::SortTransferServiceImpl impl(&loop, server_address); 84 | RpcServer server(&loop, listen_address); 85 | server.RegisterService(&impl); 86 | server.Start(); 87 | loop.loop(); 88 | } 89 | 90 | -------------------------------------------------------------------------------- /netty/Acceptor.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace claire { 16 | 17 | Acceptor::Acceptor(EventLoop* loop, 18 | const InetAddress& listen_address, 19 | bool reuse_port) 20 | : loop_(loop), 21 | accept_socket_(Socket::NewNonBlockingSocket(true)), 22 | accept_channel_(new Channel(loop, accept_socket_->fd())), 23 | listenning_(false) 24 | { 25 | accept_socket_->SetReuseAddr(true); 26 | accept_socket_->SetReusePort(reuse_port); 27 | accept_socket_->BindOrDie(listen_address); 28 | 29 | accept_channel_->set_read_callback( 30 | boost::bind(&Acceptor::OnRead, this)); 31 | } 32 | 33 | Acceptor::~Acceptor() 34 | { 35 | accept_channel_->DisableAll(); 36 | accept_channel_->Remove(); 37 | } 38 | 39 | void Acceptor::Listen() 40 | { 41 | loop_->AssertInLoopThread(); 42 | 43 | if (!listenning_) 44 | { 45 | listenning_ = true; 46 | accept_socket_->ListenOrDie(); 47 | accept_channel_->EnableReading(); 48 | } 49 | } 50 | 51 | void Acceptor::OnRead() 52 | { 53 | loop_->AssertInLoopThread(); 54 | 55 | InetAddress from; 56 | Socket socket(accept_socket_->AcceptOrDie(&from)); 57 | if (socket.fd() >= 0) 58 | { 59 | if (new_connection_callback_) 60 | { 61 | new_connection_callback_(socket); 62 | } 63 | } 64 | else 65 | { 66 | if (errno == EMFILE) 67 | { 68 | // In multi-thread env, no good solution 69 | PLOG(ERROR) << "accept overload"; 70 | } 71 | } 72 | } 73 | 74 | } // namespace claire 75 | -------------------------------------------------------------------------------- /netty/Acceptor.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace claire { 12 | 13 | class Channel; 14 | class EventLoop; 15 | class InetAddress; 16 | 17 | /// 18 | /// Acceptor of incoming TCP connections. 19 | /// 20 | class Acceptor : boost::noncopyable 21 | { 22 | public: 23 | /// 24 | /// Default ctor, do not use reuse port 25 | /// 26 | Acceptor(EventLoop* loop, const InetAddress& listen_address) 27 | : Acceptor(loop, listen_address, false) {} 28 | 29 | /// 30 | /// User can enable reuse port by 3rd params 31 | /// 32 | Acceptor(EventLoop* loop, 33 | const InetAddress& listen_address, 34 | bool reuse_port); 35 | 36 | ~Acceptor(); 37 | 38 | /// 39 | /// Must call before Listen(), set NewConnectionCallback for notify new connection event 40 | /// 41 | void SetNewConnectionCallback(const NewConnectionCallback& callback) 42 | { 43 | new_connection_callback_ = callback; 44 | } 45 | 46 | /// 47 | /// Is acceptor listening 48 | /// 49 | bool listenning() const { return listenning_; } 50 | 51 | /// 52 | /// Begin Listen 53 | /// 54 | void Listen(); 55 | 56 | private: 57 | /// 58 | /// Process events which channel notified 59 | /// 60 | void OnRead(); 61 | 62 | EventLoop* loop_; 63 | std::unique_ptr accept_socket_; 64 | std::unique_ptr accept_channel_; 65 | NewConnectionCallback new_connection_callback_; 66 | bool listenning_; 67 | }; 68 | 69 | } // namespace claire 70 | -------------------------------------------------------------------------------- /netty/BUILD: -------------------------------------------------------------------------------- 1 | resource_library( 2 | name = 'static_resource', 3 | srcs = [ 4 | './inspect/assets/flags.js', 5 | './inspect/assets/flags.html', 6 | './inspect/assets/graphview.html', 7 | './inspect/assets/grapher.js', 8 | './inspect/assets/parser.js', 9 | './inspect/assets/dygraph-combined.js', 10 | './inspect/assets/dygraph-extra.js', 11 | './http/assets/jquery/js/jquery-1.10.2.min.js', 12 | './http/assets/jquery/js/jquery-1.10.3.ui.min.js', 13 | './http/assets/jquery/js/jquery.json-2.4.min.js', 14 | './http/assets/bootstrap/js/bootstrap-2.2.1.min.js', 15 | './http/assets/bootstrap/css/bootstrap-2.2.1.combined.min.css' 16 | ] 17 | ) 18 | 19 | cc_library( 20 | name = 'claire_netty', 21 | srcs = [ 22 | 'Buffer.cc', 23 | 'IOStream.cc', 24 | 'InetAddress.cc', 25 | 'Socket.cc', 26 | 'Acceptor.cc', 27 | 'Connector.cc', 28 | 'TcpConnection.cc', 29 | 'TcpClient.cc', 30 | 'TcpServer.cc', 31 | 'UdpClient.cc', 32 | 'UdpServer.cc', 33 | './resolver/ResolverFactory.cc', 34 | './resolver/StaticAddressResolver.cc', 35 | './resolver/DnsResolver.cc', 36 | './loadbalancer/LoadBalancerFactory.cc', 37 | './inspect/PProfInspector.cc', 38 | './inspect/FlagsInspector.cc', 39 | './inspect/StatisticsInspector.cc', 40 | './http/Uri.cc', 41 | './http/MimeType.cc', 42 | './http/HttpRequest.cc', 43 | './http/HttpResponse.cc', 44 | './http/HttpConnection.cc', 45 | './http/HttpServer.cc', 46 | './http/HttpClient.cc' 47 | ], 48 | deps = [ 49 | ':static_resource', 50 | '#pthread', 51 | '#rt', 52 | '#boost_regex', 53 | '//thirdparty/ctemplate:ctemplate', 54 | '//thirdparty/gperftools:tcmalloc_and_profiler', 55 | '//thirdparty/c-ares:cares', 56 | '//claire/common:claire_common', 57 | ], 58 | extra_cppflags = '-std=c++0x' 59 | ) 60 | -------------------------------------------------------------------------------- /netty/Buffer.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | namespace claire { 8 | 9 | const char Buffer::kCRLF[] = "\r\n"; 10 | 11 | } // namespace claire 12 | -------------------------------------------------------------------------------- /netty/Callbacks.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_CALLBACKS_H_ 6 | #define _CLAIRE_NETTY_CALLBACKS_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace claire { 12 | 13 | class Buffer; 14 | class Socket; 15 | class EventLoop; 16 | class TcpConnection; 17 | typedef boost::shared_ptr TcpConnectionPtr; 18 | 19 | typedef boost::function CloseCallback; 20 | typedef boost::function MessageCallback; 21 | typedef boost::function ConnectionCallback; 22 | typedef boost::function WriteCompleteCallback; 23 | typedef boost::function HighWaterMarkCallback; 24 | typedef boost::function ThreadInitCallback; 25 | 26 | typedef boost::function NewConnectionCallback; 27 | 28 | } // namespace claire 29 | 30 | #endif // _CLAIRE_NETTY_CALLBACKS_H_ 31 | -------------------------------------------------------------------------------- /netty/Connector.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_CONNECTOR_H_ 6 | #define _CLAIRE_NETTY_CONNECTOR_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | namespace claire { 21 | 22 | class Socket; 23 | class Channel; 24 | class EventLoop; 25 | 26 | class Connector : boost::noncopyable, 27 | public boost::enable_shared_from_this 28 | { 29 | public: 30 | Connector(EventLoop* loop, const InetAddress& server_address); 31 | ~Connector(); 32 | 33 | void set_new_connection_callback(const NewConnectionCallback& callback) 34 | { 35 | new_connection_callback_ = callback; 36 | } 37 | 38 | void Connect(); 39 | void Stop(); 40 | void Restart(); 41 | 42 | private: 43 | enum States 44 | { 45 | kDisconnected, // Init state or connection down 46 | kConnecting, // Before fd writeable 47 | kConnected // After fd writeable 48 | }; 49 | 50 | void set_state(States s) 51 | { 52 | state_ = s; 53 | } 54 | 55 | void ConnectInLoop(); 56 | void StopInLoop(); 57 | 58 | void OnWrite(); 59 | void OnError(); 60 | void OnConnectTimeout(); 61 | 62 | void ResetAndRetry(); 63 | void RemoveAndResetChannel(); 64 | void ResetChannel(); 65 | 66 | EventLoop* loop_; 67 | const InetAddress server_address_; 68 | 69 | std::unique_ptr channel_; 70 | NewConnectionCallback new_connection_callback_; 71 | 72 | boost::atomic connect_; 73 | boost::atomic state_; 74 | 75 | boost::random::mt19937 gen_; 76 | TimerId retry_timer_; 77 | TimerId connect_timer_; 78 | }; 79 | 80 | typedef boost::shared_ptr ConnectorPtr; 81 | 82 | } // namespace claire 83 | 84 | #endif // _CLAIRE_NETTY_CONNECTOR_H_ 85 | -------------------------------------------------------------------------------- /netty/Endian.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_ENDIAN_H_ 6 | #define _CLAIRE_NETTY_ENDIAN_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace claire { 12 | 13 | #if defined(__clang__) || __GNUC_MINOR__ >= 6 14 | #pragma GCC diagnostic push 15 | #endif 16 | #pragma GCC diagnostic ignored "-Wconversion" 17 | #pragma GCC diagnostic ignored "-Wold-style-cast" 18 | inline uint64_t HostToNetwork64(uint64_t host64) 19 | { 20 | return htobe64(host64); 21 | } 22 | 23 | inline uint32_t HostToNetwork32(uint32_t host32) 24 | { 25 | return htobe32(host32); 26 | } 27 | 28 | inline uint16_t HostToNetwork16(uint16_t host16) 29 | { 30 | return htobe16(host16); 31 | } 32 | 33 | inline uint64_t NetworkToHost64(uint64_t net64) 34 | { 35 | return be64toh(net64); 36 | } 37 | 38 | inline uint32_t NetworkToHost32(uint32_t net32) 39 | { 40 | return be32toh(net32); 41 | } 42 | 43 | inline uint16_t NetworkToHost16(uint16_t net16) 44 | { 45 | return be16toh(net16); 46 | } 47 | #if defined(__clang__) || __GNUC_MINOR__ >= 6 48 | #pragma GCC diagnostic pop 49 | #else 50 | #pragma GCC diagnostic error "-Wconversion" 51 | #pragma GCC diagnostic error "-Wold-style-cast" 52 | #endif 53 | 54 | } // namespace claire 55 | 56 | #endif // _CLAIRE_NETTY_ENDIAN_H_ 57 | -------------------------------------------------------------------------------- /netty/IOStream.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | 9 | namespace claire { 10 | 11 | namespace { 12 | 13 | template 14 | T Swap(T v) 15 | { 16 | T ret = v; 17 | std::reverse(reinterpret_cast(&ret), 18 | reinterpret_cast(&ret)+sizeof(v)); 19 | return ret; 20 | } 21 | 22 | } // namespace 23 | 24 | template 25 | IOStream& IOStream::operator<<(T i) 26 | { 27 | T v = Swap(i); 28 | buffer_->Append(&v, sizeof v); 29 | return *this; 30 | } 31 | 32 | template IOStream& IOStream::operator<<(uint8_t); 33 | template IOStream& IOStream::operator<<(int8_t); 34 | template IOStream& IOStream::operator<<(uint16_t); 35 | template IOStream& IOStream::operator<<(int16_t); 36 | template IOStream& IOStream::operator<<(uint32_t); 37 | template IOStream& IOStream::operator<<(int32_t); 38 | template IOStream& IOStream::operator<<(uint64_t); 39 | template IOStream& IOStream::operator<<(int64_t); 40 | template IOStream& IOStream::operator<<(float); 41 | template IOStream& IOStream::operator<<(double); 42 | 43 | template 44 | IOStream& IOStream::operator>>(T& i) 45 | { 46 | if (buffer_->Read(&i, sizeof i) < sizeof i) 47 | { 48 | set_status(kReadPastEnd); 49 | } 50 | i = Swap(i); 51 | return *this; 52 | } 53 | 54 | template IOStream& IOStream::operator>>(uint8_t&); 55 | template IOStream& IOStream::operator>>(int8_t&); 56 | template IOStream& IOStream::operator>>(uint16_t&); 57 | template IOStream& IOStream::operator>>(int16_t&); 58 | template IOStream& IOStream::operator>>(uint32_t&); 59 | template IOStream& IOStream::operator>>(int32_t&); 60 | template IOStream& IOStream::operator>>(uint64_t&); 61 | template IOStream& IOStream::operator>>(int64_t&); 62 | template IOStream& IOStream::operator>>(float&); 63 | template IOStream& IOStream::operator>>(double&); 64 | 65 | } // namespace claire 66 | -------------------------------------------------------------------------------- /netty/IOStream.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_IOSTREAM_H_ 6 | #define _CLAIRE_NETTY_IOSTREAM_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace claire { 15 | 16 | class IOStream : boost::noncopyable 17 | { 18 | public: 19 | enum Status 20 | { 21 | kOk, 22 | kReadPastEnd, 23 | kNoEnoughSpace, 24 | kInvalidData 25 | }; 26 | 27 | IOStream(Buffer* buffer) 28 | : buffer_(buffer), 29 | status_(kOk) 30 | {} 31 | 32 | Status status() const { return status_; } 33 | 34 | void set_status(Status s) 35 | { 36 | if (status_ == kOk) 37 | status_ = s; 38 | } 39 | 40 | template 41 | inline size_t Read(T (&s)[N], size_t length) 42 | { 43 | static_assert(sizeof(T) == 1, "T must be char like size"); 44 | if (N < length) 45 | { 46 | set_status(kReadPastEnd); 47 | return 0; 48 | } 49 | return buffer_->Read(&s[0], length); 50 | } 51 | 52 | template 53 | inline void Append(const T (&s)[N], size_t length) 54 | { 55 | static_assert(sizeof(T) == 1, "T must be char like size"); 56 | if (N < length) 57 | { 58 | set_status(kNoEnoughSpace); 59 | return ; 60 | } 61 | buffer_->Append(&s[0], length); 62 | } 63 | 64 | void Skip(size_t length) 65 | { 66 | buffer_->Consume(length); 67 | } 68 | 69 | template 70 | IOStream& operator<<(T i); 71 | 72 | template 73 | IOStream& operator>>(T& i); 74 | 75 | operator bool() const { return status() == kOk; } 76 | 77 | private: 78 | Buffer* buffer_; 79 | Status status_; 80 | }; 81 | 82 | } // namespace claire 83 | 84 | #endif // _CLAIRE_NETTY_IOSTREAM_H_ 85 | -------------------------------------------------------------------------------- /netty/InetAddress.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_INETADDRESS_H_ 6 | #define _CLAIRE_NETTY_INETADDRESS_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace claire { 16 | 17 | /// Wrapper of sockaddr_in 18 | class InetAddress 19 | { 20 | public: 21 | InetAddress(); 22 | 23 | /// Constructs an endpoint with given port number. 24 | /// Mostly used in TcpServer listening. 25 | explicit InetAddress(uint16_t port); 26 | 27 | /// Constructs an endpoint with given ip and port. 28 | /// @c ip should be "1.2.3.4" 29 | InetAddress(const StringPiece& ip, uint16_t port); 30 | 31 | /// Constructs an endpoint with given struct @c sockaddr_in 32 | /// Mostly used when accepting new connections 33 | InetAddress(const struct sockaddr_in& address) 34 | : address_(address) 35 | {} 36 | 37 | /// @c address should be "1.2.3.4:56" 38 | InetAddress(const StringPiece& address); 39 | 40 | std::string ip() const; 41 | int IpAsInt() const; 42 | uint16_t port() const; 43 | 44 | std::string ToString() const; 45 | 46 | const struct sockaddr_in& sockaddr() const 47 | { 48 | return address_; 49 | } 50 | 51 | struct sockaddr_in* mutable_sockaddr() 52 | { 53 | return &address_; 54 | } 55 | 56 | void swap(InetAddress& other) 57 | { 58 | std::swap(address_, other.address_); 59 | } 60 | 61 | private: 62 | struct sockaddr_in address_; 63 | }; 64 | 65 | inline bool operator==(const InetAddress& lhs, const InetAddress& rhs) 66 | { 67 | return memcmp(&lhs, &rhs, sizeof lhs) == 0; 68 | } 69 | 70 | inline bool operator<(const InetAddress& lhs, const InetAddress& rhs) 71 | { 72 | return memcmp(&lhs, &rhs, sizeof lhs) < 0; 73 | } 74 | 75 | } // namespace claire 76 | 77 | #endif // _CLAIRE_NETTY_INETADDRESS_H_ 78 | -------------------------------------------------------------------------------- /netty/Socket.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_SOCKET_H_ 6 | #define _CLAIRE_NETTY_SOCKET_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | 15 | struct tcp_info; 16 | 17 | namespace claire { 18 | 19 | class Buffer; 20 | 21 | /// Wrapper of socket file descriptor. 22 | /// It closes the sockfd when desctructs. 23 | /// It's thread safe, all operations are delagated to OS. 24 | class Socket : boost::noncopyable 25 | { 26 | public: 27 | static std::unique_ptr NewNonBlockingSocket(bool is_tcp); 28 | 29 | Socket() 30 | : fd_(-1) 31 | {} 32 | 33 | explicit Socket(int fd__) 34 | : fd_(fd__) 35 | {} 36 | 37 | Socket(Socket&& other) 38 | : fd_(-1) 39 | { 40 | std::swap(fd_, other.fd_); 41 | } 42 | 43 | ~Socket(); 44 | 45 | int fd() const { return fd_; } 46 | void Reset() { fd_ = -1; } 47 | 48 | /// abort if address in use 49 | void BindOrDie(const InetAddress& local_address); 50 | 51 | /// abort if address in use 52 | void ListenOrDie(); 53 | 54 | /// On success, returns a non-negative integer that is 55 | /// a descriptor for the accepted socket, which has been 56 | /// set to non-blocking and close-on-exec. *from is assigned. 57 | /// On error, -1 is returned, and *from is untouched. 58 | int AcceptOrDie(InetAddress* peer_address); 59 | 60 | int Connect(const InetAddress& server_address); 61 | 62 | /// half close the socket 63 | void ShutdownWrite(); 64 | 65 | ssize_t Read(void* buffer, size_t length); 66 | ssize_t Read(Buffer* buffer, InetAddress* peer_address); 67 | ssize_t Write(const void* buffer, size_t length); 68 | ssize_t Write(Buffer* buffer); 69 | ssize_t sendto(const void* buffer, size_t length, const InetAddress& server_address); 70 | 71 | /// Get local InetAddress 72 | const InetAddress local_address() const; 73 | 74 | /// Get peer InetAddress 75 | const InetAddress peer_address() const; 76 | 77 | bool IsSelfConnect() const { return local_address() == peer_address(); } 78 | 79 | /// Get the errno of socket fd_ 80 | int ErrorCode() const; 81 | 82 | void SetTcpNoDelay(bool on); 83 | void SetReuseAddr(bool on); 84 | void SetKeepAlive(bool on); 85 | 86 | void SetReusePort(bool on); 87 | 88 | bool GetTcpInfo(struct tcp_info*) const; 89 | bool GetTcpInfoString(char* buffer, int length) const; 90 | private: 91 | int fd_; 92 | }; 93 | 94 | } // namespace claire 95 | 96 | #endif // _CLAIRE_NETTY_SOCKET_H_ 97 | -------------------------------------------------------------------------------- /netty/TcpClient.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_TCPCLIENT_H_ 6 | #define _CLAIRE_NETTY_TCPCLIENT_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace claire { 16 | 17 | class EventLoop; 18 | class InetAddress; 19 | class TcpConnection; 20 | typedef boost::shared_ptr TcpConnectionPtr; 21 | 22 | class TcpClient : boost::noncopyable 23 | { 24 | public: 25 | TcpClient(EventLoop* loop, const std::string& name); 26 | ~TcpClient(); 27 | 28 | /// Start client to connect server_address 29 | /// It's harmless to call it multiple times. 30 | /// Thread safe 31 | void Connect(const InetAddress& server_address); 32 | 33 | /// Shutdown connection to server_address 34 | /// It's harmless to call it multiple times. 35 | /// Thread safe 36 | void Shutdown(); 37 | 38 | /// Stop client, it will not shutdown the up connection 39 | /// It's harmless to call it multiple times. 40 | /// Thread safe 41 | void Stop(); 42 | 43 | /// Is enable retry 44 | /// Thread safe 45 | bool retry() const; 46 | 47 | /// enable/disable retry 48 | /// Thread safe 49 | void set_retry(bool on); 50 | 51 | /// ConnectionCallback to TcpConnection, called when connection up/down 52 | /// Not thread safe 53 | void set_connection_callback(const ConnectionCallback& callback); 54 | 55 | /// MessageCallback to TcpConnection, called when message received 56 | /// Not thread safe 57 | void set_message_callback(const MessageCallback& callback); 58 | 59 | /// WriteCompleteCallback to TcpConnection, called when write success(to OS!) 60 | /// Not thread safe 61 | void set_write_complete_callback(const WriteCompleteCallback& callback); 62 | 63 | TcpConnectionPtr connection() const; 64 | 65 | EventLoop* loop(); 66 | 67 | private: 68 | class Impl; 69 | boost::shared_ptr impl_; 70 | }; 71 | 72 | } // namespace claire 73 | 74 | #endif // _CLAIRE_NETTY_TCPCLIENT_H_ 75 | -------------------------------------------------------------------------------- /netty/TcpServer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_TCPSERVER_H_ 6 | #define _CLAIRE_NETTY_TCPSERVER_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace claire { 16 | 17 | class EventLoop; 18 | class InetAddress; 19 | 20 | class TcpServer : boost::noncopyable 21 | { 22 | public: 23 | enum Option 24 | { 25 | kNoReusePort, 26 | kReusePort 27 | }; 28 | 29 | TcpServer(EventLoop* loop__, 30 | const InetAddress& listen_address, 31 | const std::string& name__) 32 | : TcpServer(loop__, listen_address, name__, kNoReusePort) {} 33 | TcpServer(EventLoop* loop, 34 | const InetAddress& listen_address, 35 | const std::string& name, 36 | const Option& option); 37 | ~TcpServer(); 38 | 39 | const std::string& hostport() const; 40 | const std::string& name() const; 41 | 42 | /// Starts the server if it's not listenning. 43 | /// 44 | /// It's harmless to call it multiple times. 45 | /// Thread safe. 46 | void Start(); 47 | 48 | /// Set the number of threads for handling input. 49 | /// 50 | /// Always accepts new connection in loop's thread. 51 | /// Must be called before @c Start 52 | /// @param num_threads 53 | /// - 0 means all I/O in loop's thread, no thread will created. 54 | /// this is the default value. 55 | /// - 1 means all I/O in another thread. 56 | /// - N means a thread pool with N threads, new connections 57 | /// are assigned on a round-robin basis. 58 | /// Please only set before @c Start! 59 | void set_num_threads(int num_threads); 60 | 61 | /// ThreadInitCallback to threadpool 62 | /// Not thread safe 63 | void set_thread_init_callback(const ThreadInitCallback& callback); 64 | 65 | /// ConnectionCallback to TcpConnection, called when connections up/down 66 | /// Not thread safe 67 | void set_connection_callback(const ConnectionCallback& callback); 68 | 69 | /// MessageCallback to TcpConnection, called when message arriving 70 | /// Not thread safe 71 | void set_message_callback(const MessageCallback& callback); 72 | 73 | /// WriteCompleteCallback to TcpConnection, called when message write success(to OS!) 74 | /// Not thread safe 75 | void set_write_complete_callback(const WriteCompleteCallback& callback); 76 | 77 | EventLoop* loop(); 78 | private: 79 | class Impl; 80 | boost::shared_ptr impl_; 81 | }; 82 | 83 | } // namespace claire 84 | 85 | #endif // _CLAIRE_NET_TCPSERVER_H_ 86 | -------------------------------------------------------------------------------- /netty/UdpClient.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-common Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_UDPCLIENT_H_ 6 | #define _CLAIRE_NETTY_UDPCLIENT_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | namespace claire { 20 | 21 | class Socket; 22 | class Channel; 23 | class EventLoop; 24 | 25 | class UdpClient : boost::noncopyable 26 | { 27 | public: 28 | typedef boost::function MessageCallback; 29 | typedef boost::function TimeoutCallback; 30 | typedef boost::function HashCodeFunction; 31 | 32 | UdpClient(EventLoop* loop, const std::string& name__); 33 | ~UdpClient(); 34 | 35 | const std::string name() const { return name_; } 36 | 37 | void Start(); 38 | void Send(Buffer* buffer, const InetAddress& server_address); 39 | void Send(const void* data, size_t length, const InetAddress& server_address); 40 | 41 | void set_message_callback(const MessageCallback& callback) 42 | { 43 | message_callback_ = callback; 44 | } 45 | 46 | void set_timeout_callback(const TimeoutCallback& callback) 47 | { 48 | timeout_callback_ = callback; 49 | } 50 | 51 | void set_hash_code_function(const HashCodeFunction& function) 52 | { 53 | hash_code_function_ = function; 54 | } 55 | 56 | // timeout in milisecond, default is 0 57 | void set_timeout(int64_t timeout) { timeout_ = timeout; } 58 | 59 | private: 60 | void StartInLoop(); 61 | 62 | void OnRead(); 63 | void OnTimeout(int64_t hash_code); 64 | 65 | struct OutstandingCall; 66 | 67 | EventLoop* loop_; 68 | const std::string name_; 69 | 70 | std::unique_ptr socket_; 71 | std::unique_ptr channel_; 72 | Buffer input_buffer_; 73 | boost::atomic started_; 74 | int64_t timeout_; 75 | 76 | MessageCallback message_callback_; 77 | TimeoutCallback timeout_callback_; 78 | HashCodeFunction hash_code_function_; 79 | 80 | Mutex mutex_; 81 | std::map outstanding_calls_; //@GUARDBY mutex_ 82 | }; 83 | 84 | } // namespace claire 85 | 86 | #endif // _CLAIRE_NETTY_UDPCLIENT_H_ 87 | -------------------------------------------------------------------------------- /netty/UdpServer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_UDPSERVER_H_ 6 | #define _CLAIRE_NETTY_UDPSERVER_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace claire { 18 | 19 | class Socket; 20 | class Channel; 21 | class EventLoop; 22 | class InetAddress; 23 | 24 | class UdpServer : boost::noncopyable 25 | { 26 | public: 27 | typedef boost::function MessageCallback; 28 | 29 | UdpServer(EventLoop* loop, 30 | const InetAddress& listen_address, 31 | const std::string& name); 32 | ~UdpServer(); 33 | 34 | const std::string name() const 35 | { 36 | return name_; 37 | } 38 | 39 | const std::string local_address() const 40 | { 41 | return local_address_; 42 | } 43 | 44 | void Start(); 45 | void Send(Buffer* buffer, const InetAddress& server_address); 46 | void Send(const void* data, size_t length, const InetAddress& server_address); 47 | 48 | void set_message_callback(const MessageCallback& callback) 49 | { 50 | message_callback_ = callback; 51 | } 52 | 53 | private: 54 | void OnRead(); 55 | void StartInLoop(); 56 | 57 | EventLoop* loop_; 58 | std::unique_ptr socket_; 59 | std::unique_ptr channel_; 60 | Buffer input_buffer_; 61 | 62 | const std::string name_; 63 | const std::string local_address_; 64 | MessageCallback message_callback_; 65 | bool started_; 66 | 67 | Counter received_bytes_counter_; 68 | Counter sent_bytes_counter_; 69 | }; 70 | 71 | } // namespace claire 72 | 73 | #endif // _CLAIRE_NETTY_UDPSERVER_H_ 74 | -------------------------------------------------------------------------------- /netty/http/HttpClient.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace claire { 13 | 14 | HttpClient::~HttpClient() {} 15 | 16 | HttpClient::HttpClient(EventLoop* loop, const std::string& name) 17 | : loop_(loop), 18 | client_(loop, name) 19 | { 20 | client_.set_connection_callback( 21 | boost::bind(&HttpClient::OnConnection, this, _1)); 22 | client_.set_message_callback( 23 | boost::bind(&HttpClient::OnMessage, this, _1, _2)); 24 | } 25 | 26 | void HttpClient::Connect(const InetAddress& server_address) 27 | { 28 | client_.Connect(server_address); 29 | } 30 | 31 | void HttpClient::Shutdown() 32 | { 33 | client_.Shutdown(); 34 | } 35 | 36 | void HttpClient::OnConnection(const TcpConnectionPtr& connection) 37 | { 38 | if (connection->connected()) 39 | { 40 | connection_.reset(new HttpConnection(connection)); 41 | if (headers_callback_) 42 | { 43 | connection_->set_headers_callback(headers_callback_); 44 | } 45 | 46 | if (connection_callback_) 47 | { 48 | connection_callback_(connection_); 49 | } 50 | } 51 | else 52 | { 53 | if (connection_callback_) 54 | { 55 | connection_callback_(connection_); 56 | } 57 | connection_.reset(); 58 | } 59 | } 60 | 61 | void HttpClient::OnMessage(const TcpConnectionPtr& connection, Buffer* buffer) 62 | { 63 | DCHECK(connection_->id() == connection->id()); 64 | 65 | if (!connection_->Parse(buffer)) 66 | { 67 | connection_->Shutdown(); 68 | return ; 69 | } 70 | 71 | if (connection_->GotAll()) 72 | { 73 | if (message_callback_) 74 | { 75 | message_callback_(connection_); 76 | } 77 | connection_->Reset(); 78 | } 79 | } 80 | 81 | } // namespace claire 82 | -------------------------------------------------------------------------------- /netty/http/HttpClient.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_HTTP_HTTPCLIENT_H_ 6 | #define _CLAIRE_NETTY_HTTP_HTTPCLIENT_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace claire { 15 | 16 | class HttpClient : boost::noncopyable 17 | { 18 | public: 19 | typedef HttpConnection::HeadersCallback HeadersCallback; 20 | typedef boost::function MessageCallback; 21 | typedef boost::function ConnectionCallback; 22 | 23 | HttpClient(EventLoop* loop, const std::string& name); 24 | ~HttpClient(); 25 | 26 | void set_headers_callback(const HeadersCallback& callback) 27 | { 28 | headers_callback_ = callback; 29 | } 30 | 31 | void set_message_callback(const MessageCallback& callback) 32 | { 33 | message_callback_ = callback; 34 | } 35 | 36 | void set_connection_callback(const ConnectionCallback& callback) 37 | { 38 | connection_callback_ = callback; 39 | } 40 | 41 | void Connect(const InetAddress& server_address); 42 | void Shutdown(); 43 | 44 | void Send(Buffer* buffer) 45 | { 46 | if (connection_) 47 | { 48 | connection_->Send(buffer); 49 | } 50 | } 51 | 52 | bool connected() const 53 | { 54 | if (connection_) 55 | { 56 | return connection_->connected(); 57 | } 58 | return false; 59 | } 60 | 61 | InetAddress peer_address() const 62 | { 63 | if (connection_) 64 | { 65 | return connection_->peer_address(); 66 | } 67 | return InetAddress(); 68 | } 69 | 70 | InetAddress local_address() const 71 | { 72 | if (connection_) 73 | { 74 | return connection_->local_address(); 75 | } 76 | return InetAddress(); 77 | } 78 | 79 | bool retry() const { return client_.retry(); } 80 | void set_retry(bool on) 81 | { 82 | client_.set_retry(on); 83 | } 84 | 85 | private: 86 | void OnConnection(const TcpConnectionPtr& connection); 87 | void OnMessage(const TcpConnectionPtr& connection, Buffer* buffer); 88 | 89 | EventLoop* loop_; 90 | TcpClient client_; 91 | HttpConnectionPtr connection_; 92 | MessageCallback message_callback_; 93 | HeadersCallback headers_callback_; 94 | ConnectionCallback connection_callback_; 95 | }; 96 | 97 | } // namespace claire 98 | 99 | #endif // _CLAIRE_NETTY_HTTP_HTTPCLIENT_H_ 100 | -------------------------------------------------------------------------------- /netty/http/HttpRequest.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | using namespace claire; 16 | 17 | void HttpRequest::Reset() 18 | { 19 | HttpRequest dummy; 20 | swap(dummy); 21 | } 22 | 23 | bool HttpRequest::ParseStartLine(const std::string& line) 24 | { 25 | std::vector result; 26 | boost::algorithm::split(result, line, boost::is_any_of(" ")); 27 | 28 | if (result.size() != 2 && result.size() != 3) 29 | { 30 | return false; 31 | } 32 | 33 | if (!set_method(result[0].data(), result[0].data() + result[0].size())) 34 | { 35 | return false; 36 | } 37 | 38 | if (!set_uri(result[1])) 39 | { 40 | return false; 41 | } 42 | 43 | if (result.size() == 3 && !set_version(result[2])) 44 | { 45 | return false; 46 | } 47 | 48 | return true; 49 | } 50 | 51 | bool HttpRequest::IsComplete(Buffer* buffer) const 52 | { 53 | if (method_ == kGet || method_ == kHead) 54 | { 55 | return true; 56 | } 57 | 58 | return IsBodyComplete(buffer); 59 | } 60 | 61 | -------------------------------------------------------------------------------- /netty/http/MimeType.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace claire { 18 | 19 | namespace { 20 | 21 | void UpdateMimeTypeMap(std::map* m, 22 | const std::string& k, 23 | std::string& v) 24 | { 25 | m->insert(std::make_pair(k, v)); 26 | } 27 | 28 | std::map InitMimeTypeMapping() 29 | { 30 | std::map m; 31 | m.insert(std::make_pair("gif", "image/gif")); 32 | m.insert(std::make_pair("jpg", "image/jpeg")); 33 | m.insert(std::make_pair("png", "image/png")); 34 | m.insert(std::make_pair("ico", "image/x-icon")); 35 | m.insert(std::make_pair("htm", "text/html")); 36 | m.insert(std::make_pair("html", "text/html")); 37 | m.insert(std::make_pair("txt", "text/x")); 38 | m.insert(std::make_pair("xml", "text/xml")); 39 | m.insert(std::make_pair("js", "application/x-javascript")); 40 | 41 | std::string fdata; 42 | if (FileUtil::ReadFileToString("/etc/mime.types", &fdata)) 43 | { 44 | return m; 45 | } 46 | 47 | std::vector lines; 48 | boost::algorithm::split(lines, fdata, boost::is_any_of("\r\n")); 49 | 50 | for (auto& line : lines) 51 | { 52 | if (line.empty() || line[0] == '#') 53 | { 54 | continue; 55 | } 56 | 57 | std::vector result; 58 | boost::algorithm::split(result, line, boost::is_any_of("\t")); 59 | std::for_each(result.begin()+1, 60 | result.end(), 61 | boost::bind(&UpdateMimeTypeMap, &m, result[0], _1)); 62 | } 63 | 64 | return m; 65 | } 66 | 67 | } // namespace 68 | 69 | MimeType::MimeType(const std::string& mime) 70 | { 71 | auto pos = mime.find('/'); 72 | if (pos != std::string::npos) 73 | { 74 | type_ = mime.substr(0, pos); 75 | subtype_ = mime.substr(pos + 1, mime.size() + 1); 76 | } 77 | // throw ? 78 | } 79 | 80 | MimeType MimeType::ExtensionToMimeType(const std::string& extension) 81 | { 82 | const static std::map mapping = InitMimeTypeMapping(); 83 | 84 | auto it = mapping.find(extension); 85 | if (it != mapping.end()) 86 | { 87 | return MimeType(it->second); 88 | } 89 | 90 | LOG(ERROR) << "extension " << extension << " not found match mime"; 91 | return MimeType(); 92 | } 93 | 94 | } // namespace claire 95 | -------------------------------------------------------------------------------- /netty/http/MimeType.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_HTTP_MIMETYPE_H_ 6 | #define _CLAIRE_NETTY_HTTP_MIMETYPE_H_ 7 | 8 | #include 9 | 10 | namespace claire { 11 | 12 | class MimeType 13 | { 14 | public: 15 | MimeType() {} 16 | MimeType(const std::string& mime); 17 | MimeType(const std::string& type, const std::string& subtype) 18 | : type_(type), subtype_(subtype) {} 19 | 20 | void swap(MimeType& other) 21 | { 22 | type_.swap(other.type_); 23 | subtype_.swap(other.subtype_); 24 | } 25 | 26 | static MimeType ExtensionToMimeType(const std::string& extension); 27 | 28 | bool match(const MimeType& mime) const 29 | { 30 | return ((mime.type_ == type_) || (mime.type_ == "*") || (type_ == "*")) 31 | && ((mime.subtype_ == subtype_) || (mime.subtype_ == "*") || (subtype_ == "*")); 32 | } 33 | 34 | bool Match(const std::string& m) const 35 | { 36 | return match(MimeType(m)); 37 | } 38 | 39 | const std::string& get_type() const 40 | { 41 | return type_; 42 | } 43 | 44 | const std::string& get_subtype() const 45 | { 46 | return subtype_; 47 | } 48 | 49 | const std::string ToString() const 50 | { 51 | return type_ + "/" + subtype_; 52 | } 53 | 54 | bool empty() const 55 | { 56 | return type_.empty() && subtype_.empty(); 57 | } 58 | 59 | private: 60 | std::string type_; 61 | std::string subtype_; 62 | }; 63 | 64 | } // namespace claire 65 | 66 | #endif // _CLAIRE_NETTY_HTTP_MIMETYPE_H_ 67 | -------------------------------------------------------------------------------- /netty/http/assets/jquery/js/jquery.json-2.4.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery JSON plugin 2.4.0 | code.google.com/p/jquery-json */(function($){'use strict';var escape=/["\\\x00-\x1f\x7f-\x9f]/g,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},hasOwn=Object.prototype.hasOwnProperty;$.toJSON=typeof JSON==='object'&&JSON.stringify?JSON.stringify:function(o){if(o===null){return'null';}var pairs,k,name,val,type=$.type(o);if(type==='undefined'){return undefined;}if(type==='number'||type==='boolean'){return String(o);}if(type==='string'){return $.quoteString(o);}if(typeof o.toJSON==='function'){return $.toJSON(o.toJSON());}if(type==='date'){var month=o.getUTCMonth()+1,day=o.getUTCDate(),year=o.getUTCFullYear(),hours=o.getUTCHours(),minutes=o.getUTCMinutes(),seconds=o.getUTCSeconds(),milli=o.getUTCMilliseconds();if(month<10){month='0'+month;}if(day<10){day='0'+day;}if(hours<10){hours='0'+hours;}if(minutes<10){minutes='0'+minutes;}if(seconds<10){seconds='0'+seconds;}if(milli<100){milli='0'+milli;}if(milli<10){milli='0'+milli;}return'"'+year+'-'+month+'-'+day+'T'+hours+':'+minutes+':'+seconds+'.'+milli+'Z"';}pairs=[];if($.isArray(o)){for(k=0;k 8 | #include 9 | 10 | namespace claire { 11 | 12 | class HttpServer; 13 | class HttpConnection; 14 | typedef boost::shared_ptr HttpConnectionPtr; 15 | 16 | class FlagsInspector : boost::noncopyable 17 | { 18 | public: 19 | explicit FlagsInspector(HttpServer* server); 20 | 21 | private: 22 | static void OnFlags(const HttpConnectionPtr& connnection); 23 | }; 24 | 25 | } // namespace claire 26 | -------------------------------------------------------------------------------- /netty/inspect/PProfInspector.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace claire { 15 | 16 | class HttpServer; 17 | class PProfInspector : boost::noncopyable 18 | { 19 | public: 20 | explicit PProfInspector(HttpServer* server); 21 | 22 | private: 23 | void OnProfile(const HttpConnectionPtr& connection); 24 | void OnProfileComplete(); 25 | 26 | void OnHeap(const HttpConnectionPtr& connection); 27 | void OnHeapProfileComplete(); 28 | 29 | static void OnGrowth(const HttpConnectionPtr& connection); 30 | static void OnCmdline(const HttpConnectionPtr& connection); 31 | static void OnSymbol(const HttpConnectionPtr& connection); 32 | static void OnHeapStats(const HttpConnectionPtr& connection); 33 | static void OnHeapHistogram(const HttpConnectionPtr& connection); 34 | 35 | HttpServer* server_; 36 | 37 | Mutex mutex_; 38 | std::set connections_; 39 | std::set heap_connections_; 40 | }; 41 | 42 | } // namespace claire 43 | -------------------------------------------------------------------------------- /netty/inspect/StatisticsInspector.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace claire { 12 | 13 | class HttpServer; 14 | class HttpConnection; 15 | typedef boost::shared_ptr HttpConnectionPtr; 16 | class CounterSampler; 17 | 18 | class StatisticsInspector : boost::noncopyable 19 | { 20 | public: 21 | explicit StatisticsInspector(HttpServer* server); 22 | ~StatisticsInspector(); 23 | 24 | private: 25 | void OnCounterData(const HttpConnectionPtr& connection); 26 | static void OnCounters(const HttpConnectionPtr& connection); 27 | static void OnHistograms(const HttpConnectionPtr& connection); 28 | 29 | boost::scoped_ptr sampler_; 30 | }; 31 | 32 | } // namespace claire 33 | -------------------------------------------------------------------------------- /netty/inspect/assets/flags.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Flags for {{HOST_NAME}} 5 | 6 | 7 | 8 | 10 | 15 | 16 | 17 | {{#FLAG_TABLE}} 18 |

{{FILE_NAME}}

19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {{#FLAG_ROW}} 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | {{/FLAG_ROW}} 41 |
ModifyNameTypeDescriptionDefault ValueCurrent ValueNew Value
{{FLAG_NAME}}{{FLAG_TYPE}}{{FLAG_DESCRIPTION}}{{FLAG_DEFAULT_VALUE}}{{FLAG_CURRENT_VALUE}}
42 |
43 | {{/FLAG_TABLE}} 44 | 45 |
46 |
47 | 48 |
49 | 50 |
51 |
52 |
53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /netty/inspect/assets/graphview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Server Graphing 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

Metrics

17 |
18 | 19 |
20 |
21 | 25 | 26 |
27 | 28 |
29 |
30 | 31 | 32 | 36 | 40 | 41 | 42 | 49 | 55 | 56 |
33 | 34 | 35 | 37 | 38 | 39 |
43 | 44 |
45 | 46 | pt 47 |
48 |
50 |
51 | 52 | 53 |
54 |
57 |
58 |
59 | 60 |
61 |
62 |
63 | 64 | 65 | -------------------------------------------------------------------------------- /netty/loadbalancer/LoadBalancer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_LOADBALANCER_LOADBALANCER_H_ 6 | #define _CLAIRE_NETTY_LOADBALANCER_LOADBALANCER_H_ 7 | 8 | namespace claire { 9 | 10 | class InetAddress; 11 | 12 | enum class ConnectResult 13 | { 14 | kSuccess, 15 | kFailed, 16 | kTimeout 17 | }; 18 | 19 | enum class RequestResult 20 | { 21 | kSuccess, 22 | kFailed, 23 | kTimeout 24 | }; 25 | 26 | class LoadBalancer 27 | { 28 | public: 29 | virtual ~LoadBalancer() {} 30 | 31 | virtual void AddBackend(const InetAddress& backend, int weight) = 0; 32 | 33 | virtual void ReleaseBackend(const InetAddress& backend) 34 | { 35 | // No-op 36 | } 37 | 38 | virtual InetAddress NextBackend() = 0; 39 | 40 | virtual void AddConnectResult(const InetAddress& key, ConnectResult result, int64_t connect_time) 41 | { 42 | // No-op 43 | } 44 | 45 | virtual void AddRequestResult(const InetAddress& key, RequestResult result, int64_t request_time) 46 | { 47 | // No-op 48 | } 49 | }; 50 | 51 | } // namespace claire 52 | 53 | #endif // _CLAIRE_NETTY_LOADBALANCER_LOADBALANCER_H_ 54 | -------------------------------------------------------------------------------- /netty/loadbalancer/LoadBalancerFactory.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace claire { 12 | 13 | LoadBalancerFactory::LoadBalancerFactory() 14 | { 15 | creators_.insert(std::make_pair("random", &LoadBalancerCreator)); 16 | creators_.insert(std::make_pair("roundrobin", &LoadBalancerCreator)); 17 | } 18 | 19 | LoadBalancerFactory::~LoadBalancerFactory() {} 20 | 21 | LoadBalancerFactory* LoadBalancerFactory::instance() 22 | { 23 | return Singleton::instance(); 24 | } 25 | 26 | LoadBalancer* LoadBalancerFactory::Create(const std::string& name) const 27 | { 28 | MutexLock lock(mutex_); 29 | auto it = creators_.find(name); 30 | if (it == creators_.end()) 31 | { 32 | return NULL; 33 | } 34 | return (*(it->second))(); 35 | } 36 | 37 | void LoadBalancerFactory::Register(const std::string& name, Creator creator) 38 | { 39 | MutexLock lock(mutex_); 40 | auto it = creators_.find(name); 41 | if (it != creators_.end()) 42 | { 43 | LOG(FATAL) << "LoadBalancerFactory: " << name << " already registered."; 44 | } 45 | else 46 | { 47 | creators_.insert(std::make_pair(name, creator)); 48 | } 49 | } 50 | 51 | } // namespace claire 52 | -------------------------------------------------------------------------------- /netty/loadbalancer/LoadBalancerFactory.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_LOADBALANCER_LOADBALANCERFACTORY_H_ 6 | #define _CLAIRE_NETTY_LOADBALANCER_LOADBALANCERFACTORY_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace claire { 18 | 19 | template 20 | LoadBalancer* LoadBalancerCreator() 21 | { 22 | return new NewLoadBalancer(); 23 | } 24 | 25 | class LoadBalancerFactory : boost::noncopyable 26 | { 27 | public: 28 | typedef LoadBalancer* (*Creator)(); 29 | 30 | static LoadBalancerFactory* instance(); 31 | 32 | LoadBalancer* Create(const std::string& name) const; 33 | void Register(const std::string& name, Creator creator); 34 | 35 | private: 36 | LoadBalancerFactory(); 37 | ~LoadBalancerFactory(); 38 | 39 | friend class Singleton; 40 | 41 | mutable Mutex mutex_; 42 | std::map creators_; 43 | }; 44 | 45 | } // namespace claire 46 | 47 | #endif // _CLAIRE_NETTY_LOADBALANCER_LOADBALANCERFACTORY_H_ 48 | -------------------------------------------------------------------------------- /netty/loadbalancer/RandomLoadBalancer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_LOADBALANCER_RANDOMLOADBALANCER_H_ 6 | #define _CLAIRE_NETTY_LOADBALANCER_RANDOMLOADBALANCER_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace claire { 19 | 20 | class RandomLoadBalancer : public LoadBalancer, 21 | boost::noncopyable 22 | { 23 | public: 24 | virtual ~RandomLoadBalancer() {} 25 | 26 | virtual void AddBackend(const InetAddress& backend, int weight) 27 | { 28 | auto it = std::find(backends_.begin(), backends_.end(), backend); 29 | if (it == backends_.end()) 30 | { 31 | backends_.push_back(backend); 32 | std::sort(backends_.begin(), backends_.end()); 33 | } 34 | } 35 | 36 | virtual void ReleaseBackend(const InetAddress& backend) 37 | { 38 | auto it = std::find(backends_.begin(), backends_.end(), backend); 39 | if (it != backends_.end()) 40 | { 41 | backends_.erase(it); 42 | } 43 | } 44 | 45 | virtual InetAddress NextBackend() 46 | { 47 | boost::random::uniform_int_distribution dist(0, backends_.size()-1); 48 | return backends_[dist(gen_)]; 49 | } 50 | 51 | private: 52 | std::vector backends_; 53 | boost::random::mt19937 gen_; 54 | }; 55 | 56 | } // namespace claire 57 | 58 | #endif // _CLAIRE_NETTY_LOADBALANCER_RANDOMLOADBALANCER_H_ 59 | -------------------------------------------------------------------------------- /netty/loadbalancer/RoundRobinLoadBalancer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_NETTY_LOADBALANCER_ROUNDROBINBALANCER_H_ 6 | #define _CLAIRE_NETTY_LOADBALANCER_ROUNDROBINBALANCER_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | namespace claire { 19 | 20 | // RoundRobinLoadBalancer need external synchronization 21 | class RoundRobinLoadBalancer : public LoadBalancer, 22 | boost::noncopyable 23 | { 24 | public: 25 | RoundRobinLoadBalancer() : current_(0) {} 26 | 27 | virtual ~RoundRobinLoadBalancer() {} 28 | 29 | virtual void AddBackend(const InetAddress& backend, int weight) 30 | { 31 | auto it = std::find(backends_.begin(), backends_.end(), backend); 32 | if (it == backends_.end()) 33 | { 34 | backends_.push_back(backend); 35 | } 36 | } 37 | 38 | virtual void ReleaseBackend(const InetAddress& backend) 39 | { 40 | backends_.erase(std::remove(backends_.begin(), backends_.end(), backend), 41 | backends_.end()); 42 | } 43 | 44 | virtual InetAddress NextBackend() 45 | { 46 | CHECK(!backends_.empty()); 47 | if (current_ >= backends_.size()) 48 | { 49 | current_ = 0; 50 | } 51 | return backends_[current_++]; 52 | } 53 | 54 | private: 55 | std::vector backends_; 56 | size_t current_; 57 | }; 58 | 59 | } // namespace claire 60 | 61 | #endif // _CLAIRE_NETTY_LOADBALANCER_ROUNDROBINBALANCER_H_ 62 | -------------------------------------------------------------------------------- /netty/resolver/DnsResolver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | namespace claire { 13 | 14 | class DnsResolver : public Resolver, 15 | boost::noncopyable 16 | { 17 | public: 18 | DnsResolver(); 19 | virtual ~DnsResolver(); 20 | 21 | virtual void Init(EventLoop* loop); 22 | virtual void Resolve(const std::string& address, const Resolver::ResolveCallback& callback); 23 | 24 | private: 25 | class Impl; 26 | boost::scoped_ptr impl_; 27 | }; 28 | 29 | } // namespace claire 30 | -------------------------------------------------------------------------------- /netty/resolver/Resolver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace claire { 16 | 17 | class Resolver 18 | { 19 | public: 20 | typedef boost::function&)> ResolveCallback; 21 | 22 | virtual ~Resolver() {} 23 | 24 | /// 25 | /// we use 2-step initialize, you can use loop or not 26 | /// 27 | virtual void Init(EventLoop* loop) {} 28 | 29 | /// 30 | /// sub-class must implement @c Resolve, callback can be called direct or later 31 | /// 32 | virtual void Resolve(const std::string& address, const ResolveCallback& callback) = 0; 33 | }; 34 | 35 | } // namespace claire 36 | -------------------------------------------------------------------------------- /netty/resolver/ResolverFactory.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace claire { 10 | 11 | ResolverFactory::ResolverFactory() 12 | { 13 | creators_.insert({"static", &ResolverCreator}); 14 | } 15 | 16 | ResolverFactory* ResolverFactory::instance() 17 | { 18 | return Singleton::instance(); 19 | } 20 | 21 | Resolver* ResolverFactory::Create(const std::string& name) const 22 | { 23 | MutexLock lock(mutex_); 24 | auto it = creators_.find(name); 25 | if (it == creators_.end()) 26 | { 27 | return nullptr; 28 | } 29 | return (*(it->second))(); 30 | } 31 | 32 | void ResolverFactory::Register(const std::string& name, Creator creator) 33 | { 34 | MutexLock lock(mutex_); 35 | auto it = creators_.find(name); 36 | if (it != creators_.end()) 37 | { 38 | LOG(FATAL) << "ResolverFactory: " << name << " already registered"; 39 | } 40 | else 41 | { 42 | creators_.insert({name, creator}); 43 | } 44 | } 45 | 46 | } // namespace claire 47 | -------------------------------------------------------------------------------- /netty/resolver/ResolverFactory.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace claire { 17 | 18 | template 19 | Resolver* ResolverCreator() 20 | { 21 | return new NewResolver(); 22 | } 23 | 24 | class ResolverFactory : boost::noncopyable 25 | { 26 | public: 27 | typedef Resolver* (*Creator)(); 28 | 29 | static ResolverFactory* instance(); 30 | 31 | /// 32 | /// Create a specific type resolver by resolver's name 33 | /// 34 | Resolver* Create(const std::string& name) const; 35 | 36 | /// 37 | /// Register a resolver creator by name to factory 38 | /// 39 | void Register(const std::string& name, Creator creator); 40 | 41 | private: 42 | ResolverFactory(); 43 | ~ResolverFactory() {} 44 | friend class Singleton; 45 | 46 | mutable Mutex mutex_; 47 | std::map creators_; 48 | }; 49 | 50 | } // namespace claire 51 | -------------------------------------------------------------------------------- /netty/resolver/StaticAddressResolver.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace claire { 13 | 14 | void StaticAddressResolver::Resolve(const std::string& address, const Resolver::ResolveCallback& callback) 15 | { 16 | std::vector v; 17 | boost::algorithm::split(v, address, boost::is_any_of(",;")); 18 | 19 | std::vector result; 20 | for (auto& item : v) 21 | { 22 | result.push_back(InetAddress(item)); 23 | } 24 | 25 | std::sort(result.begin(), result.end()); 26 | result.erase(std::unique(result.begin(), result.end()), result.end()); 27 | 28 | callback(result); 29 | } 30 | 31 | } // namespace claire 32 | -------------------------------------------------------------------------------- /netty/resolver/StaticAddressResolver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-netty Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace claire { 12 | 13 | class StaticAddressResolver : public Resolver, 14 | boost::noncopyable 15 | { 16 | public: 17 | virtual ~StaticAddressResolver() {} 18 | 19 | virtual void Resolve(const std::string& address, const Resolver::ResolveCallback& callback); 20 | }; 21 | 22 | } // namespace claire 23 | -------------------------------------------------------------------------------- /netty/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(CARES_FOUND) 2 | add_executable(dns_test resolver_test.cc) 3 | target_link_libraries(dns_test claire_netty cares) 4 | endif() 5 | 6 | add_executable(HttpRequest_unittest HttpRequest_unittest.cc) 7 | target_link_libraries(HttpRequest_unittest claire_netty gtest gtest_main) 8 | 9 | add_executable(HttpResponse_unittest HttpResponse_unittest.cc) 10 | target_link_libraries(HttpResponse_unittest claire_netty gtest gtest_main) 11 | 12 | add_executable(Uri_unittest Uri_unittest.cc) 13 | target_link_libraries(Uri_unittest claire_netty gtest gtest_main) 14 | -------------------------------------------------------------------------------- /netty/tests/HttpResponse_unittest.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "thirdparty/gtest/gtest.h" 6 | 7 | using namespace claire; 8 | 9 | TEST(HttpResponseTest, SimpleHeader) 10 | { 11 | TcpConnectionPtr ptr; 12 | HttpConnection conn(ptr); 13 | Buffer buf; 14 | buf.Append("HTTP/1.1 200 OK\r\n"); 15 | buf.Append("Content-Length: 45\r\n"); 16 | buf.Append("Connection: Keep-Alive\r\n"); 17 | buf.Append("\r\n"); 18 | 19 | EXPECT_TRUE(conn.Parse(&buf)); 20 | EXPECT_EQ(conn.mutable_response()->headers().size(), 2); 21 | } 22 | 23 | TEST(HttpResponseTest, NonStandardHeader) 24 | { 25 | TcpConnectionPtr ptr; 26 | HttpConnection conn(ptr); 27 | Buffer buf; 28 | 29 | buf.Append("HTTP/1.1 200 OK\r\n"); 30 | buf.Append("Content-Length: 45\r\n"); 31 | buf.Append("Connection: Keep-Alive\r\n"); 32 | buf.Append("HTTP/1.1 200 OK\r\n"); 33 | buf.Append("Content-Type: text/html\r\n"); 34 | buf.Append("\r\n"); 35 | 36 | EXPECT_TRUE(conn.Parse(&buf)); 37 | EXPECT_EQ(conn.mutable_response()->headers().size(), 3); 38 | } 39 | 40 | TEST(HttpResponseTest, SimpleBody) 41 | { 42 | TcpConnectionPtr ptr; 43 | HttpConnection conn(ptr); 44 | Buffer buf; 45 | buf.Append("HTTP/1.1 200 OK\r\n"); 46 | buf.Append("Content-Length: 9\r\n"); 47 | buf.Append("Content-Type: text/html\r\n"); 48 | buf.Append("\r\n"); 49 | buf.Append("robbinfan"); 50 | 51 | EXPECT_TRUE(conn.Parse(&buf)); 52 | EXPECT_EQ(conn.mutable_response()->headers().size(), 2); 53 | EXPECT_EQ(*conn.mutable_response()->mutable_body(), "robbinfan"); 54 | } 55 | 56 | TEST(HttpResponseTest, HeadersToString) 57 | { 58 | HttpResponse response; 59 | response.AddHeader("Content-Length", "10000"); 60 | response.AddHeader("Connection", "keep-alive"); 61 | auto headers = response.headers().ToString(); 62 | EXPECT_EQ("Content-Length: 10000\r\nConnection: keep-alive\r\n\r\n", 63 | headers); 64 | 65 | } 66 | 67 | -------------------------------------------------------------------------------- /netty/tests/Uri_unittest.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "thirdparty/gtest/gtest.h" 5 | 6 | using namespace claire; 7 | 8 | TEST(UriTest, UriSimple) 9 | { 10 | std::string s("http://t.qq.com/hello/world?query#fragment"); 11 | Uri u; 12 | 13 | EXPECT_EQ(true, u.Parse(s)); 14 | EXPECT_EQ("http", u.scheme()); 15 | EXPECT_EQ("", u.username()); 16 | EXPECT_EQ("", u.password()); 17 | EXPECT_EQ("t.qq.com", u.host()); 18 | EXPECT_EQ(0, u.port()); 19 | EXPECT_EQ("/hello/world", u.path()); 20 | EXPECT_EQ("query", u.query()); 21 | EXPECT_EQ("fragment", u.fragment()); 22 | EXPECT_EQ(s, u.ToString()); // canonical 23 | } 24 | 25 | TEST(UriTest, UriRelative) 26 | { 27 | std::string s("/protorpc?x=1&y=2"); 28 | Uri u; 29 | 30 | EXPECT_EQ(true, u.Parse(s)); 31 | EXPECT_EQ("/protorpc", u.path()); 32 | EXPECT_EQ("x=1&y=2", u.query()); 33 | EXPECT_EQ(s, u.ToString()); 34 | } 35 | 36 | TEST(UriTest, UriEscape) 37 | { 38 | EXPECT_EQ("hello%2C%20%2Fworld", UriEscape("hello, /world", EscapeMode::ALL)); 39 | EXPECT_EQ("hello%2C%20/world", UriEscape("hello, /world", EscapeMode::PATH)); 40 | EXPECT_EQ("hello%2C+%2Fworld", UriEscape("hello, /world", EscapeMode::QUERY)); 41 | } 42 | 43 | TEST(UriTest, UriUnescape) 44 | { 45 | EXPECT_EQ("hello, /world", UriUnescape("hello, /world", EscapeMode::ALL)); 46 | EXPECT_EQ("hello, /world", UriUnescape("hello%2c%20%2fworld", EscapeMode::ALL)); 47 | EXPECT_EQ("hello,+/world", UriUnescape("hello%2c+%2fworld", EscapeMode::ALL)); 48 | EXPECT_EQ("hello, /world", UriUnescape("hello%2c+%2fworld", EscapeMode::QUERY)); 49 | EXPECT_EQ("hello/", UriUnescape("hello%2f", EscapeMode::ALL)); 50 | EXPECT_EQ("hello/", UriUnescape("hello%2F", EscapeMode::ALL)); 51 | //EXPECT_THROW(UriUnescape("hello%"), std::invalid_argument); 52 | //EXPECT_THROW(UriUnescape("hello%2"), std::invalid_argument); 53 | //EXPECT_THROW(UriUnescape("hello%2g"), std::invalid_argument); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /netty/tests/resolver_test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace claire; 9 | 10 | EventLoop* g_loop = NULL; 11 | 12 | void result(const StringPiece& s, const std::vector& addrs) 13 | { 14 | for (auto it = addrs.begin(); it != addrs.end(); ++it) 15 | { 16 | LOG(INFO) << "host " << s << " : " << (*it).ip(); 17 | } 18 | 19 | g_loop->quit(); 20 | } 21 | 22 | void resolve(Resolver* r, const StringPiece& s) 23 | { 24 | r->Resolve(s.ToString(), boost::bind(&result, s, _1)); 25 | } 26 | 27 | int main(int argc, char* argv[]) 28 | { 29 | EventLoop loop; 30 | g_loop = &loop; 31 | 32 | DnsResolver resolver; 33 | resolver.Init(&loop); 34 | resolve(&resolver, "www.google.com"); 35 | loop.loop(); 36 | } 37 | -------------------------------------------------------------------------------- /protorpc/.gitignore: -------------------------------------------------------------------------------- 1 | *.pb.* 2 | *Assets.* 3 | -------------------------------------------------------------------------------- /protorpc/BUILD: -------------------------------------------------------------------------------- 1 | resource_library( 2 | name = 'static_resource', 3 | srcs = [ 4 | './assets/forms.html', 5 | './assets/forms.js', 6 | './assets/methods.html' 7 | ] 8 | ) 9 | 10 | cc_binary( 11 | name='protoc-gen-rpc', 12 | srcs=['./generator/protoc-gen-rpc.cc'], 13 | deps=['//thirdparty/protobuf:protobuf', '//thirdparty/protobuf:protoc', '#pthread'], 14 | dynamic_link=True 15 | ) 16 | 17 | gen_rule( 18 | name = 'gen-rpc-proto', 19 | srcs = ['rpcmessage.proto', 'builtin_service.proto'], 20 | cmd = 'sh -x claire/protorpc/gen-rpc.sh $BUILD_DIR', 21 | outs = ['builtin_service.pb.h', 'builtin_service.pb.cc', 'rpcmessage.pb.h', 'rpcmessage.pb.cc'], 22 | deps = ['//thirdparty/protobuf-2.6.1/src:protoc.bin', ':protoc-gen-rpc'] 23 | ) 24 | 25 | cc_library( 26 | name = 'claire_protorpc', 27 | srcs = [ 28 | 'BuiltinService.cc', 29 | 'RpcChannel.cc', 30 | 'RpcCodec.cc', 31 | 'RpcController.cc', 32 | 'RpcServer.cc', 33 | 'RpcUtil.cc', 34 | 'builtin_service.pb.cc', 35 | 'rpcmessage.pb.cc' 36 | ], 37 | deps = [ 38 | '//claire/common:claire_common', 39 | '//claire/netty:claire_netty', 40 | ':static_resource', 41 | ':gen-rpc-proto', 42 | '//thirdparty/protobuf-2.6.1/src:protobuf', 43 | '//thirdparty/snappy-1.1.2:snappy' 44 | ] 45 | ) 46 | -------------------------------------------------------------------------------- /protorpc/BuiltinService.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-protorpc Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | 7 | #include "thirdparty/gflags/gflags.h" 8 | 9 | namespace claire { 10 | namespace protorpc { 11 | 12 | static bool g_protorpc_healthy = true; 13 | 14 | void BuiltinServiceImpl::HeartBeat(RpcControllerPtr& controller, 15 | const HeartBeatRequestPtr& request, 16 | const HeartBeatResponse* response_prototype, 17 | const RpcDoneCallback& done) 18 | { 19 | HeartBeatResponse response; 20 | if (g_protorpc_healthy) 21 | { 22 | response.set_status("Ok"); 23 | } 24 | else 25 | { 26 | response.set_status("Bad"); 27 | } 28 | done(controller, &response); 29 | } 30 | 31 | void BuiltinServiceImpl::Services(RpcControllerPtr& controller, 32 | const ServicesRequestPtr& request, 33 | const ServicesResponse* response_prototype, 34 | const RpcDoneCallback& done) 35 | { 36 | ServicesResponse response; 37 | for (auto it = services_.cbegin(); it != services_.cend(); ++it) 38 | { 39 | if (it->second == this) 40 | { 41 | continue; 42 | } 43 | response.add_services()->set_name(it->second->GetDescriptor()->full_name()); 44 | } 45 | done(controller, &response); 46 | } 47 | 48 | void BuiltinServiceImpl::GetFileSet(RpcControllerPtr& controller, 49 | const GetFileSetRequestPtr& request, 50 | const GetFileSetResponse* response_prototype, 51 | const RpcDoneCallback& done) 52 | { 53 | GetFileSetResponse response; 54 | for (int i = 0; i < request->names_size(); i++) 55 | { 56 | auto it = services_.find(request->names(i)); 57 | if (it != services_.end()) 58 | { 59 | auto file = response.mutable_file_set()->add_file(); 60 | it->second->GetDescriptor()->file()->CopyTo(file); 61 | } 62 | } 63 | done(controller, &response); 64 | } 65 | 66 | } // namespace protorpc 67 | } // namespace claire 68 | -------------------------------------------------------------------------------- /protorpc/BuiltinService.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-protorpc Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include // generate by protoc 11 | 12 | namespace claire { 13 | namespace protorpc { 14 | 15 | class BuiltinServiceImpl : public BuiltinService { 16 | public: 17 | typedef std::map ServiceMap; 18 | 19 | void set_services(const ServiceMap& services) 20 | { 21 | services_ = services; 22 | } 23 | 24 | virtual void HeartBeat(RpcControllerPtr& controller, 25 | const HeartBeatRequestPtr& request, 26 | const HeartBeatResponse* response_prototype, 27 | const RpcDoneCallback& done); 28 | 29 | virtual void Services(RpcControllerPtr& controller, 30 | const ServicesRequestPtr& request, 31 | const ServicesResponse* response_prototype, 32 | const RpcDoneCallback& done); 33 | 34 | virtual void GetFileSet(RpcControllerPtr& controller, 35 | const GetFileSetRequestPtr& request, 36 | const GetFileSetResponse* response_prototype, 37 | const RpcDoneCallback& done); 38 | 39 | private: 40 | ServiceMap services_; 41 | }; 42 | 43 | } // namespace protorpc 44 | } // namespace claire 45 | -------------------------------------------------------------------------------- /protorpc/README.md: -------------------------------------------------------------------------------- 1 | # claire-protorpc 2 | 3 | claire-protorpc is a protobuf-base RPC library implement in C++, for x86-64 Linux. 4 | 5 | It supprt almost all common Client/Server features, with powerful profile/debug/trace/monitor fuctions, make it easier for developers to build applications and services. 6 | 7 | ## Tutorial ## 8 | 9 | See [Tutorial][1] 10 | 11 | ## Features ## 12 | 13 | See [Features][2] 14 | 15 | ## Slide ## 16 | 17 | See [intro to claire-protorpc][3] 18 | 19 | [1]: https://github.com/robbinfan/claire/protorpc/blob/master/Tutorial.md 20 | [2]: https://github.com/robbinfan/claire/protorpc/blob/master/Features.md 21 | [3]: http://www.slideshare.net/fanyu83/claire-protorpc 22 | -------------------------------------------------------------------------------- /protorpc/RpcCodec.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-protorpc Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace claire { 12 | 13 | class Buffer; 14 | class HttpConnection; 15 | typedef boost::shared_ptr HttpConnectionPtr; 16 | 17 | namespace protorpc { 18 | 19 | class RpcMessage; 20 | class RpcCodec : boost::noncopyable 21 | { 22 | public: 23 | typedef boost::function MessageCallback; 25 | 26 | RpcCodec(); 27 | 28 | void set_message_callback(const MessageCallback& callback) 29 | { 30 | message_callback_ = callback; 31 | } 32 | 33 | void ParseFromBuffer(const HttpConnectionPtr& connection, Buffer* buffer) const; 34 | void SerializeToBuffer(RpcMessage& message, Buffer* buffer) const; 35 | 36 | private: 37 | MessageCallback message_callback_; 38 | }; 39 | 40 | } // namespace protorpc 41 | } // namespace claire 42 | -------------------------------------------------------------------------------- /protorpc/RpcController.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-protorpc Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | #include 7 | 8 | namespace claire { 9 | namespace protorpc { 10 | 11 | RpcController::RpcController() 12 | : error_(RPC_SUCCESS), 13 | compress_type_(Compress_None) {} 14 | 15 | void RpcController::Reset() 16 | { 17 | error_ = RPC_SUCCESS; 18 | reason_.clear(); 19 | compress_type_ = Compress_None; 20 | parent_.reset(); 21 | trace_id_.Clear(); 22 | context_ = boost::any(); 23 | } 24 | 25 | bool RpcController::Failed() const 26 | { 27 | return error_ != RPC_SUCCESS; 28 | } 29 | 30 | void RpcController::SetFailed(const std::string& reason) 31 | { 32 | SetFailed(RPC_ERROR_INTERNAL_ERROR, reason); 33 | } 34 | 35 | std::string RpcController::ErrorText() const 36 | { 37 | std::string output; 38 | if (Failed()) 39 | { 40 | output = ErrorCodeToString(error_); 41 | 42 | if (!reason_.empty()) 43 | { 44 | output += ": " + reason_; 45 | } 46 | } 47 | return output; 48 | } 49 | 50 | } // namespace protorpc 51 | } // namespace claire 52 | -------------------------------------------------------------------------------- /protorpc/RpcServer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-protorpc Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | namespace claire { 11 | 12 | class EventLoop; 13 | class InetAddress; 14 | 15 | namespace protorpc { 16 | 17 | class Service; 18 | class RpcServer : boost::noncopyable 19 | { 20 | public: 21 | struct Options 22 | { 23 | bool disable_form = false; 24 | bool disable_json = false; 25 | bool disable_flags = false; 26 | bool disable_pprof = false; 27 | bool disable_statistics = false; 28 | bool disable_builtin_service = false; 29 | }; 30 | 31 | RpcServer(EventLoop* loop, const InetAddress& listen_address) 32 | : RpcServer(loop, listen_address, Options()) {} 33 | RpcServer(EventLoop* loop, const InetAddress& listen_address, const Options& options); 34 | ~RpcServer(); // force dtor 35 | 36 | /// 37 | /// set the num of threads of server, must called before Start 38 | /// 39 | void set_num_threads(int num_threads); 40 | 41 | /// 42 | /// register any service for server, must before Start 43 | /// 44 | void RegisterService(Service* service); 45 | 46 | /// 47 | /// run the server 48 | /// 49 | void Start(); 50 | 51 | private: 52 | class Impl; 53 | boost::shared_ptr impl_; 54 | }; 55 | 56 | } // namespace protorpc 57 | } // namespace claire 58 | -------------------------------------------------------------------------------- /protorpc/RpcUtil.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-protorpc Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace claire { 12 | namespace protorpc { 13 | 14 | const std::string& ErrorCodeToString(int error) 15 | { 16 | auto descriptor = ErrorCode_descriptor()->FindValueByNumber(error); 17 | if (!descriptor) 18 | { 19 | return ErrorCode_descriptor()->FindValueByNumber(RPC_ERROR_UNKNOWN_ERROR)->name(); 20 | } 21 | 22 | return descriptor->name(); 23 | } 24 | 25 | } // namespace protorpc 26 | } // namespace claire 27 | -------------------------------------------------------------------------------- /protorpc/RpcUtil.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-protorpc Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | namespace claire { 10 | namespace protorpc { 11 | 12 | const std::string& ErrorCodeToString(int error); 13 | } // namespace protorpc 14 | } // namespace claire 15 | -------------------------------------------------------------------------------- /protorpc/assets/forms.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | ProtoRPC Methods for {{HOST_NAME}} 4 | 6 | 8 | 10 | 20 | 25 | 26 | 27 | 28 |

ProtoRPC Methods for {{HOST_NAME}}

29 | 30 |
31 | 32 |
33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /protorpc/assets/methods.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form for {{SERVICE_NAME}}.{{METHOD_NAME}} 4 | 6 | 8 | 10 | 20 | 25 | 26 | 27 | 28 | << Back to method selection 29 |

Form for {{SERVICE_NAME}}.{{METHOD_NAME}}

30 | 31 | 32 |
33 | 34 |
35 | 36 |
37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /protorpc/builtin_service.proto: -------------------------------------------------------------------------------- 1 | import "google/protobuf/descriptor.proto"; 2 | import "rpcmessage.proto"; 3 | 4 | package claire.protorpc; 5 | option cc_generic_services = true; 6 | 7 | message HeartBeatRequest { 8 | } 9 | 10 | message HeartBeatResponse { 11 | required string status = 1; 12 | } 13 | 14 | message ServicesRequest { 15 | } 16 | 17 | message ServiceDescriptor { 18 | required string name = 1; 19 | } 20 | 21 | message ServicesResponse { 22 | repeated ServiceDescriptor services = 1; 23 | } 24 | 25 | message GetFileSetRequest { 26 | repeated string names = 1; 27 | } 28 | 29 | message GetFileSetResponse { 30 | required google.protobuf.FileDescriptorSet file_set = 1; 31 | } 32 | 33 | service BuiltinService { 34 | rpc HeartBeat (HeartBeatRequest) returns (HeartBeatResponse); 35 | rpc Services (ServicesRequest) returns (ServicesResponse); 36 | rpc GetFileSet (GetFileSetRequest) returns (GetFileSetResponse); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /protorpc/gen-rpc.sh: -------------------------------------------------------------------------------- 1 | $1/thirdparty/protobuf-2.6.1/src/protoc.bin --plugin=$1/claire/protorpc/protoc-gen-rpc --rpc_out=claire/protorpc/ claire/protorpc/rpcmessage.proto -Iclaire/protorpc -Ithirdparty 2 | $1/thirdparty/protobuf-2.6.1/src/protoc.bin --plugin=$1/claire/protorpc/protoc-gen-rpc --rpc_out=claire/protorpc/ claire/protorpc/builtin_service.proto -Iclaire/protorpc -Ithirdparty 3 | sed -i "s/#include /#include /" claire/protorpc/builtin_service.pb.h 4 | sed -i "s/#include .rpcmessage.pb.h./#include /" claire/protorpc/builtin_service.pb.h 5 | sed -i "/protoc_insertion_point.includes./i#include " claire/protorpc/rpcmessage.pb.h 6 | 7 | 8 | -------------------------------------------------------------------------------- /protorpc/generator/cpp_options.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // http://code.google.com/p/protobuf/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: rennie@google.com (Jeffrey Rennie) 32 | 33 | #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__ 34 | #define GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__ 35 | 36 | #include 37 | 38 | #include "thirdparty/google/protobuf/stubs/common.h" 39 | 40 | namespace google { 41 | namespace protobuf { 42 | namespace compiler { 43 | namespace cpp { 44 | 45 | // Generator options: 46 | struct Options { 47 | Options() : safe_boundary_check(false) { 48 | } 49 | string dllexport_decl; 50 | bool safe_boundary_check; 51 | }; 52 | 53 | } // namespace cpp 54 | } // namespace compiler 55 | } // namespace protobuf 56 | 57 | 58 | } // namespace google 59 | #endif // GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__ 60 | -------------------------------------------------------------------------------- /protorpc/rpcmessage.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-protorpc Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | import "google/protobuf/descriptor.proto"; 6 | 7 | package claire.protorpc; 8 | 9 | enum MessageType { 10 | REQUEST = 1; 11 | RESPONSE = 2; 12 | } 13 | 14 | enum CompressType { 15 | Compress_None = 0; 16 | Compress_Snappy = 1; 17 | } 18 | 19 | enum ErrorCode { 20 | RPC_SUCCESS = 0; 21 | RPC_ERROR_INVALID_CHECKSUM = 1; 22 | RPC_ERROR_INVALID_SERVICE = 2; 23 | RPC_ERROR_INVALID_METHOD = 3; 24 | RPC_ERROR_INVALID_REQUEST = 4; 25 | RPC_ERROR_INVALID_RESPONSE = 5; 26 | RPC_ERROR_AUTH_FAIL = 6; 27 | RPC_ERROR_UNCOMPRESS_FAIL = 7; 28 | RPC_ERROR_PARSE_FAIL = 8; 29 | RPC_ERROR_INVALID_LENGTH = 9; 30 | RPC_ERROR_INVALID_TYPE = 10; 31 | RPC_ERROR_INTERNAL_ERROR = 11; 32 | RPC_ERROR_REQUEST_TIMEOUT = 12; 33 | RPC_ERROR_UNKNOWN_ERROR = 13; 34 | } 35 | 36 | message TraceId { 37 | required int64 trace_id = 1; 38 | required int64 span_id = 2; 39 | optional int64 parent_span_id = 3; 40 | } 41 | 42 | message RpcMessage { 43 | required MessageType type = 1; 44 | required fixed64 id = 2; 45 | 46 | optional string service = 3; 47 | optional string method = 4; 48 | 49 | optional bytes request = 5; 50 | optional bytes response = 6; 51 | 52 | optional ErrorCode error = 7; 53 | optional string reason = 8; 54 | 55 | optional CompressType compress_type = 9; 56 | 57 | optional TraceId trace_id = 10; 58 | } 59 | 60 | extend google.protobuf.ServiceOptions { 61 | // service timeout in milliseconds 62 | optional int64 service_timeout = 10000 [default = 1000]; 63 | } 64 | 65 | extend google.protobuf.MethodOptions { 66 | // method timeout in milliseconds, if not set then use method_timeout 67 | optional int64 method_timeout = 10000; 68 | 69 | optional CompressType request_compress_type = 10001; 70 | optional CompressType expect_response_compress_type = 10002; 71 | } 72 | -------------------------------------------------------------------------------- /zipkin/.gitignore: -------------------------------------------------------------------------------- 1 | *.cpp 2 | *_constants.* 3 | *_types.* 4 | Facebook* 5 | scribe*.h 6 | zipkinCore*.h 7 | -------------------------------------------------------------------------------- /zipkin/BUILD: -------------------------------------------------------------------------------- 1 | thrift_library( 2 | name = 'fb303', 3 | srcs = 'fb303.thrift' 4 | ) 5 | 6 | thrift_library( 7 | name = 'scribe', 8 | srcs = 'scribe.thrift', 9 | deps = ':fb303' 10 | ) 11 | 12 | thrift_library( 13 | name = 'zipkinCore', 14 | srcs = 'zipkinCore.thrift', 15 | deps = ':scribe' 16 | ) 17 | 18 | cc_library( 19 | name = 'claire_zipkin', 20 | srcs = [ 21 | 'ZipkinTracer.cc', 22 | 'ScribeClient.cc' 23 | ], 24 | deps = [':zipkinCore'] 25 | ) 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /zipkin/ScribeClient.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-zipkin Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_ZIPKIN_SCRIBECLIENT_H_ 6 | #define _CLAIRE_ZIPKIN_SCRIBECLIENT_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | namespace claire { 14 | 15 | class InetAddress; 16 | class ScribeClient : boost::noncopyable 17 | { 18 | public: 19 | ScribeClient(const InetAddress& scribe_address); 20 | ~ScribeClient(); 21 | 22 | void Log(const std::string& category, const std::string& message); 23 | 24 | private: 25 | class Impl; 26 | boost::scoped_ptr impl_; 27 | }; 28 | 29 | } // namespace claire 30 | #endif // _CLAIRE_ZIPKIN_SCRIBECLIENT_H_ 31 | -------------------------------------------------------------------------------- /zipkin/ZipkinTracer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The claire-zipkin Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef _CLAIRE_ZIPKIN_ZIPKINTRACER_H_ 6 | #define _CLAIRE_ZIPKIN_ZIPKINTRACER_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace claire { 15 | 16 | class InetAddress; 17 | class Trace; 18 | class Annotation; 19 | class BinaryAnnotation; 20 | 21 | class ZipkinTracer : public Tracer, 22 | boost::noncopyable 23 | { 24 | public: 25 | ZipkinTracer(const InetAddress& scribe_address); 26 | virtual ~ZipkinTracer(); 27 | 28 | virtual void Record(const Trace& trace, const Annotation& annotation); 29 | virtual void Record(const Trace& trace, const BinaryAnnotation& annotation); 30 | 31 | private: 32 | ScribeClient client_; 33 | }; 34 | 35 | } // namespace claire 36 | 37 | #endif // _CLAIRE_ZIPKIN_ZIPKINTRACER_H_ 38 | -------------------------------------------------------------------------------- /zipkin/fb303.thrift: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | /** 21 | * fb303.thrift 22 | */ 23 | 24 | namespace java com.facebook.fb303 25 | namespace cpp facebook.fb303 26 | 27 | /** 28 | * Common status reporting mechanism across all services 29 | */ 30 | enum fb_status { 31 | DEAD = 0, 32 | STARTING = 1, 33 | ALIVE = 2, 34 | STOPPING = 3, 35 | STOPPED = 4, 36 | WARNING = 5, 37 | } 38 | 39 | /** 40 | * Standard base service 41 | */ 42 | service FacebookService { 43 | 44 | /** 45 | * Returns a descriptive name of the service 46 | */ 47 | string getName(), 48 | 49 | /** 50 | * Returns the version of the service 51 | */ 52 | string getVersion(), 53 | 54 | /** 55 | * Gets the status of this service 56 | */ 57 | fb_status getStatus(), 58 | 59 | /** 60 | * User friendly description of status, such as why the service is in 61 | * the dead or warning state, or what is being started or stopped. 62 | */ 63 | string getStatusDetails(), 64 | 65 | /** 66 | * Gets the counters for this service 67 | */ 68 | map getCounters(), 69 | 70 | /** 71 | * Gets the value of a single counter 72 | */ 73 | i64 getCounter(1: string key), 74 | 75 | /** 76 | * Sets an option 77 | */ 78 | void setOption(1: string key, 2: string value), 79 | 80 | /** 81 | * Gets an option 82 | */ 83 | string getOption(1: string key), 84 | 85 | /** 86 | * Gets all options 87 | */ 88 | map getOptions(), 89 | 90 | /** 91 | * Returns a CPU profile over the given time interval (client and server 92 | * must agree on the profile format). 93 | */ 94 | string getCpuProfile(1: i32 profileDurationInSec), 95 | 96 | /** 97 | * Returns the unix time that the server has been running since 98 | */ 99 | i64 aliveSince(), 100 | 101 | /** 102 | * Tell the server to reload its configuration, reopen log files, etc 103 | */ 104 | oneway void reinitialize(), 105 | 106 | /** 107 | * Suggest a shutdown to the server 108 | */ 109 | oneway void shutdown(), 110 | 111 | } 112 | -------------------------------------------------------------------------------- /zipkin/scribe.thrift: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/thrift --gen cpp:pure_enums --gen php 2 | 3 | ## Copyright (c) 2007-2008 Facebook 4 | ## 5 | ## Licensed under the Apache License, Version 2.0 (the "License"); 6 | ## you may not use this file except in compliance with the License. 7 | ## You may obtain a copy of the License at 8 | ## 9 | ## http://www.apache.org/licenses/LICENSE-2.0 10 | ## 11 | ## Unless required by applicable law or agreed to in writing, software 12 | ## distributed under the License is distributed on an "AS IS" BASIS, 13 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ## See the License for the specific language governing permissions and 15 | ## limitations under the License. 16 | ## 17 | ## See accompanying file LICENSE or visit the Scribe site at: 18 | ## http://developers.facebook.com/scribe/ 19 | 20 | include "./fb303.thrift" 21 | 22 | namespace cpp scribe.thrift 23 | namespace java scribe.thrift 24 | namespace perl Scribe.Thrift 25 | 26 | enum ResultCode 27 | { 28 | OK, 29 | TRY_LATER 30 | } 31 | 32 | struct LogEntry 33 | { 34 | 1: string category, 35 | 2: string message 36 | } 37 | 38 | service scribe extends fb303.FacebookService 39 | { 40 | ResultCode Log(1: list messages); 41 | } 42 | -------------------------------------------------------------------------------- /zipkin/zipkinCore.thrift: -------------------------------------------------------------------------------- 1 | # Copyright 2012 Twitter Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | namespace java com.twitter.zipkin.gen 15 | namespace cpp zipkin.thrift 16 | 17 | //************** Collection related structs ************** 18 | 19 | // these are the annotations we always expect to find in a span 20 | const string CLIENT_SEND = "cs" 21 | const string CLIENT_RECV = "cr" 22 | const string SERVER_SEND = "ss" 23 | const string SERVER_RECV = "sr" 24 | 25 | // this represents a host and port in a network 26 | struct Endpoint { 27 | 1: i32 ipv4, 28 | 2: i16 port // beware that this will give us negative ports. some conversion needed 29 | 3: string service_name // which service did this operation happen on? 30 | } 31 | 32 | // some event took place, either one by the framework or by the user 33 | struct Annotation { 34 | 1: i64 timestamp // microseconds from epoch 35 | 2: string value // what happened at the timestamp? 36 | 3: optional Endpoint host // host this happened on 37 | } 38 | 39 | enum AnnotationType { BOOL, BYTES, I16, I32, I64, DOUBLE, STRING } 40 | 41 | struct BinaryAnnotation { 42 | 1: string key, 43 | 2: binary value, 44 | 3: AnnotationType annotation_type, 45 | 4: optional Endpoint host 46 | } 47 | 48 | struct Span { 49 | 1: i64 trace_id // unique trace id, use for all spans in trace 50 | 3: string name, // span name, rpc method for example 51 | 4: i64 id, // unique span id, only used for this span 52 | 5: optional i64 parent_id, // parent span id 53 | 6: list annotations, // list of all annotations/events that occured 54 | 8: list binary_annotations // any binary annotations 55 | } 56 | --------------------------------------------------------------------------------