diff options
author | nga <nga@yandex-team.ru> | 2022-02-10 16:48:09 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:48:09 +0300 |
commit | c2a1af049e9deca890e9923abe64fe6c59060348 (patch) | |
tree | b222e5ac2e2e98872661c51ccceee5da0d291e13 /library/cpp | |
parent | 1f553f46fb4f3c5eec631352cdd900a0709016af (diff) | |
download | ydb-c2a1af049e9deca890e9923abe64fe6c59060348.tar.gz |
Restoring authorship annotation for <nga@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp')
388 files changed, 14274 insertions, 14274 deletions
diff --git a/library/cpp/actors/dnscachelib/timekeeper.h b/library/cpp/actors/dnscachelib/timekeeper.h index d8dc5560bc..0528d8549c 100644 --- a/library/cpp/actors/dnscachelib/timekeeper.h +++ b/library/cpp/actors/dnscachelib/timekeeper.h @@ -4,7 +4,7 @@ #include <util/generic/singleton.h> #include <util/string/cast.h> #include <util/system/thread.h> -#include <util/system/event.h> +#include <util/system/event.h> #include <util/system/env.h> #include <cstdlib> @@ -59,11 +59,11 @@ private: static void* Worker(void* arg) { TTimeKeeper* owner = static_cast<TTimeKeeper*>(arg); - do { + do { /* Race condition may occur here but locking looks too expensive */ gettimeofday(&owner->CurrentTime, nullptr); - } while (!owner->Exit.WaitT(TDuration::MicroSeconds(UpdateInterval))); + } while (!owner->Exit.WaitT(TDuration::MicroSeconds(UpdateInterval))); return nullptr; } diff --git a/library/cpp/balloc/malloc-info.cpp b/library/cpp/balloc/malloc-info.cpp index de48ae41ce..604b1fb145 100644 --- a/library/cpp/balloc/malloc-info.cpp +++ b/library/cpp/balloc/malloc-info.cpp @@ -1,13 +1,13 @@ #include <library/cpp/malloc/api/malloc.h> - + #include <string.h> - -using namespace NMalloc; - + +using namespace NMalloc; + extern "C" void DisableBalloc(); extern "C" void EnableBalloc(); extern "C" bool BallocDisabled(); - + namespace { bool SetAllocParam(const char* name, const char* value) { if (strcmp(name, "disable") == 0) { @@ -30,12 +30,12 @@ namespace { } } -TMallocInfo NMalloc::MallocInfo() { - TMallocInfo r; +TMallocInfo NMalloc::MallocInfo() { + TMallocInfo r; - r.Name = "balloc"; + r.Name = "balloc"; r.SetParam = SetAllocParam; r.CheckParam = CheckAllocParam; - return r; -} + return r; +} diff --git a/library/cpp/cgiparam/cgiparam_ut.cpp b/library/cpp/cgiparam/cgiparam_ut.cpp index e33efa3f26..a562342084 100644 --- a/library/cpp/cgiparam/cgiparam_ut.cpp +++ b/library/cpp/cgiparam/cgiparam_ut.cpp @@ -12,9 +12,9 @@ Y_UNIT_TEST_SUITE(TCgiParametersTest) { UNIT_ASSERT(C.Has("ag0", "")); UNIT_ASSERT(!C.Has("a", "bbb")); UNIT_ASSERT(!C.Has("aaa", "bb")); - - UNIT_ASSERT(C.Has("ccc")); - UNIT_ASSERT(!C.Has("zzzzzz")); + + UNIT_ASSERT(C.Has("ccc")); + UNIT_ASSERT(!C.Has("zzzzzz")); } Y_UNIT_TEST(TestQuick) { diff --git a/library/cpp/containers/compact_vector/compact_vector.h b/library/cpp/containers/compact_vector/compact_vector.h index 0e9667c906..dbe7473f0c 100644 --- a/library/cpp/containers/compact_vector/compact_vector.h +++ b/library/cpp/containers/compact_vector/compact_vector.h @@ -1,209 +1,209 @@ #pragma once - -#include <util/generic/yexception.h> -#include <util/generic/utility.h> + +#include <util/generic/yexception.h> +#include <util/generic/utility.h> #include <util/memory/alloc.h> #include <util/stream/output.h> -#include <util/system/yassert.h> - +#include <util/system/yassert.h> + #include <cstdlib> // vector that is 8 bytes when empty (TVector is 24 bytes) - -template <typename T> -class TCompactVector { -private: - typedef TCompactVector<T> TThis; - - // XXX: make header independent on T and introduce nullptr - struct THeader { - size_t Size; - size_t Capacity; - }; - - T* Ptr; - - THeader* Header() { + +template <typename T> +class TCompactVector { +private: + typedef TCompactVector<T> TThis; + + // XXX: make header independent on T and introduce nullptr + struct THeader { + size_t Size; + size_t Capacity; + }; + + T* Ptr; + + THeader* Header() { return ((THeader*)Ptr) - 1; - } - - const THeader* Header() const { + } + + const THeader* Header() const { return ((THeader*)Ptr) - 1; - } - -public: - typedef T* TIterator; - typedef const T* TConstIterator; - - typedef TIterator iterator; - typedef TConstIterator const_iterator; - - TCompactVector() + } + +public: + typedef T* TIterator; + typedef const T* TConstIterator; + + typedef TIterator iterator; + typedef TConstIterator const_iterator; + + TCompactVector() : Ptr(nullptr) { } - - TCompactVector(const TThis& that) + + TCompactVector(const TThis& that) : Ptr(nullptr) - { - Reserve(that.Size()); - for (TConstIterator i = that.Begin(); i != that.End(); ++i) { - PushBack(*i); - } - } - - ~TCompactVector() { - for (size_t i = 0; i < Size(); ++i) { - try { - (*this)[i].~T(); - } catch (...) { - } - } + { + Reserve(that.Size()); + for (TConstIterator i = that.Begin(); i != that.End(); ++i) { + PushBack(*i); + } + } + + ~TCompactVector() { + for (size_t i = 0; i < Size(); ++i) { + try { + (*this)[i].~T(); + } catch (...) { + } + } if (Ptr) - free(Header()); - } - - TIterator Begin() { - return Ptr; - } - - TIterator End() { - return Ptr + Size(); - } - - TConstIterator Begin() const { - return Ptr; - } - - TConstIterator End() const { - return Ptr + Size(); - } - - iterator begin() { - return Begin(); - } - - const_iterator begin() const { - return Begin(); - } - - iterator end() { - return End(); - } - - const_iterator end() const { - return End(); - } - - void Swap(TThis& that) { - DoSwap(Ptr, that.Ptr); - } - - void Reserve(size_t newCapacity) { - if (newCapacity <= Capacity()) { + free(Header()); + } + + TIterator Begin() { + return Ptr; + } + + TIterator End() { + return Ptr + Size(); + } + + TConstIterator Begin() const { + return Ptr; + } + + TConstIterator End() const { + return Ptr + Size(); + } + + iterator begin() { + return Begin(); + } + + const_iterator begin() const { + return Begin(); + } + + iterator end() { + return End(); + } + + const_iterator end() const { + return End(); + } + + void Swap(TThis& that) { + DoSwap(Ptr, that.Ptr); + } + + void Reserve(size_t newCapacity) { + if (newCapacity <= Capacity()) { } else if (Ptr == nullptr) { void* mem = ::malloc(sizeof(THeader) + newCapacity * sizeof(T)); if (mem == nullptr) - ythrow yexception() << "out of memory"; + ythrow yexception() << "out of memory"; Ptr = (T*)(((THeader*)mem) + 1); - Header()->Size = 0; - Header()->Capacity = newCapacity; - } else { - TThis copy; - size_t realNewCapacity = Max(Capacity() * 2, newCapacity); - copy.Reserve(realNewCapacity); - for (TConstIterator it = Begin(); it != End(); ++it) { - copy.PushBack(*it); - } - Swap(copy); - } - } - - size_t Size() const { + Header()->Size = 0; + Header()->Capacity = newCapacity; + } else { + TThis copy; + size_t realNewCapacity = Max(Capacity() * 2, newCapacity); + copy.Reserve(realNewCapacity); + for (TConstIterator it = Begin(); it != End(); ++it) { + copy.PushBack(*it); + } + Swap(copy); + } + } + + size_t Size() const { return Ptr ? Header()->Size : 0; - } - - size_t size() const { - return Size(); - } - - bool Empty() const { - return Size() == 0; - } - - bool empty() const { - return Empty(); - } - - size_t Capacity() const { + } + + size_t size() const { + return Size(); + } + + bool Empty() const { + return Size() == 0; + } + + bool empty() const { + return Empty(); + } + + size_t Capacity() const { return Ptr ? Header()->Capacity : 0; - } - - void PushBack(const T& elem) { - Reserve(Size() + 1); - new (Ptr + Size()) T(elem); - ++(Header()->Size); - } - - T& Back() { - return *(End() - 1); - } - - const T& Back() const { - return *(End() - 1); - } - - T& back() { - return Back(); - } - - const T& back() const { - return Back(); - } - - TIterator Insert(TIterator pos, const T& elem) { + } + + void PushBack(const T& elem) { + Reserve(Size() + 1); + new (Ptr + Size()) T(elem); + ++(Header()->Size); + } + + T& Back() { + return *(End() - 1); + } + + const T& Back() const { + return *(End() - 1); + } + + T& back() { + return Back(); + } + + const T& back() const { + return Back(); + } + + TIterator Insert(TIterator pos, const T& elem) { Y_ASSERT(pos >= Begin()); Y_ASSERT(pos <= End()); - - size_t posn = pos - Begin(); - if (pos == End()) { - PushBack(elem); - } else { + + size_t posn = pos - Begin(); + if (pos == End()) { + PushBack(elem); + } else { Y_ASSERT(Size() > 0); - - Reserve(Size() + 1); - - PushBack(*(End() - 1)); - - for (size_t i = Size() - 2; i + 1 > posn; --i) { - (*this)[i + 1] = (*this)[i]; - } - - (*this)[posn] = elem; - } - return Begin() + posn; - } - - iterator insert(iterator pos, const T& elem) { - return Insert(pos, elem); - } - - void Clear() { - TThis clean; - Swap(clean); - } - - void clear() { - Clear(); - } - + + Reserve(Size() + 1); + + PushBack(*(End() - 1)); + + for (size_t i = Size() - 2; i + 1 > posn; --i) { + (*this)[i + 1] = (*this)[i]; + } + + (*this)[posn] = elem; + } + return Begin() + posn; + } + + iterator insert(iterator pos, const T& elem) { + return Insert(pos, elem); + } + + void Clear() { + TThis clean; + Swap(clean); + } + + void clear() { + Clear(); + } + T& operator[](size_t index) { Y_ASSERT(index < Size()); - return Ptr[index]; - } - + return Ptr[index]; + } + const T& operator[](size_t index) const { Y_ASSERT(index < Size()); - return Ptr[index]; - } -}; + return Ptr[index]; + } +}; diff --git a/library/cpp/containers/compact_vector/compact_vector_ut.cpp b/library/cpp/containers/compact_vector/compact_vector_ut.cpp index cb5e603fd9..7d413d6575 100644 --- a/library/cpp/containers/compact_vector/compact_vector_ut.cpp +++ b/library/cpp/containers/compact_vector/compact_vector_ut.cpp @@ -1,39 +1,39 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "compact_vector.h" - + +#include "compact_vector.h" + Y_UNIT_TEST_SUITE(TCompactVectorTest) { Y_UNIT_TEST(TestSimple1) { - } - + } + Y_UNIT_TEST(TestSimple) { - TCompactVector<ui32> vector; - for (ui32 i = 0; i < 10000; ++i) { - vector.PushBack(i + 20); - UNIT_ASSERT_VALUES_EQUAL(i + 1, vector.Size()); - } - for (ui32 i = 0; i < 10000; ++i) { - UNIT_ASSERT_VALUES_EQUAL(i + 20, vector[i]); - } - } - + TCompactVector<ui32> vector; + for (ui32 i = 0; i < 10000; ++i) { + vector.PushBack(i + 20); + UNIT_ASSERT_VALUES_EQUAL(i + 1, vector.Size()); + } + for (ui32 i = 0; i < 10000; ++i) { + UNIT_ASSERT_VALUES_EQUAL(i + 20, vector[i]); + } + } + Y_UNIT_TEST(TestInsert) { - TCompactVector<ui32> vector; - - for (ui32 i = 0; i < 10; ++i) { - vector.PushBack(i + 2); - } - - vector.Insert(vector.Begin(), 99); - + TCompactVector<ui32> vector; + + for (ui32 i = 0; i < 10; ++i) { + vector.PushBack(i + 2); + } + + vector.Insert(vector.Begin(), 99); + UNIT_ASSERT_VALUES_EQUAL(11u, vector.Size()); UNIT_ASSERT_VALUES_EQUAL(99u, vector[0]); - for (ui32 i = 0; i < 10; ++i) { - UNIT_ASSERT_VALUES_EQUAL(i + 2, vector[i + 1]); - } - - vector.Insert(vector.Begin() + 3, 77); - + for (ui32 i = 0; i < 10; ++i) { + UNIT_ASSERT_VALUES_EQUAL(i + 2, vector[i + 1]); + } + + vector.Insert(vector.Begin() + 3, 77); + UNIT_ASSERT_VALUES_EQUAL(12u, vector.Size()); UNIT_ASSERT_VALUES_EQUAL(99u, vector[0]); UNIT_ASSERT_VALUES_EQUAL(2u, vector[1]); @@ -42,5 +42,5 @@ Y_UNIT_TEST_SUITE(TCompactVectorTest) { UNIT_ASSERT_VALUES_EQUAL(4u, vector[4]); UNIT_ASSERT_VALUES_EQUAL(5u, vector[5]); UNIT_ASSERT_VALUES_EQUAL(11u, vector[11]); - } -} + } +} diff --git a/library/cpp/containers/comptrie/array_with_size.h b/library/cpp/containers/comptrie/array_with_size.h index 4a1c85ce68..36e61c7410 100644 --- a/library/cpp/containers/comptrie/array_with_size.h +++ b/library/cpp/containers/comptrie/array_with_size.h @@ -1,67 +1,67 @@ #pragma once - -#include <util/generic/ptr.h> -#include <util/generic/noncopyable.h> -#include <util/generic/utility.h> + +#include <util/generic/ptr.h> +#include <util/generic/noncopyable.h> +#include <util/generic/utility.h> #include <util/system/sys_alloc.h> - -template <typename T> + +template <typename T> class TArrayWithSizeHolder : TNonCopyable { - typedef TArrayWithSizeHolder<T> TThis; - - T* Data; - -public: + typedef TArrayWithSizeHolder<T> TThis; + + T* Data; + +public: TArrayWithSizeHolder() : Data(nullptr) { } - - ~TArrayWithSizeHolder() { - if (!Data) - return; - for (size_t i = 0; i < Size(); ++i) { - try { - Data[i].~T(); - } catch (...) { - } - } + + ~TArrayWithSizeHolder() { + if (!Data) + return; + for (size_t i = 0; i < Size(); ++i) { + try { + Data[i].~T(); + } catch (...) { + } + } y_deallocate(((size_t*)Data) - 1); - } - - void Swap(TThis& copy) { - DoSwap(Data, copy.Data); - } - - void Resize(size_t newSize) { - if (newSize == Size()) - return; - TThis copy; + } + + void Swap(TThis& copy) { + DoSwap(Data, copy.Data); + } + + void Resize(size_t newSize) { + if (newSize == Size()) + return; + TThis copy; copy.Data = (T*)(((size_t*)y_allocate(sizeof(size_t) + sizeof(T) * newSize)) + 1); - // does not handle constructor exceptions properly - for (size_t i = 0; i < Min(Size(), newSize); ++i) { - new (copy.Data + i) T(Data[i]); - } - for (size_t i = Min(Size(), newSize); i < newSize; ++i) { - new (copy.Data + i) T; - } + // does not handle constructor exceptions properly + for (size_t i = 0; i < Min(Size(), newSize); ++i) { + new (copy.Data + i) T(Data[i]); + } + for (size_t i = Min(Size(), newSize); i < newSize; ++i) { + new (copy.Data + i) T; + } ((size_t*)copy.Data)[-1] = newSize; - Swap(copy); - } - - size_t Size() const { + Swap(copy); + } + + size_t Size() const { return Data ? ((size_t*)Data)[-1] : 0; - } - - bool Empty() const { - return Size() == 0; - } - - T* Get() { - return Data; - } - - const T* Get() const { - return Data; - } -}; + } + + bool Empty() const { + return Size() == 0; + } + + T* Get() { + return Data; + } + + const T* Get() const { + return Data; + } +}; diff --git a/library/cpp/containers/comptrie/comptrie_builder.h b/library/cpp/containers/comptrie/comptrie_builder.h index 652c3151c5..cf7d2e39a3 100644 --- a/library/cpp/containers/comptrie/comptrie_builder.h +++ b/library/cpp/containers/comptrie/comptrie_builder.h @@ -53,19 +53,19 @@ public: bool Add(const TSymbol* key, size_t keylen, const TData& value); bool Add(const TKeyBuf& key, const TData& value) { return Add(key.data(), key.size(), value); - } + } - // add already serialized data + // add already serialized data bool AddPtr(const TSymbol* key, size_t keylen, const char* data); bool AddPtr(const TKeyBuf& key, const char* data) { return AddPtr(key.data(), key.size(), data); - } - + } + bool AddSubtreeInFile(const TSymbol* key, size_t keylen, const TString& filename); bool AddSubtreeInFile(const TKeyBuf& key, const TString& filename) { return AddSubtreeInFile(key.data(), key.size(), filename); - } - + } + bool AddSubtreeInBuffer(const TSymbol* key, size_t keylen, TArrayWithSizeHolder<char>&& buffer); bool AddSubtreeInBuffer(const TKeyBuf& key, TArrayWithSizeHolder<char>&& buffer) { return AddSubtreeInBuffer(key.data(), key.size(), std::move(buffer)); @@ -74,8 +74,8 @@ public: bool Find(const TSymbol* key, size_t keylen, TData* value) const; bool Find(const TKeyBuf& key, TData* value = nullptr) const { return Find(key.data(), key.size(), value); - } - + } + bool FindLongestPrefix(const TSymbol* key, size_t keylen, size_t* prefixLen, TData* value = nullptr) const; bool FindLongestPrefix(const TKeyBuf& key, size_t* prefixLen, TData* value = nullptr) const { return FindLongestPrefix(key.data(), key.size(), prefixLen, value); @@ -85,8 +85,8 @@ public: size_t SaveAndDestroy(IOutputStream& os); size_t SaveToFile(const TString& fileName) const { TFixedBufferFileOutput out(fileName); - return Save(out); - } + return Save(out); + } void Clear(); // Returns all memory to the system and resets the builder state. diff --git a/library/cpp/containers/comptrie/comptrie_builder.inl b/library/cpp/containers/comptrie/comptrie_builder.inl index 1410d4590f..f273fa6571 100644 --- a/library/cpp/containers/comptrie/comptrie_builder.inl +++ b/library/cpp/containers/comptrie/comptrie_builder.inl @@ -28,54 +28,54 @@ template <class T, class D, class S> class TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl { protected: TMemoryPool Pool; - size_t PayloadSize; - THolder<TFixedSizeAllocator> NodeAllocator; + size_t PayloadSize; + THolder<TFixedSizeAllocator> NodeAllocator; class TNode; - class TArc; + class TArc; TNode* Root; TCompactTrieBuilderFlags Flags; size_t EntryCount; size_t NodeCount; - TPacker Packer; - - enum EPayload { - DATA_ABSENT, - DATA_INSIDE, - DATA_MALLOCED, - DATA_IN_MEMPOOL, - }; - + TPacker Packer; + + enum EPayload { + DATA_ABSENT, + DATA_INSIDE, + DATA_MALLOCED, + DATA_IN_MEMPOOL, + }; + protected: void ConvertSymbolArrayToChar(const TSymbol* key, size_t keylen, TTempBuf& buf, size_t ckeylen) const; - void NodeLinkTo(TNode* thiz, const TBlob& label, TNode* node); + void NodeLinkTo(TNode* thiz, const TBlob& label, TNode* node); TNode* NodeForwardAdd(TNode* thiz, const char* label, size_t len, size_t& passed, size_t* nodeCount); bool FindEntryImpl(const char* key, size_t keylen, TData* value) const; bool FindLongestPrefixImpl(const char* keyptr, size_t keylen, size_t* prefixLen, TData* value) const; - size_t NodeMeasureSubtree(TNode* thiz) const; + size_t NodeMeasureSubtree(TNode* thiz) const; ui64 NodeSaveSubtree(TNode* thiz, IOutputStream& os) const; ui64 NodeSaveSubtreeAndDestroy(TNode* thiz, IOutputStream& osy); - void NodeBufferSubtree(TNode* thiz); - - size_t NodeMeasureLeafValue(TNode* thiz) const; + void NodeBufferSubtree(TNode* thiz); + + size_t NodeMeasureLeafValue(TNode* thiz) const; ui64 NodeSaveLeafValue(TNode* thiz, IOutputStream& os) const; - + virtual ui64 ArcMeasure(const TArc* thiz, size_t leftsize, size_t rightsize) const; - + virtual ui64 ArcSaveSelf(const TArc* thiz, IOutputStream& os) const; ui64 ArcSave(const TArc* thiz, IOutputStream& os) const; ui64 ArcSaveAndDestroy(const TArc* thiz, IOutputStream& os); - + public: TCompactTrieBuilderImpl(TCompactTrieBuilderFlags flags, TPacker packer, IAllocator* alloc); virtual ~TCompactTrieBuilderImpl(); - void DestroyNode(TNode* node); - void NodeReleasePayload(TNode* thiz); - + void DestroyNode(TNode* node); + void NodeReleasePayload(TNode* thiz); + char* AddEntryForData(const TSymbol* key, size_t keylen, size_t dataLen, bool& isNewAddition); TNode* AddEntryForSomething(const TSymbol* key, size_t keylen, bool& isNewAddition); - + bool AddEntry(const TSymbol* key, size_t keylen, const TData& value); bool AddEntryPtr(const TSymbol* key, size_t keylen, const char* value); bool AddSubtreeInFile(const TSymbol* key, size_t keylen, const TString& fileName); @@ -98,38 +98,38 @@ public: }; template <class T, class D, class S> -class TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TArc { +class TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TArc { public: - TBlob Label; - TNode* Node; - mutable size_t LeftOffset; - mutable size_t RightOffset; + TBlob Label; + TNode* Node; + mutable size_t LeftOffset; + mutable size_t RightOffset; - TArc(const TBlob& lbl, TNode* nd); -}; + TArc(const TBlob& lbl, TNode* nd); +}; -template <class T, class D, class S> -class TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode { -public: - typedef typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl TBuilderImpl; - typedef typename TBuilderImpl::TArc TArc; +template <class T, class D, class S> +class TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode { +public: + typedef typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl TBuilderImpl; + typedef typename TBuilderImpl::TArc TArc; - struct ISubtree { + struct ISubtree { virtual ~ISubtree() = default; - virtual bool IsLast() const = 0; - virtual ui64 Measure(const TBuilderImpl* builder) const = 0; + virtual bool IsLast() const = 0; + virtual ui64 Measure(const TBuilderImpl* builder) const = 0; virtual ui64 Save(const TBuilderImpl* builder, IOutputStream& os) const = 0; virtual ui64 SaveAndDestroy(TBuilderImpl* builder, IOutputStream& os) = 0; - virtual void Destroy(TBuilderImpl*) { } + virtual void Destroy(TBuilderImpl*) { } // Tries to find key in subtree. // Returns next node to find the key in (to avoid recursive calls) // If it has end result, writes it to @value and @result arguments and returns nullptr virtual const TNode* Find(TStringBuf& key, TData* value, bool& result, const TPacker& packer) const = 0; virtual const TNode* FindLongestPrefix(TStringBuf& key, TData* value, bool& result, const TPacker& packer) const = 0; - }; - - class TArcSet: public ISubtree, public TCompactVector<TArc> { + }; + + class TArcSet: public ISubtree, public TCompactVector<TArc> { public: typedef typename TCompactVector<TArc>::iterator iterator; typedef typename TCompactVector<TArc>::const_iterator const_iterator; @@ -141,35 +141,35 @@ public: iterator Find(char ch); const_iterator Find(char ch) const; void Add(const TBlob& s, TNode* node); - + bool IsLast() const override { - return this->Empty(); - } - + return this->Empty(); + } + const TNode* Find(TStringBuf& key, TData* value, bool& result, const TPacker& packer) const override; const TNode* FindLongestPrefix(TStringBuf& key, TData* value, bool& result, const TPacker& packer) const override { return Find(key, value, result, packer); } ui64 Measure(const TBuilderImpl* builder) const override { - return MeasureRange(builder, 0, this->size()); - } - - ui64 MeasureRange(const TBuilderImpl* builder, size_t from, size_t to) const { - if (from >= to) - return 0; - - size_t median = (from + to) / 2; + return MeasureRange(builder, 0, this->size()); + } + + ui64 MeasureRange(const TBuilderImpl* builder, size_t from, size_t to) const { + if (from >= to) + return 0; + + size_t median = (from + to) / 2; size_t leftsize = (size_t)MeasureRange(builder, from, median); size_t rightsize = (size_t)MeasureRange(builder, median + 1, to); - - return builder->ArcMeasure(&(*this)[median], leftsize, rightsize); - } - + + return builder->ArcMeasure(&(*this)[median], leftsize, rightsize); + } + ui64 Save(const TBuilderImpl* builder, IOutputStream& os) const override { - return SaveRange(builder, 0, this->size(), os); - } - + return SaveRange(builder, 0, this->size(), os); + } + ui64 SaveAndDestroy(TBuilderImpl* builder, IOutputStream& os) override { ui64 result = SaveRangeAndDestroy(builder, 0, this->size(), os); Destroy(builder); @@ -177,17 +177,17 @@ public: } ui64 SaveRange(const TBuilderImpl* builder, size_t from, size_t to, IOutputStream& os) const { - if (from >= to) - return 0; - - size_t median = (from + to) / 2; - - ui64 written = builder->ArcSave(&(*this)[median], os); - written += SaveRange(builder, from, median, os); - written += SaveRange(builder, median + 1, to, os); - return written; - } - + if (from >= to) + return 0; + + size_t median = (from + to) / 2; + + ui64 written = builder->ArcSave(&(*this)[median], os); + written += SaveRange(builder, from, median, os); + written += SaveRange(builder, median + 1, to, os); + return written; + } + ui64 SaveRangeAndDestroy(TBuilderImpl* builder, size_t from, size_t to, IOutputStream& os) { if (from >= to) return 0; @@ -201,30 +201,30 @@ public: } void Destroy(TBuilderImpl* builder) override { - // Delete all nodes down the stream. - for (iterator it = this->begin(); it != this->end(); ++it) { - builder->DestroyNode(it->Node); - } - this->clear(); - } - + // Delete all nodes down the stream. + for (iterator it = this->begin(); it != this->end(); ++it) { + builder->DestroyNode(it->Node); + } + this->clear(); + } + ~TArcSet() override { Y_ASSERT(this->empty()); - } - + } + }; - struct TBufferedSubtree: public ISubtree { - TArrayWithSizeHolder<char> Buffer; - + struct TBufferedSubtree: public ISubtree { + TArrayWithSizeHolder<char> Buffer; + TBufferedSubtree() { Y_ASSERT(reinterpret_cast<ISubtree*>(this) == static_cast<void*>(this)); // This assumption is used in TNode::Subtree() } bool IsLast() const override { - return Buffer.Empty(); - } - + return Buffer.Empty(); + } + const TNode* Find(TStringBuf& key, TData* value, bool& result, const TPacker& packer) const override { if (Buffer.Empty()) { result = false; @@ -252,45 +252,45 @@ public: } ui64 Measure(const TBuilderImpl*) const override { - return Buffer.Size(); - } - + return Buffer.Size(); + } + ui64 Save(const TBuilderImpl*, IOutputStream& os) const override { - os.Write(Buffer.Get(), Buffer.Size()); - return Buffer.Size(); - } + os.Write(Buffer.Get(), Buffer.Size()); + return Buffer.Size(); + } ui64 SaveAndDestroy(TBuilderImpl* builder, IOutputStream& os) override { ui64 result = Save(builder, os); TArrayWithSizeHolder<char>().Swap(Buffer); return result; } - }; - - struct TSubtreeInFile: public ISubtree { - struct TData { + }; + + struct TSubtreeInFile: public ISubtree { + struct TData { TString FileName; - ui64 Size; - }; - THolder<TData> Data; - + ui64 Size; + }; + THolder<TData> Data; + TSubtreeInFile(const TString& fileName) { - // stupid API - TFile file(fileName, RdOnly); - i64 size = file.GetLength(); - if (size < 0) - ythrow yexception() << "unable to get file " << fileName.Quote() << " size for unknown reason"; - Data.Reset(new TData); - Data->FileName = fileName; - Data->Size = size; + // stupid API + TFile file(fileName, RdOnly); + i64 size = file.GetLength(); + if (size < 0) + ythrow yexception() << "unable to get file " << fileName.Quote() << " size for unknown reason"; + Data.Reset(new TData); + Data->FileName = fileName; + Data->Size = size; Y_ASSERT(reinterpret_cast<ISubtree*>(this) == static_cast<void*>(this)); // This assumption is used in TNode::Subtree() - } - + } + bool IsLast() const override { - return Data->Size == 0; - } - + return Data->Size == 0; + } + const TNode* Find(TStringBuf& key, typename TCompactTrieBuilder::TData* value, bool& result, const TPacker& packer) const override { if (!Data) { result = false; @@ -317,104 +317,104 @@ public: } ui64 Measure(const TBuilderImpl*) const override { - return Data->Size; - } - + return Data->Size; + } + ui64 Save(const TBuilderImpl*, IOutputStream& os) const override { TUnbufferedFileInput is(Data->FileName); - ui64 written = TransferData(&is, &os); - if (written != Data->Size) - ythrow yexception() << "file " << Data->FileName.Quote() << " size changed"; - return written; - } + ui64 written = TransferData(&is, &os); + if (written != Data->Size) + ythrow yexception() << "file " << Data->FileName.Quote() << " size changed"; + return written; + } ui64 SaveAndDestroy(TBuilderImpl* builder, IOutputStream& os) override { return Save(builder, os); } - }; - - union { + }; + + union { char ArcsData[CONSTEXPR_MAX3(sizeof(TArcSet), sizeof(TBufferedSubtree), sizeof(TSubtreeInFile))]; union { void* Data1; long long int Data2; } Aligner; - }; - - inline ISubtree* Subtree() { - return reinterpret_cast<ISubtree*>(ArcsData); - } - - inline const ISubtree* Subtree() const { - return reinterpret_cast<const ISubtree*>(ArcsData); - } - - EPayload PayloadType; + }; + + inline ISubtree* Subtree() { + return reinterpret_cast<ISubtree*>(ArcsData); + } + + inline const ISubtree* Subtree() const { + return reinterpret_cast<const ISubtree*>(ArcsData); + } + + EPayload PayloadType; inline const char* PayloadPtr() const { return ((const char*) this) + sizeof(TNode); } - inline char* PayloadPtr() { - return ((char*) this) + sizeof(TNode); - } - - // *Payload() + inline char* PayloadPtr() { + return ((char*) this) + sizeof(TNode); + } + + // *Payload() inline const char*& PayloadAsPtr() const { const char** payload = (const char**) PayloadPtr(); return *payload; } - inline char*& PayloadAsPtr() { - char** payload = (char**) PayloadPtr(); - return *payload; - } - + inline char*& PayloadAsPtr() { + char** payload = (char**) PayloadPtr(); + return *payload; + } + inline const char* GetPayload() const { - switch (PayloadType) { - case DATA_INSIDE: - return PayloadPtr(); - case DATA_MALLOCED: - case DATA_IN_MEMPOOL: - return PayloadAsPtr(); + switch (PayloadType) { + case DATA_INSIDE: + return PayloadPtr(); + case DATA_MALLOCED: + case DATA_IN_MEMPOOL: + return PayloadAsPtr(); case DATA_ABSENT: - default: - abort(); - } - } - + default: + abort(); + } + } + inline char* GetPayload() { const TNode* thiz = this; return const_cast<char*>(thiz->GetPayload()); // const_cast is to avoid copy-paste style } - bool IsFinal() const { - return PayloadType != DATA_ABSENT; - } - - bool IsLast() const { - return Subtree()->IsLast(); - } - - inline void* operator new(size_t, TFixedSizeAllocator& pool) { - return pool.Allocate(); - } - + bool IsFinal() const { + return PayloadType != DATA_ABSENT; + } + + bool IsLast() const { + return Subtree()->IsLast(); + } + + inline void* operator new(size_t, TFixedSizeAllocator& pool) { + return pool.Allocate(); + } + inline void operator delete(void* ptr, TFixedSizeAllocator& pool) noexcept { - pool.Release(ptr); - } - - TNode() - : PayloadType(DATA_ABSENT) - { - new (Subtree()) TArcSet; - } - - ~TNode() { - Subtree()->~ISubtree(); + pool.Release(ptr); + } + + TNode() + : PayloadType(DATA_ABSENT) + { + new (Subtree()) TArcSet; + } + + ~TNode() { + Subtree()->~ISubtree(); Y_ASSERT(PayloadType == DATA_ABSENT); - } - + } + }; // TCompactTrieBuilder @@ -433,14 +433,14 @@ bool TCompactTrieBuilder<T, D, S>::Add(const TSymbol* key, size_t keylen, const template <class T, class D, class S> bool TCompactTrieBuilder<T, D, S>::AddPtr(const TSymbol* key, size_t keylen, const char* value) { return Impl->AddEntryPtr(key, keylen, value); -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> bool TCompactTrieBuilder<T, D, S>::AddSubtreeInFile(const TSymbol* key, size_t keylen, const TString& fileName) { return Impl->AddSubtreeInFile(key, keylen, fileName); -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> bool TCompactTrieBuilder<T, D, S>::AddSubtreeInBuffer(const TSymbol* key, size_t keylen, TArrayWithSizeHolder<char>&& buffer) { return Impl->AddSubtreeInBuffer(key, keylen, std::move(buffer)); } @@ -486,19 +486,19 @@ size_t TCompactTrieBuilder<T, D, S>::GetNodeCount() const { template <class T, class D, class S> TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TCompactTrieBuilderImpl(TCompactTrieBuilderFlags flags, TPacker packer, IAllocator* alloc) : Pool(1000000, TMemoryPool::TLinearGrow::Instance(), alloc) - , PayloadSize(sizeof(void*)) // XXX: find better value + , PayloadSize(sizeof(void*)) // XXX: find better value , NodeAllocator(new TFixedSizeAllocator(sizeof(TNode) + PayloadSize, alloc)) , Flags(flags) , EntryCount(0) , NodeCount(1) - , Packer(packer) + , Packer(packer) { - Root = new (*NodeAllocator) TNode; + Root = new (*NodeAllocator) TNode; } template <class T, class D, class S> TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::~TCompactTrieBuilderImpl() { - DestroyNode(Root); + DestroyNode(Root); } template <class T, class D, class S> @@ -519,67 +519,67 @@ void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ConvertSymbolArrayTo } template <class T, class D, class S> -void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::DestroyNode(TNode* thiz) { - thiz->Subtree()->Destroy(this); - NodeReleasePayload(thiz); - thiz->~TNode(); - NodeAllocator->Release(thiz); -} - -template <class T, class D, class S> -void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeReleasePayload(TNode* thiz) { - switch (thiz->PayloadType) { - case DATA_ABSENT: - case DATA_INSIDE: - case DATA_IN_MEMPOOL: - break; - case DATA_MALLOCED: - delete[] thiz->PayloadAsPtr(); - break; - default: - abort(); - } - thiz->PayloadType = DATA_ABSENT; -} - -template <class T, class D, class S> +void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::DestroyNode(TNode* thiz) { + thiz->Subtree()->Destroy(this); + NodeReleasePayload(thiz); + thiz->~TNode(); + NodeAllocator->Release(thiz); +} + +template <class T, class D, class S> +void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeReleasePayload(TNode* thiz) { + switch (thiz->PayloadType) { + case DATA_ABSENT: + case DATA_INSIDE: + case DATA_IN_MEMPOOL: + break; + case DATA_MALLOCED: + delete[] thiz->PayloadAsPtr(); + break; + default: + abort(); + } + thiz->PayloadType = DATA_ABSENT; +} + +template <class T, class D, class S> bool TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::AddEntry( const TSymbol* key, size_t keylen, const TData& value) { - size_t datalen = Packer.MeasureLeaf(value); - + size_t datalen = Packer.MeasureLeaf(value); + bool isNewAddition = false; char* place = AddEntryForData(key, keylen, datalen, isNewAddition); - Packer.PackLeaf(place, value, datalen); + Packer.PackLeaf(place, value, datalen); return isNewAddition; -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> bool TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::AddEntryPtr( const TSymbol* key, size_t keylen, const char* value) { - size_t datalen = Packer.SkipLeaf(value); - + size_t datalen = Packer.SkipLeaf(value); + bool isNewAddition = false; char* place = AddEntryForData(key, keylen, datalen, isNewAddition); - memcpy(place, value, datalen); + memcpy(place, value, datalen); return isNewAddition; -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> bool TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::AddSubtreeInFile( const TSymbol* key, size_t keylen, const TString& fileName) { - typedef typename TNode::ISubtree ISubtree; - typedef typename TNode::TSubtreeInFile TSubtreeInFile; - + typedef typename TNode::ISubtree ISubtree; + typedef typename TNode::TSubtreeInFile TSubtreeInFile; + bool isNewAddition = false; TNode* node = AddEntryForSomething(key, keylen, isNewAddition); - node->Subtree()->Destroy(this); - node->Subtree()->~ISubtree(); - - new (node->Subtree()) TSubtreeInFile(fileName); + node->Subtree()->Destroy(this); + node->Subtree()->~ISubtree(); + + new (node->Subtree()) TSubtreeInFile(fileName); return isNewAddition; -} - -template <class T, class D, class S> +} + +template <class T, class D, class S> bool TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::AddSubtreeInBuffer( const TSymbol* key, size_t keylen, TArrayWithSizeHolder<char>&& buffer) { @@ -613,10 +613,10 @@ typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode* // Special case of empty key: replace it by 1-byte "\0" key. size_t ckeylen = keylen ? keylen * sizeof(TSymbol) : 1; TTempBuf ckeybuf(ckeylen); - if (keylen == 0) { + if (keylen == 0) { ckeybuf.Append("\0", 1); - } else { - ConvertSymbolArrayToChar(key, keylen, ckeybuf, ckeylen); + } else { + ConvertSymbolArrayToChar(key, keylen, ckeybuf, ckeylen); } char* ckey = ckeybuf.Data(); @@ -638,24 +638,24 @@ typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode* isNewAddition = (current->PayloadType == DATA_ABSENT); if ((Flags & CTBF_UNIQUE) && !isNewAddition) ythrow yexception() << "Duplicate key"; - return current; -} + return current; +} -template <class T, class D, class S> +template <class T, class D, class S> char* TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::AddEntryForData(const TSymbol* key, size_t keylen, size_t datalen, bool& isNewAddition) { TNode* current = AddEntryForSomething(key, keylen, isNewAddition); - NodeReleasePayload(current); - if (datalen <= PayloadSize) { - current->PayloadType = DATA_INSIDE; + NodeReleasePayload(current); + if (datalen <= PayloadSize) { + current->PayloadType = DATA_INSIDE; } else if (Flags & CTBF_PREFIX_GROUPED) { - current->PayloadType = DATA_MALLOCED; - current->PayloadAsPtr() = new char[datalen]; - } else { - current->PayloadType = DATA_IN_MEMPOOL; - current->PayloadAsPtr() = (char*) Pool.Allocate(datalen); // XXX: allocate unaligned - } - return current->GetPayload(); + current->PayloadType = DATA_MALLOCED; + current->PayloadAsPtr() = new char[datalen]; + } else { + current->PayloadType = DATA_IN_MEMPOOL; + current->PayloadAsPtr() = (char*) Pool.Allocate(datalen); // XXX: allocate unaligned + } + return current->GetPayload(); } template <class T, class D, class S> @@ -741,19 +741,19 @@ bool TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::FindLongestPrefixImp template <class T, class D, class S> void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::Clear() { - DestroyNode(Root); + DestroyNode(Root); Pool.Clear(); - NodeAllocator.Reset(new TFixedSizeAllocator(sizeof(TNode) + PayloadSize, TDefaultAllocator::Instance())); - Root = new (*NodeAllocator) TNode; + NodeAllocator.Reset(new TFixedSizeAllocator(sizeof(TNode) + PayloadSize, TDefaultAllocator::Instance())); + Root = new (*NodeAllocator) TNode; EntryCount = 0; NodeCount = 1; } template <class T, class D, class S> size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::Save(IOutputStream& os) const { - const size_t len = NodeMeasureSubtree(Root); - if (len != NodeSaveSubtree(Root, os)) - ythrow yexception() << "something wrong"; + const size_t len = NodeMeasureSubtree(Root); + if (len != NodeSaveSubtree(Root, os)) + ythrow yexception() << "something wrong"; return len; } @@ -781,13 +781,13 @@ template <class T, class D, class S> typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode* TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeForwardAdd( TNode* thiz, const char* label, size_t len, size_t& passed, size_t* nodeCount) { - typename TNode::TArcSet* arcSet = dynamic_cast<typename TNode::TArcSet*>(thiz->Subtree()); + typename TNode::TArcSet* arcSet = dynamic_cast<typename TNode::TArcSet*>(thiz->Subtree()); if (!arcSet) ythrow yexception() << "Bad input order - expected input strings to be prefix-grouped."; - typename TNode::TArcSet::iterator it = arcSet->Find(*label); + typename TNode::TArcSet::iterator it = arcSet->Find(*label); - if (it != arcSet->end()) { + if (it != arcSet->end()) { const char* arcLabel = it->Label.AsCharPtr(); size_t arcLabelLen = it->Label.Length(); @@ -797,8 +797,8 @@ typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode* if (passed < arcLabelLen) { (*nodeCount)++; - TNode* node = new (*NodeAllocator) TNode(); - NodeLinkTo(node, it->Label.SubBlob(passed, arcLabelLen), it->Node); + TNode* node = new (*NodeAllocator) TNode(); + NodeLinkTo(node, it->Label.SubBlob(passed, arcLabelLen), it->Node); it->Node = node; it->Label = it->Label.SubBlob(passed); @@ -811,26 +811,26 @@ typename TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TNode* } template <class T, class D, class S> -void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeLinkTo(TNode* thiz, const TBlob& label, TNode* node) { - typename TNode::TArcSet* arcSet = dynamic_cast<typename TNode::TArcSet*>(thiz->Subtree()); - if (!arcSet) +void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeLinkTo(TNode* thiz, const TBlob& label, TNode* node) { + typename TNode::TArcSet* arcSet = dynamic_cast<typename TNode::TArcSet*>(thiz->Subtree()); + if (!arcSet) ythrow yexception() << "Bad input order - expected input strings to be prefix-grouped."; // Buffer the node at the last arc if ((Flags & CTBF_PREFIX_GROUPED) && !arcSet->empty()) - NodeBufferSubtree(arcSet->back().Node); + NodeBufferSubtree(arcSet->back().Node); - arcSet->Add(label, node); + arcSet->Add(label, node); } template <class T, class D, class S> -size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeMeasureSubtree(TNode* thiz) const { +size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeMeasureSubtree(TNode* thiz) const { return (size_t)thiz->Subtree()->Measure(this); } template <class T, class D, class S> ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeSaveSubtree(TNode* thiz, IOutputStream& os) const { - return thiz->Subtree()->Save(this, os); + return thiz->Subtree()->Save(this, os); } template <class T, class D, class S> @@ -839,52 +839,52 @@ ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeSaveSubtreeAndDe } template <class T, class D, class S> -void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeBufferSubtree(TNode* thiz) { - typedef typename TNode::TArcSet TArcSet; - - TArcSet* arcSet = dynamic_cast<TArcSet*>(thiz->Subtree()); - if (!arcSet) +void TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeBufferSubtree(TNode* thiz) { + typedef typename TNode::TArcSet TArcSet; + + TArcSet* arcSet = dynamic_cast<TArcSet*>(thiz->Subtree()); + if (!arcSet) return; size_t bufferLength = (size_t)arcSet->Measure(this); - TArrayWithSizeHolder<char> buffer; - buffer.Resize(bufferLength); + TArrayWithSizeHolder<char> buffer; + buffer.Resize(bufferLength); + + TMemoryOutput bufout(buffer.Get(), buffer.Size()); - TMemoryOutput bufout(buffer.Get(), buffer.Size()); - - ui64 written = arcSet->Save(this, bufout); + ui64 written = arcSet->Save(this, bufout); Y_ASSERT(written == bufferLength); - - arcSet->Destroy(this); - arcSet->~TArcSet(); - typename TNode::TBufferedSubtree* bufferedArcSet = new (thiz->Subtree()) typename TNode::TBufferedSubtree; - - bufferedArcSet->Buffer.Swap(buffer); + arcSet->Destroy(this); + arcSet->~TArcSet(); + + typename TNode::TBufferedSubtree* bufferedArcSet = new (thiz->Subtree()) typename TNode::TBufferedSubtree; + + bufferedArcSet->Buffer.Swap(buffer); } template <class T, class D, class S> -size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeMeasureLeafValue(TNode* thiz) const { - if (!thiz->IsFinal()) +size_t TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeMeasureLeafValue(TNode* thiz) const { + if (!thiz->IsFinal()) return 0; - return Packer.SkipLeaf(thiz->GetPayload()); + return Packer.SkipLeaf(thiz->GetPayload()); } template <class T, class D, class S> ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::NodeSaveLeafValue(TNode* thiz, IOutputStream& os) const { - if (!thiz->IsFinal()) - return 0; + if (!thiz->IsFinal()) + return 0; - size_t len = Packer.SkipLeaf(thiz->GetPayload()); - os.Write(thiz->GetPayload(), len); - return len; + size_t len = Packer.SkipLeaf(thiz->GetPayload()); + os.Write(thiz->GetPayload(), len); + return len; } // TCompactTrieBuilder::TCompactTrieBuilderImpl::TNode::TArc template <class T, class D, class S> -TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TArc::TArc(const TBlob& lbl, TNode* nd) +TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::TArc::TArc(const TBlob& lbl, TNode* nd) : Label(lbl) , Node(nd) , LeftOffset(0) @@ -896,11 +896,11 @@ ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ArcMeasure( const TArc* thiz, size_t leftsize, size_t rightsize) const { using namespace NCompactTrie; - size_t coresize = 2 + NodeMeasureLeafValue(thiz->Node); // 2 == (char + flags) - size_t treesize = NodeMeasureSubtree(thiz->Node); + size_t coresize = 2 + NodeMeasureLeafValue(thiz->Node); // 2 == (char + flags) + size_t treesize = NodeMeasureSubtree(thiz->Node); - if (thiz->Label.Length() > 0) - treesize += 2 * (thiz->Label.Length() - 1); + if (thiz->Label.Length() > 0) + treesize += 2 * (thiz->Label.Length() - 1); // Triple measurements are needed because the space needed to store the offset // shall be added to the offset itself. Hence three iterations. @@ -912,8 +912,8 @@ ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ArcMeasure( rightoffsetsize = rightsize ? MeasureOffset(coresize + treesize + leftsize + leftoffsetsize + rightoffsetsize) : 0; coresize += leftoffsetsize + rightoffsetsize; - thiz->LeftOffset = leftsize ? coresize + treesize : 0; - thiz->RightOffset = rightsize ? coresize + treesize + leftsize : 0; + thiz->LeftOffset = leftsize ? coresize + treesize : 0; + thiz->RightOffset = rightsize ? coresize + treesize + leftsize : 0; return coresize + treesize + leftsize + rightsize; } @@ -922,12 +922,12 @@ template <class T, class D, class S> ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ArcSaveSelf(const TArc* thiz, IOutputStream& os) const { using namespace NCompactTrie; - ui64 written = 0; - - size_t leftoffsetsize = MeasureOffset(thiz->LeftOffset); - size_t rightoffsetsize = MeasureOffset(thiz->RightOffset); + ui64 written = 0; - size_t labelLen = thiz->Label.Length(); + size_t leftoffsetsize = MeasureOffset(thiz->LeftOffset); + size_t rightoffsetsize = MeasureOffset(thiz->RightOffset); + + size_t labelLen = thiz->Label.Length(); for (size_t i = 0; i < labelLen; ++i) { char flags = 0; @@ -938,34 +938,34 @@ ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ArcSaveSelf(const TA } if (i == labelLen-1) { - if (thiz->Node->IsFinal()) + if (thiz->Node->IsFinal()) flags |= MT_FINAL; - if (!thiz->Node->IsLast()) + if (!thiz->Node->IsLast()) flags |= MT_NEXT; } else { flags |= MT_NEXT; } os.Write(&flags, 1); - os.Write(&thiz->Label.AsCharPtr()[i], 1); - written += 2; + os.Write(&thiz->Label.AsCharPtr()[i], 1); + written += 2; if (i == 0) { - written += ArcSaveOffset(thiz->LeftOffset, os); - written += ArcSaveOffset(thiz->RightOffset, os); + written += ArcSaveOffset(thiz->LeftOffset, os); + written += ArcSaveOffset(thiz->RightOffset, os); } } - written += NodeSaveLeafValue(thiz->Node, os); + written += NodeSaveLeafValue(thiz->Node, os); return written; } template <class T, class D, class S> ui64 TCompactTrieBuilder<T, D, S>::TCompactTrieBuilderImpl::ArcSave(const TArc* thiz, IOutputStream& os) const { ui64 written = ArcSaveSelf(thiz, os); - written += NodeSaveSubtree(thiz->Node, os); - return written; + written += NodeSaveSubtree(thiz->Node, os); + return written; } template <class T, class D, class S> diff --git a/library/cpp/containers/comptrie/comptrie_impl.cpp b/library/cpp/containers/comptrie/comptrie_impl.cpp index 309176e0ec..a116ab6d1e 100644 --- a/library/cpp/containers/comptrie/comptrie_impl.cpp +++ b/library/cpp/containers/comptrie/comptrie_impl.cpp @@ -1,6 +1,6 @@ #include "comptrie_impl.h" -#include <util/system/rusage.h> +#include <util/system/rusage.h> #include <util/stream/output.h> // Unpack the leaf value. The algorithm can store up to 8 full bytes in leafs. diff --git a/library/cpp/containers/comptrie/comptrie_impl.h b/library/cpp/containers/comptrie/comptrie_impl.h index 2cbae822bf..f41c38311a 100644 --- a/library/cpp/containers/comptrie/comptrie_impl.h +++ b/library/cpp/containers/comptrie/comptrie_impl.h @@ -1,6 +1,6 @@ #pragma once -#include <util/stream/output.h> +#include <util/stream/output.h> #ifndef COMPTRIE_DATA_CHECK #define COMPTRIE_DATA_CHECK 1 @@ -11,10 +11,10 @@ namespace NCompactTrie { const char MT_FINAL = '\x80'; const char MT_NEXT = '\x40'; - const char MT_SIZEMASK = '\x07'; + const char MT_SIZEMASK = '\x07'; const size_t MT_LEFTSHIFT = 3; - const size_t MT_RIGHTSHIFT = 0; - + const size_t MT_RIGHTSHIFT = 0; + Y_FORCE_INLINE size_t UnpackOffset(const char* p, size_t len); size_t MeasureOffset(size_t offset); size_t PackOffset(char* buffer, size_t offset); @@ -52,20 +52,20 @@ namespace NCompactTrie { void ShowProgress(size_t n); // just print dots } -namespace NCompTriePrivate { - template <typename TChar> - struct TStringForChar { - }; - - template <> - struct TStringForChar<char> { +namespace NCompTriePrivate { + template <typename TChar> + struct TStringForChar { + }; + + template <> + struct TStringForChar<char> { typedef TString TResult; - }; - - template <> - struct TStringForChar<wchar16> { + }; + + template <> + struct TStringForChar<wchar16> { typedef TUtf16String TResult; - }; + }; template <> struct TStringForChar<wchar32> { @@ -73,7 +73,7 @@ namespace NCompTriePrivate { }; } - + namespace NCompTriePrivate { struct TCmp { template <class T> @@ -88,18 +88,18 @@ namespace NCompTriePrivate { }; } -namespace NCompactTrie { +namespace NCompactTrie { static inline ui64 ArcSaveOffset(size_t offset, IOutputStream& os) { - using namespace NCompactTrie; - - if (!offset) - return 0; - - char buf[16]; - size_t len = PackOffset(buf, offset); - os.Write(buf, len); - return len; - } + using namespace NCompactTrie; + + if (!offset) + return 0; + + char buf[16]; + size_t len = PackOffset(buf, offset); + os.Write(buf, len); + return len; + } // Unpack the offset to the next node. The encoding scheme can store offsets // up to 7 bytes; whether they fit into size_t is another issue. @@ -218,4 +218,4 @@ namespace NCompactTrie { return false; } -} +} diff --git a/library/cpp/containers/comptrie/comptrie_trie.h b/library/cpp/containers/comptrie/comptrie_trie.h index 534f7d424f..40ec1e52b3 100644 --- a/library/cpp/containers/comptrie/comptrie_trie.h +++ b/library/cpp/containers/comptrie/comptrie_trie.h @@ -14,9 +14,9 @@ #include <util/stream/input.h> #include <utility> -template <class T, class D, class S> -class TCompactTrieBuilder; - +template <class T, class D, class S> +class TCompactTrieBuilder; + namespace NCompactTrie { template <class TTrie> class TFirstSymbolIterator; @@ -38,17 +38,17 @@ public: typedef typename TCompactTrieKeySelector<TSymbol>::TKey TKey; typedef typename TCompactTrieKeySelector<TSymbol>::TKeyBuf TKeyBuf; - + typedef std::pair<TKey, TData> TValueType; typedef std::pair<size_t, TData> TPhraseMatch; typedef TVector<TPhraseMatch> TPhraseMatchVector; - typedef TCompactTrieBuilder<T, D, S> TBuilder; - + typedef TCompactTrieBuilder<T, D, S> TBuilder; + protected: TBlob DataHolder; const char* EmptyValue = nullptr; - TPacker Packer; + TPacker Packer; NCompactTrie::TPackerLeafSkipper<TPacker> Skipper = &Packer; // This should be true for every constructor. public: @@ -74,7 +74,7 @@ public: return !IsEmpty(); } - void Init(const char* d, size_t len, TPacker packer = TPacker()); + void Init(const char* d, size_t len, TPacker packer = TPacker()); void Init(const TBlob& data, TPacker packer = TPacker()); bool IsInitialized() const; @@ -83,17 +83,17 @@ public: bool Find(const TSymbol* key, size_t keylen, TData* value = nullptr) const; bool Find(const TKeyBuf& key, TData* value = nullptr) const { return Find(key.data(), key.size(), value); - } - - TData Get(const TSymbol* key, size_t keylen) const { - TData value; - if (!Find(key, keylen, &value)) - ythrow yexception() << "key " << TKey(key, keylen).Quote() << " not found in trie"; - return value; - } + } + + TData Get(const TSymbol* key, size_t keylen) const { + TData value; + if (!Find(key, keylen, &value)) + ythrow yexception() << "key " << TKey(key, keylen).Quote() << " not found in trie"; + return value; + } TData Get(const TKeyBuf& key) const { return Get(key.data(), key.size()); - } + } TData GetDefault(const TKeyBuf& key, const TData& def) const { TData value; if (!Find(key.data(), key.size(), &value)) @@ -101,7 +101,7 @@ public: else return value; } - + const TBlob& Data() const { return DataHolder; }; @@ -121,11 +121,11 @@ public: void FindPhrases(const TSymbol* key, size_t keylen, TPhraseMatchVector& matches, TSymbol separator = TSymbol(' ')) const; void FindPhrases(const TKeyBuf& key, TPhraseMatchVector& matches, TSymbol separator = TSymbol(' ')) const { return FindPhrases(key.data(), key.size(), matches, separator); - } + } bool FindLongestPrefix(const TSymbol* key, size_t keylen, size_t* prefixLen, TData* value = nullptr, bool* hasNext = nullptr) const; bool FindLongestPrefix(const TKeyBuf& key, size_t* prefixLen, TData* value = nullptr, bool* hasNext = nullptr) const { return FindLongestPrefix(key.data(), key.size(), prefixLen, value, hasNext); - } + } // Return trie, containing all tails for the given key inline TCompactTrie<T, D, S> FindTails(const TSymbol* key, size_t keylen) const; @@ -154,7 +154,7 @@ public: bool IsEmpty() const { return !Impl; } // Almost no other method can be called. - + bool operator==(const TConstIterator& other) const; bool operator!=(const TConstIterator& other) const; TConstIterator& operator++(); @@ -163,12 +163,12 @@ public: TConstIterator operator--(int /*unused*/); TValueType operator*(); - TKey GetKey() const; + TKey GetKey() const; size_t GetKeySize() const; - TData GetValue() const; + TData GetValue() const; void GetValue(TData& data) const; - const char* GetValuePtr() const; - + const char* GetValuePtr() const; + private: TPacker Packer; TCopyPtr<TOpaqueTrieIterator> Impl; @@ -186,7 +186,7 @@ public: TConstIterator UpperBound(const TKeyBuf& key) const; void Print(IOutputStream& os); - + size_t Size() const; friend class NCompactTrie::TFirstSymbolIterator<TCompactTrie>; @@ -224,7 +224,7 @@ public: template <class T, class D, class S> TCompactTrie<T, D, S>::TCompactTrie(const TBlob& data, TPacker packer) : DataHolder(data) - , Packer(packer) + , Packer(packer) { Init(data, packer); } @@ -246,7 +246,7 @@ template <class T, class D, class S> TCompactTrie<T, D, S>::TCompactTrie(const TBlob& data, const char* emptyValue, TPacker packer) : DataHolder(data) , EmptyValue(emptyValue) - , Packer(packer) + , Packer(packer) { } @@ -296,7 +296,7 @@ void TCompactTrie<T, D, S>::Init(const TBlob& data, TPacker packer) { using namespace NCompactTrie; DataHolder = data; - Packer = packer; + Packer = packer; const char* datapos = DataHolder.AsCharPtr(); size_t len = DataHolder.Length(); @@ -454,11 +454,11 @@ typename TCompactTrie<T, D, S>::TConstIterator TCompactTrie<T, D, S>::UpperBound template <class T, class D, class S> void TCompactTrie<T, D, S>::Print(IOutputStream& os) { typedef typename ::TCompactTrieKeySelector<T>::TKeyBuf TSBuffer; - for (TConstIterator it = Begin(); it != End(); ++it) { + for (TConstIterator it = Begin(); it != End(); ++it) { os << TSBuffer((*it).first.data(), (*it).first.size()) << "\t" << (*it).second << Endl; - } -} - + } +} + template <class T, class D, class S> bool TCompactTrie<T, D, S>::FindLongestPrefix(const TSymbol* key, size_t keylen, size_t* prefixLen, TData* value, bool* hasNext) const { const char* valuepos = nullptr; @@ -654,10 +654,10 @@ typename TCompactTrie<T, D, S>::TData TCompactTrie<T, D, S>::TConstIterator::Get template <class T, class D, class S> void TCompactTrie<T, D, S>::TConstIterator::GetValue(typename TCompactTrie<T, D, S>::TData& data) const { - const char* ptr = GetValuePtr(); + const char* ptr = GetValuePtr(); if (ptr) { Packer.UnpackLeaf(ptr, data); - } else { + } else { data = typename TCompactTrie<T, D, S>::TData(); - } -} + } +} diff --git a/library/cpp/containers/comptrie/comptrie_ut.cpp b/library/cpp/containers/comptrie/comptrie_ut.cpp index 2db5143c60..74bee09b5d 100644 --- a/library/cpp/containers/comptrie/comptrie_ut.cpp +++ b/library/cpp/containers/comptrie/comptrie_ut.cpp @@ -12,8 +12,8 @@ #include <util/generic/ptr.h> #include <util/generic/ylimits.h> -#include <util/folder/dirut.h> - +#include <util/folder/dirut.h> + #include <util/random/random.h> #include <util/random/fast.h> @@ -369,31 +369,31 @@ void TCompactTrieTest::CheckData(const char* data, size_t datalen) { size_t prefixLen = 0; typename TCompactTrie<T>::TKey key = MakeWideKey<T>(i, len); - UNIT_ASSERT(trie.Find(key, &value)); + UNIT_ASSERT(trie.Find(key, &value)); UNIT_ASSERT_EQUAL(len * 2, value); - UNIT_ASSERT(trie.FindLongestPrefix(key, &prefixLen, &value)); + UNIT_ASSERT(trie.FindLongestPrefix(key, &prefixLen, &value)); UNIT_ASSERT_EQUAL(len, prefixLen); UNIT_ASSERT_EQUAL(len * 2, value); TString badkey("bb"); badkey += i; key = MakeWideKey<T>(badkey); - UNIT_ASSERT(!trie.Find(key)); + UNIT_ASSERT(!trie.Find(key)); value = 123; - UNIT_ASSERT(!trie.Find(key, &value)); + UNIT_ASSERT(!trie.Find(key, &value)); UNIT_ASSERT_EQUAL(123, value); - UNIT_ASSERT(trie.FindLongestPrefix(key, &prefixLen, &value)); + UNIT_ASSERT(trie.FindLongestPrefix(key, &prefixLen, &value)); UNIT_ASSERT_EQUAL(1, prefixLen); UNIT_ASSERT_EQUAL(2, value); badkey = i; badkey += "x"; key = MakeWideKey<T>(badkey); - UNIT_ASSERT(!trie.Find(key)); + UNIT_ASSERT(!trie.Find(key)); value = 1234; - UNIT_ASSERT(!trie.Find(key, &value)); + UNIT_ASSERT(!trie.Find(key, &value)); UNIT_ASSERT_EQUAL(1234, value); - UNIT_ASSERT(trie.FindLongestPrefix(key, &prefixLen, &value)); + UNIT_ASSERT(trie.FindLongestPrefix(key, &prefixLen, &value)); UNIT_ASSERT_EQUAL(len, prefixLen); UNIT_ASSERT_EQUAL(len * 2, value); UNIT_ASSERT(trie.FindLongestPrefix(key, &prefixLen, nullptr)); @@ -410,12 +410,12 @@ void TCompactTrieTest::CheckData(const char* data, size_t datalen) { testkey = "fbbax"; key = MakeWideKey<T>(testkey); - UNIT_ASSERT(trie.FindLongestPrefix(key, &prefixLen, &value)); + UNIT_ASSERT(trie.FindLongestPrefix(key, &prefixLen, &value)); UNIT_ASSERT_EQUAL(prefixLen, 3); UNIT_ASSERT_EQUAL(6, value); value = 12345678; - UNIT_ASSERT(!trie.Find(key, &value)); + UNIT_ASSERT(!trie.Find(key, &value)); UNIT_ASSERT_EQUAL(12345678, value); //Failed Find() should not change value } @@ -689,7 +689,7 @@ void TCompactTrieTest::TestRandom(const size_t n, const size_t maxKeySize) { TCompactTrie<char, typename T::TData, T> trieMin(buftmp.Buffer().Data(), buftmp.Buffer().Size()); TCompactTrieBuilder<char, typename T::TData, T> prefixGroupedBuilder(CTBF_PREFIX_GROUPED); - + for (typename TKeys::const_iterator i = keys.begin(), mi = keys.end(); i != mi; ++i) { UNIT_ASSERT(!prefixGroupedBuilder.Find(i->first.c_str(), i->first.size(), &dummy)); UNIT_ASSERT(trie.Find(i->first.c_str(), i->first.size(), &dummy)); @@ -698,7 +698,7 @@ void TCompactTrieTest::TestRandom(const size_t n, const size_t maxKeySize) { UNIT_ASSERT(trieMin.Find(i->first.c_str(), i->first.size(), &dummy)); UNIT_ASSERT(dummy == i->second); } - + prefixGroupedBuilder.Add(i->first.c_str(), i->first.size(), dummy); UNIT_ASSERT(prefixGroupedBuilder.Find(i->first.c_str(), i->first.size(), &dummy)); @@ -712,10 +712,10 @@ void TCompactTrieTest::TestRandom(const size_t n, const size_t maxKeySize) { } } } - + TBufferStream prefixGroupedBuffer; prefixGroupedBuilder.Save(prefixGroupedBuffer); - + UNIT_ASSERT_VALUES_EQUAL(stream.Buffer().Size(), prefixGroupedBuffer.Buffer().Size()); UNIT_ASSERT(0 == memcmp(stream.Buffer().Data(), prefixGroupedBuffer.Buffer().Data(), stream.Buffer().Size())); } @@ -776,9 +776,9 @@ void TCompactTrieTest::TestFindTailsImpl(const TString& prefix) { } void TCompactTrieTest::TestPrefixGrouped() { - TBuffer b1b; + TBuffer b1b; TCompactTrieBuilder<char, ui32> b1(CTBF_PREFIX_GROUPED); - const char* data[] = { + const char* data[] = { "Kazan", "Moscow", "Monino", @@ -787,8 +787,8 @@ void TCompactTrieTest::TestPrefixGrouped() { "Fryazino", "Fryazevo", "Tumen", - }; - + }; + for (size_t i = 0; i < Y_ARRAY_SIZE(data); ++i) { ui32 val = strlen(data[i]) + 1; b1.Add(data[i], strlen(data[i]), val); @@ -802,24 +802,24 @@ void TCompactTrieTest::TestPrefixGrouped() { UNIT_ASSERT(!b1.Find(data[j], strlen(data[j]), &found)); } } - } - - { - TBufferOutput b1bo(b1b); - b1.Save(b1bo); - } - - TCompactTrie<char, ui32> t1(TBlob::FromBuffer(b1b)); - - //t1.Print(Cerr); - + } + + { + TBufferOutput b1bo(b1b); + b1.Save(b1bo); + } + + TCompactTrie<char, ui32> t1(TBlob::FromBuffer(b1b)); + + //t1.Print(Cerr); + for (auto& i : data) { - ui32 v; + ui32 v; UNIT_ASSERT(t1.Find(i, strlen(i), &v)); UNIT_ASSERT_VALUES_EQUAL(strlen(i) + 1, v); - } -} - + } +} + void TCompactTrieTest::CrashTestPrefixGrouped() { TCompactTrieBuilder<char, ui32> builder(CTBF_PREFIX_GROUPED); const char* data[] = { @@ -842,33 +842,33 @@ void TCompactTrieTest::CrashTestPrefixGrouped() { } void TCompactTrieTest::TestMergeFromFile() { - { - TCompactTrieBuilder<> b; - b.Add("yandex", 12); - b.Add("google", 13); - b.Add("mail", 14); + { + TCompactTrieBuilder<> b; + b.Add("yandex", 12); + b.Add("google", 13); + b.Add("mail", 14); TUnbufferedFileOutput out(GetSystemTempDir() + "/TCompactTrieTest-TestMerge-ru"); - b.Save(out); - } - - { - TCompactTrieBuilder<> b; - b.Add("yandex", 112); - b.Add("google", 113); - b.Add("yahoo", 114); + b.Save(out); + } + + { + TCompactTrieBuilder<> b; + b.Add("yandex", 112); + b.Add("google", 113); + b.Add("yahoo", 114); TUnbufferedFileOutput out(GetSystemTempDir() + "/TCompactTrieTest-TestMerge-com"); - b.Save(out); - } - - { - TCompactTrieBuilder<> b; + b.Save(out); + } + + { + TCompactTrieBuilder<> b; UNIT_ASSERT(b.AddSubtreeInFile("com.", GetSystemTempDir() + "/TCompactTrieTest-TestMerge-com")); UNIT_ASSERT(b.Add("org.kernel", 22)); UNIT_ASSERT(b.AddSubtreeInFile("ru.", GetSystemTempDir() + "/TCompactTrieTest-TestMerge-ru")); TUnbufferedFileOutput out(GetSystemTempDir() + "/TCompactTrieTest-TestMerge-res"); - b.Save(out); - } - + b.Save(out); + } + TCompactTrie<> trie(TBlob::FromFileSingleThreaded(GetSystemTempDir() + "/TCompactTrieTest-TestMerge-res")); UNIT_ASSERT_VALUES_EQUAL(12u, trie.Get("ru.yandex")); UNIT_ASSERT_VALUES_EQUAL(13u, trie.Get("ru.google")); @@ -877,12 +877,12 @@ void TCompactTrieTest::TestMergeFromFile() { UNIT_ASSERT_VALUES_EQUAL(112u, trie.Get("com.yandex")); UNIT_ASSERT_VALUES_EQUAL(113u, trie.Get("com.google")); UNIT_ASSERT_VALUES_EQUAL(114u, trie.Get("com.yahoo")); - + unlink((GetSystemTempDir() + "/TCompactTrieTest-TestMerge-res").data()); unlink((GetSystemTempDir() + "/TCompactTrieTest-TestMerge-com").data()); unlink((GetSystemTempDir() + "/TCompactTrieTest-TestMerge-ru").data()); -} - +} + void TCompactTrieTest::TestMergeFromBuffer() { TArrayWithSizeHolder<char> buffer1; { diff --git a/library/cpp/containers/comptrie/make_fast_layout.h b/library/cpp/containers/comptrie/make_fast_layout.h index 7325c284c6..b8fab5d65b 100644 --- a/library/cpp/containers/comptrie/make_fast_layout.h +++ b/library/cpp/containers/comptrie/make_fast_layout.h @@ -4,7 +4,7 @@ #include <cstddef> class IOutputStream; - + namespace NCompactTrie { // Return value: size of the resulting trie. size_t RawCompactTrieFastLayoutImpl(IOutputStream& os, const NCompactTrie::TOpaqueTrie& trie, bool verbose); diff --git a/library/cpp/containers/comptrie/minimize.h b/library/cpp/containers/comptrie/minimize.h index 354c50334e..baaa431d04 100644 --- a/library/cpp/containers/comptrie/minimize.h +++ b/library/cpp/containers/comptrie/minimize.h @@ -4,10 +4,10 @@ #include <cstddef> class IOutputStream; - + namespace NCompactTrie { size_t MeasureOffset(size_t offset); - + enum EMinimizeMode { MM_DEFAULT, // alollocate new memory for minimized tree MM_NOALLOC, // minimize tree in the same buffer diff --git a/library/cpp/containers/comptrie/opaque_trie_iterator.cpp b/library/cpp/containers/comptrie/opaque_trie_iterator.cpp index 3b2ac3d157..5fd3914be6 100644 --- a/library/cpp/containers/comptrie/opaque_trie_iterator.cpp +++ b/library/cpp/containers/comptrie/opaque_trie_iterator.cpp @@ -13,7 +13,7 @@ namespace NCompactTrie { if (!AtEmptyValue && !atend) Forward(); } - + bool TOpaqueTrieIterator::operator==(const TOpaqueTrieIterator& rhs) const { return (Trie == rhs.Trie && Forks == rhs.Forks && @@ -52,7 +52,7 @@ namespace NCompactTrie { return false; topFork = &Forks.Top(); } - } + } Y_ASSERT(!Forks.Empty()); while (Forks.Top().CurrentDirection != D_FINAL && !HasMaxKeyLength()) { @@ -228,4 +228,4 @@ namespace NCompactTrie { return Node.GetLeafOffset(); } -} +} diff --git a/library/cpp/containers/comptrie/opaque_trie_iterator.h b/library/cpp/containers/comptrie/opaque_trie_iterator.h index e2ed30a3cd..195da3c191 100644 --- a/library/cpp/containers/comptrie/opaque_trie_iterator.h +++ b/library/cpp/containers/comptrie/opaque_trie_iterator.h @@ -10,7 +10,7 @@ namespace NCompactTrie { class ILeafSkipper; - + class TFork { // Auxiliary class for a branching point in the iterator public: TNode Node; diff --git a/library/cpp/containers/comptrie/ya.make b/library/cpp/containers/comptrie/ya.make index fee6680aba..81352da4b2 100644 --- a/library/cpp/containers/comptrie/ya.make +++ b/library/cpp/containers/comptrie/ya.make @@ -1,8 +1,8 @@ LIBRARY() - + OWNER(velavokr) -SRCS( +SRCS( array_with_size.h chunked_helpers_trie.h comptrie.h @@ -23,8 +23,8 @@ SRCS( search_iterator.cpp write_trie_backwards.cpp writeable_node.cpp -) - +) + PEERDIR( library/cpp/packers library/cpp/containers/compact_vector @@ -32,4 +32,4 @@ PEERDIR( util/draft ) -END() +END() diff --git a/library/cpp/coroutine/engine/impl.cpp b/library/cpp/coroutine/engine/impl.cpp index 95e598701c..7ae6f74051 100644 --- a/library/cpp/coroutine/engine/impl.cpp +++ b/library/cpp/coroutine/engine/impl.cpp @@ -7,7 +7,7 @@ #include <util/thread/singleton.h> #include <util/stream/format.h> #include <util/stream/output.h> -#include <util/system/yassert.h> +#include <util/system/yassert.h> TCont::TJoinWait::TJoinWait(TCont& c) noexcept diff --git a/library/cpp/coroutine/engine/impl.h b/library/cpp/coroutine/engine/impl.h index d81e81fdf2..283a96ecf1 100644 --- a/library/cpp/coroutine/engine/impl.h +++ b/library/cpp/coroutine/engine/impl.h @@ -143,8 +143,8 @@ public: virtual void Execute() = 0; }; -/// Central coroutine class. -/// Note, coroutines are single-threaded, and all methods must be called from the single thread +/// Central coroutine class. +/// Note, coroutines are single-threaded, and all methods must be called from the single thread class TContExecutor { friend class TCont; using TContList = TIntrusiveList<TCont>; diff --git a/library/cpp/coroutine/engine/trampoline.cpp b/library/cpp/coroutine/engine/trampoline.cpp index a73513ded8..10ea69ddc3 100644 --- a/library/cpp/coroutine/engine/trampoline.cpp +++ b/library/cpp/coroutine/engine/trampoline.cpp @@ -6,7 +6,7 @@ #include <util/system/info.h> #include <util/system/protect.h> #include <util/system/valgrind.h> -#include <util/system/yassert.h> +#include <util/system/yassert.h> #include <cstdlib> #include <util/stream/format.h> diff --git a/library/cpp/coroutine/listener/listen.h b/library/cpp/coroutine/listener/listen.h index 5b39d75c2c..3a89cd3ecc 100644 --- a/library/cpp/coroutine/listener/listen.h +++ b/library/cpp/coroutine/listener/listen.h @@ -74,7 +74,7 @@ public: const NAddr::IRemoteAddr* Remote; const NAddr::IRemoteAddr* Local; }; - + virtual void OnAccept(const TAccept&) { } diff --git a/library/cpp/deprecated/enum_codegen/enum_codegen.h b/library/cpp/deprecated/enum_codegen/enum_codegen.h index 49f723354d..dfb04ecac2 100644 --- a/library/cpp/deprecated/enum_codegen/enum_codegen.h +++ b/library/cpp/deprecated/enum_codegen/enum_codegen.h @@ -1,10 +1,10 @@ -#pragma once - -/// see enum_codegen_ut.cpp for examples - -#define ENUM_VALUE_GEN(name, value, ...) name = value, -#define ENUM_VALUE_GEN_NO_VALUE(name, ...) name, - +#pragma once + +/// see enum_codegen_ut.cpp for examples + +#define ENUM_VALUE_GEN(name, value, ...) name = value, +#define ENUM_VALUE_GEN_NO_VALUE(name, ...) name, + #define ENUM_TO_STRING_IMPL_ITEM(name, ...) \ case name: \ return #name; @@ -12,7 +12,7 @@ case name: \ os << #name; \ break; - + #define ENUM_TO_STRING(type, MAP) \ static inline const char* ToCString(type value) { \ switch (value) { \ diff --git a/library/cpp/deprecated/enum_codegen/enum_codegen_ut.cpp b/library/cpp/deprecated/enum_codegen/enum_codegen_ut.cpp index 5a25265f2e..f8f1c9b6df 100644 --- a/library/cpp/deprecated/enum_codegen/enum_codegen_ut.cpp +++ b/library/cpp/deprecated/enum_codegen/enum_codegen_ut.cpp @@ -1,40 +1,40 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "enum_codegen.h" - + +#include "enum_codegen.h" + #include <util/string/builder.h> -#define COLOR_MAP(XX) \ +#define COLOR_MAP(XX) \ XX(RED) \ XX(GREEN) \ - XX(BLUE) - -enum EColor { - COLOR_MAP(ENUM_VALUE_GEN_NO_VALUE) -}; - -ENUM_TO_STRING(EColor, COLOR_MAP) - -#define MULTIPLIER_MAP(XX) \ + XX(BLUE) + +enum EColor { + COLOR_MAP(ENUM_VALUE_GEN_NO_VALUE) +}; + +ENUM_TO_STRING(EColor, COLOR_MAP) + +#define MULTIPLIER_MAP(XX) \ XX(GB, 9) \ XX(MB, 6) \ - XX(KB, 3) - -enum EMultiplier { - MULTIPLIER_MAP(ENUM_VALUE_GEN) -}; - -ENUM_TO_STRING(EMultiplier, MULTIPLIER_MAP) - + XX(KB, 3) + +enum EMultiplier { + MULTIPLIER_MAP(ENUM_VALUE_GEN) +}; + +ENUM_TO_STRING(EMultiplier, MULTIPLIER_MAP) + Y_UNIT_TEST_SUITE(EnumCodegen) { Y_UNIT_TEST(GenWithValue) { - UNIT_ASSERT_VALUES_EQUAL(6, MB); - } - + UNIT_ASSERT_VALUES_EQUAL(6, MB); + } + Y_UNIT_TEST(ToCString) { - UNIT_ASSERT_VALUES_EQUAL("RED", ToCString(RED)); - UNIT_ASSERT_VALUES_EQUAL("BLUE", ToCString(BLUE)); + UNIT_ASSERT_VALUES_EQUAL("RED", ToCString(RED)); + UNIT_ASSERT_VALUES_EQUAL("BLUE", ToCString(BLUE)); UNIT_ASSERT_VALUES_EQUAL("GREEN", (TStringBuilder() << GREEN)); UNIT_ASSERT_VALUES_EQUAL("GB", ToCString(GB)); - } -} + } +} diff --git a/library/cpp/deprecated/mapped_file/mapped_file.cpp b/library/cpp/deprecated/mapped_file/mapped_file.cpp index 905b90eaa1..b0e4511299 100644 --- a/library/cpp/deprecated/mapped_file/mapped_file.cpp +++ b/library/cpp/deprecated/mapped_file/mapped_file.cpp @@ -1,5 +1,5 @@ #include "mapped_file.h" - + #include <util/generic/yexception.h> #include <util/system/defaults.h> #include <util/system/hi_lo.h> diff --git a/library/cpp/digest/md5/md5_medium_ut.cpp b/library/cpp/digest/md5/md5_medium_ut.cpp index 34131aeb48..a940c5cb66 100644 --- a/library/cpp/digest/md5/md5_medium_ut.cpp +++ b/library/cpp/digest/md5/md5_medium_ut.cpp @@ -1,7 +1,7 @@ #include "md5.h" #include <library/cpp/testing/unittest/registar.h> - + Y_UNIT_TEST_SUITE(TMD5MediumTest) { Y_UNIT_TEST(TestOverflow) { if (sizeof(size_t) > sizeof(unsigned int)) { diff --git a/library/cpp/digest/md5/md5_ut.cpp b/library/cpp/digest/md5/md5_ut.cpp index d2a67eb97d..1c3e4ad0a9 100644 --- a/library/cpp/digest/md5/md5_ut.cpp +++ b/library/cpp/digest/md5/md5_ut.cpp @@ -1,7 +1,7 @@ #include "md5.h" #include <library/cpp/testing/unittest/registar.h> - + #include <util/system/fs.h> #include <util/stream/file.h> @@ -40,7 +40,7 @@ Y_UNIT_TEST_SUITE(TMD5Test) { TString memoryHash = MD5::Data((const unsigned char*)s.data(), s.size(), memBuf); UNIT_ASSERT_NO_DIFF(fileHash, memoryHash); - + fileHash = MD5::File(tmpFile); UNIT_ASSERT_NO_DIFF(fileHash, memoryHash); diff --git a/library/cpp/execprofile/profile.cpp b/library/cpp/execprofile/profile.cpp index 883054f869..d05de20203 100644 --- a/library/cpp/execprofile/profile.cpp +++ b/library/cpp/execprofile/profile.cpp @@ -1,5 +1,5 @@ -#include <util/system/defaults.h> - +#include <util/system/defaults.h> + #include "profile.h" #if defined(_unix_) && !defined(_bionic_) && !defined(_cygwin_) @@ -293,7 +293,7 @@ private: }; void TSampleAnalyser::Analyze(FILE* out) const { - fprintf(out, "samples: %" PRIu64 " unique: %" PRIu64 " dropped: %" PRIu64 " searchskips: %" PRIu64 "\n", + fprintf(out, "samples: %" PRIu64 " unique: %" PRIu64 " dropped: %" PRIu64 " searchskips: %" PRIu64 "\n", (ui64)Stats.SavedSamples, (ui64)Samples.size(), (ui64)Stats.DroppedSamples, (ui64)Stats.SearchSkipCount); @@ -306,13 +306,13 @@ void TSampleAnalyser::Analyze(FILE* out) const { // dumping the samples if (PutTimestamps && (i % 1000 == 0)) { ui64 tm = GetCycleCount(); - fprintf(out, "TM: %" PRIu64 "\n", tm); + fprintf(out, "TM: %" PRIu64 "\n", tm); } Dl_info addrInfo; if (dladdr(Samples[i].first, &addrInfo)) { if (addrInfo.dli_fbase != prevModBase || addrInfo.dli_saddr != prevFunc) { - fprintf(out, "Func\t%" PRISZT "\t%p\t%p\t%s\t%s\n", + fprintf(out, "Func\t%" PRISZT "\t%p\t%p\t%s\t%s\n", funcCnt, addrInfo.dli_fbase, addrInfo.dli_saddr, @@ -325,7 +325,7 @@ void TSampleAnalyser::Analyze(FILE* out) const { } else { fprintf(out, "[dladdr failed]\n"); } - fprintf(out, "%" PRISZT "\t%p\t%lu\n", i, Samples[i].first, Samples[i].second); + fprintf(out, "%" PRISZT "\t%p\t%lu\n", i, Samples[i].first, Samples[i].second); } } diff --git a/library/cpp/getopt/last_getopt_demo/demo.cpp b/library/cpp/getopt/last_getopt_demo/demo.cpp index cb31dba733..79426a9cc9 100644 --- a/library/cpp/getopt/last_getopt_demo/demo.cpp +++ b/library/cpp/getopt/last_getopt_demo/demo.cpp @@ -3,7 +3,7 @@ #include <library/cpp/colorizer/colors.h> // For the sake of this example, let's implement Wget - + Y_COMPLETER(HeaderCompleter) { AddCompletion("Host"); AddCompletion("Referer"); @@ -31,8 +31,8 @@ Y_COMPLETER(HeaderCompleter) { AddCompletion("Content-MD5"); AddCompletion("Content-Range"); } -} - +} + class TMain: public TMainClassArgs { bool Background_; size_t Timeout_; @@ -42,7 +42,7 @@ class TMain: public TMainClassArgs { TMaybe<TString> PostData_; TMaybe<TString> PostFile_; TVector<TString> Headers_; - + protected: void RegisterOptions(NLastGetopt::TOpts& opts) override { // Brief description for the whole program, will appear in the beginning of a help message. @@ -75,7 +75,7 @@ protected: .CompletionArgHelp("timeout (ms)") .StoreResult(&Timeout_) .Completer(NLastGetopt::NComp::Choice({{"1000"}, {"5000"}, {"10000"}, {"60000"}})); - + opts.AddLongOption("method") .RequiredArgument("http-method") .Help("specify HTTP method") @@ -100,7 +100,7 @@ protected: .CompletionHelp("set custom user agent for each HTTP request") .CompletionArgHelp("user agent string") .StoreResult(&UserAgent_); - + opts.AddLongOption("post-data") .RequiredArgument("string") .Help("use POST method and send the specified data in the request body (cannot be used with --post-file)") @@ -121,10 +121,10 @@ protected: ImplicitMethod_ = "POST"; }) .Completer(NLastGetopt::NComp::File()); - + // These two options can't be together. opts.MutuallyExclusive("post-file", "post-data"); - + opts.AddLongOption("header") .RequiredArgument("header-line") .Help("send `header-line` along with the rest of the headers in each HTTP request") @@ -133,9 +133,9 @@ protected: .AppendTo(&Headers_) .AllowMultipleCompletion() .Completer(NLastGetopt::NComp::LaunchSelf(HeaderCompleter)); - + // Setting up free arguments. - + // We are going to have one mandatory argument and unlimited number of optional arguments. opts.SetFreeArgsMin(1); opts.SetFreeArgsMax(NLastGetopt::TOpts::UNLIMITED_ARGS); @@ -239,4 +239,4 @@ protected: int main(int argc, const char** argv) { NLastGetopt::NComp::TCustomCompleter::FireCustomCompleter(argc, argv); TMain().Run(argc, argv); -} +} diff --git a/library/cpp/getopt/last_getopt_demo/ya.make b/library/cpp/getopt/last_getopt_demo/ya.make index 275f983051..53f1cfc122 100644 --- a/library/cpp/getopt/last_getopt_demo/ya.make +++ b/library/cpp/getopt/last_getopt_demo/ya.make @@ -1,13 +1,13 @@ -PROGRAM(last_getopt_demo) - +PROGRAM(last_getopt_demo) + OWNER(amatanhead) PEERDIR( library/cpp/getopt ) -SRCS( - demo.cpp -) - -END() +SRCS( + demo.cpp +) + +END() diff --git a/library/cpp/getopt/small/last_getopt.cpp b/library/cpp/getopt/small/last_getopt.cpp index d76420629d..30669b2c5a 100644 --- a/library/cpp/getopt/small/last_getopt.cpp +++ b/library/cpp/getopt/small/last_getopt.cpp @@ -6,4 +6,4 @@ namespace NLastGetopt { exit(0); } -} +} diff --git a/library/cpp/getopt/small/last_getopt.h b/library/cpp/getopt/small/last_getopt.h index 4377591fa8..07687bc914 100644 --- a/library/cpp/getopt/small/last_getopt.h +++ b/library/cpp/getopt/small/last_getopt.h @@ -1,21 +1,21 @@ #pragma once - + #include "last_getopt_opts.h" #include "last_getopt_easy_setup.h" #include "last_getopt_parse_result.h" #include <util/generic/function.h> #include <util/string/split.h> - + /// see some documentation in /// https://wiki.yandex-team.ru/development/poisk/arcadia/util/lastgetopt/ /// https://wiki.yandex-team.ru/development/poisk/arcadia/library/getopt/ /// see examples in library/cpp/getopt/last_getopt_demo - + //TODO: in most cases this include is unnecessary, but needed THandlerFunctor1<TpFunc, TpArg>::HandleOpt #include "last_getopt_parser.h" -namespace NLastGetopt { +namespace NLastGetopt { /// Handler to split option value by delimiter into a target container and allow ranges. template <class Container> struct TOptRangeSplitHandler: public IOptHandler { @@ -35,21 +35,21 @@ namespace NLastGetopt { if (curval.IsInited()) { StringSplitter(curval).Split(ElementsDelim).Consume([&](const TStringBuf& val) { TStringBuf mutableValue = val; - + TValue first = NPrivate::OptFromString<TValue>(mutableValue.NextTok(RangesDelim), parser->CurOpt()); TValue last = mutableValue ? NPrivate::OptFromString<TValue>(mutableValue, parser->CurOpt()) : first; - + if (last < first) { throw TUsageException() << "failed to parse opt " << NPrivate::OptToString(parser->CurOpt()) << " value " << TString(val).Quote() << ": the second argument is less than the first one"; } - + for (++last; first < last; ++first) { Target->insert(Target->end(), first); } }); } } - + private: TContainer* Target; char ElementsDelim; @@ -126,7 +126,7 @@ namespace NLastGetopt { << " value " << TString(curval).Quote() << ": " << CurrentExceptionMessage(); } } - - } + + } } diff --git a/library/cpp/getopt/small/last_getopt_support.h b/library/cpp/getopt/small/last_getopt_support.h index 3ea05733ff..17bed3e614 100644 --- a/library/cpp/getopt/small/last_getopt_support.h +++ b/library/cpp/getopt/small/last_getopt_support.h @@ -1,36 +1,36 @@ #pragma once - + #include <util/string/cast.h> #include <util/generic/string.h> #include <util/generic/vector.h> -#include <util/generic/utility.h> +#include <util/generic/utility.h> #include <util/generic/yexception.h> - -namespace NLastGetopt { + +namespace NLastGetopt { class TOpt; class TOpts; class TOptsParser; class TOptsParseResult; - + /// base of all getopt exceptions class TException: public yexception { }; - + /// TOpts configuration is incorrect class TConfException: public TException { }; - + /// User passed incorrect arguments, parsing failed /// Note: use `throw TUsageException()` instead of `ythrow TUsageException()` to prevent appearence of stacktrace /// and location of the `ythrow` statment in error messages. class TUsageException: public TException { }; - + struct IOptHandler { virtual void HandleOpt(const TOptsParser* parser) = 0; virtual ~IOptHandler() = default; }; - + namespace NPrivate { template <typename TpFunc> class THandlerFunctor0 @@ -94,7 +94,7 @@ namespace NLastGetopt { class TStoreResultFunctor { private: T* Target_; - + public: TStoreResultFunctor(T* target) : Target_(target) @@ -128,7 +128,7 @@ namespace NLastGetopt { class TStoreValueFunctor { T* Target; const TpVal Value; - + public: template <typename TpArg> TStoreValueFunctor(T* target, const TpArg& value) @@ -155,7 +155,7 @@ namespace NLastGetopt { inline TStringBuf OptFromStringImpl<TStringBuf>(const TStringBuf& value) { return value; } - + template <> inline const char* OptFromStringImpl<const char*>(const TStringBuf& value) { return value.data(); diff --git a/library/cpp/getopt/small/opt.cpp b/library/cpp/getopt/small/opt.cpp index 2752987a55..744501765c 100644 --- a/library/cpp/getopt/small/opt.cpp +++ b/library/cpp/getopt/small/opt.cpp @@ -1,105 +1,105 @@ #include "opt.h" - + #include <util/system/progname.h> -#include <ctype.h> +#include <ctype.h> -using namespace NLastGetopt; +using namespace NLastGetopt; -namespace { +namespace { struct TOptsNoDefault: public TOpts { TOptsNoDefault(const TStringBuf& optstring = TStringBuf()) : TOpts(optstring) { } - }; - -} - -void Opt::Init(int argc, char* argv[], const char* optString, const Ion* longOptions, bool longOnly, bool isOpen) { - Ions_ = longOptions; - Err = true; - GotError_ = false; + }; + +} + +void Opt::Init(int argc, char* argv[], const char* optString, const Ion* longOptions, bool longOnly, bool isOpen) { + Ions_ = longOptions; + Err = true; + GotError_ = false; Ind = argc; - - Opts_.Reset(new TOptsNoDefault(optString)); + + Opts_.Reset(new TOptsNoDefault(optString)); for (const Ion* o = longOptions; o != nullptr && o->name != nullptr; ++o) { - TOpt* opt; + TOpt* opt; if ((unsigned)o->val < 0x80 && isalnum(o->val)) { - opt = &Opts_->CharOption(char(o->val)); + opt = &Opts_->CharOption(char(o->val)); opt->AddLongName(o->name); - } else { - Opts_->AddLongOption(o->name); - opt = const_cast<TOpt*>(&Opts_->GetLongOption(o->name)); - } - opt->HasArg_ = EHasArg(o->has_arg); + } else { + Opts_->AddLongOption(o->name); + opt = const_cast<TOpt*>(&Opts_->GetLongOption(o->name)); + } + opt->HasArg_ = EHasArg(o->has_arg); opt->UserValue(o); } - Opts_->AllowSingleDashForLong_ = longOnly; - Opts_->AllowPlusForLong_ = true; - Opts_->AllowUnknownCharOptions_ = isOpen; - Opts_->AllowUnknownLongOptions_ = false; + Opts_->AllowSingleDashForLong_ = longOnly; + Opts_->AllowPlusForLong_ = true; + Opts_->AllowUnknownCharOptions_ = isOpen; + Opts_->AllowUnknownLongOptions_ = false; + + OptsParser_.Reset(new TOptsParser(Opts_.Get(), argc, argv)); +} - OptsParser_.Reset(new TOptsParser(Opts_.Get(), argc, argv)); +Opt::Opt(int argc, char* argv[], const char* optString, const Ion* longOptions, bool longOnly, bool isOpen) { + Init(argc, argv, optString, longOptions, longOnly, isOpen); } -Opt::Opt(int argc, char* argv[], const char* optString, const Ion* longOptions, bool longOnly, bool isOpen) { - Init(argc, argv, optString, longOptions, longOnly, isOpen); -} - -Opt::Opt(int argc, const char* argv[], const char* optString, const Ion* longOptions, bool longOnly, bool isOpen) { +Opt::Opt(int argc, const char* argv[], const char* optString, const Ion* longOptions, bool longOnly, bool isOpen) { Init(argc, (char**)argv, optString, longOptions, longOnly, isOpen); -} - -int Opt::Get() { +} + +int Opt::Get() { return Get(nullptr); } -int Opt::Get(int* longOptionIndex) { - if (GotError_) - return EOF; +int Opt::Get(int* longOptionIndex) { + if (GotError_) + return EOF; Arg = nullptr; - try { - bool r = OptsParser_->Next(); + try { + bool r = OptsParser_->Next(); Ind = (int)OptsParser_->Pos_; - if (!r) { + if (!r) { return EOF; - } else { + } else { Arg = (char*)OptsParser_->CurVal(); if (!OptsParser_->CurOpt()) { - // possible if RETURN_IN_ORDER - return 1; - } else { + // possible if RETURN_IN_ORDER + return 1; + } else { const Ion* ion = (const Ion*)OptsParser_->CurOpt()->UserValue(); if (longOptionIndex) { *longOptionIndex = int(ion - Ions_); - } + } char c = OptsParser_->CurOpt()->GetCharOr0(); - return c != 0 ? c : ion->val; + return c != 0 ? c : ion->val; } } - } catch (const NLastGetopt::TException&) { - GotError_ = true; - if (Err) - Cerr << CurrentExceptionMessage() << Endl; - return '?'; + } catch (const NLastGetopt::TException&) { + GotError_ = true; + if (Err) + Cerr << CurrentExceptionMessage() << Endl; + return '?'; } } void Opt::DummyHelp(IOutputStream& os) { Opts_->PrintUsage(GetProgramName(), os); -} - -int Opt::GetArgC() const { +} + +int Opt::GetArgC() const { return (int)OptsParser_->Argc_; -} - -const char** Opt::GetArgV() const { - return OptsParser_->Argv_; -} - +} + +const char** Opt::GetArgV() const { + return OptsParser_->Argv_; +} + int opt_get_number(int& argc, char* argv[]) { int num = -1; for (int a = 1; a < argc; a++) { diff --git a/library/cpp/getopt/small/opt.h b/library/cpp/getopt/small/opt.h index 80701aa7e9..ecb57439bc 100644 --- a/library/cpp/getopt/small/opt.h +++ b/library/cpp/getopt/small/opt.h @@ -1,118 +1,118 @@ #pragma once - + #include "last_getopt.h" #include <util/generic/ptr.h> -#include <util/generic/noncopyable.h> - -// implementation of Opt class using last getopt - -/* - short-options syntax: - - opt-letter ::= - [^: ] - - opt-string ::= - '+'|'-'?({opt-letter}':'{0,2})* - - example: "AbCx:y:z::" - {A,b,C} options without argument - {x,y} options with argument - {z} option with optional argument - - 1. shortopts begins with '-' :=> RETURN_IN_ORDER - == non-option forces getopt to return 1 and to place non-option into optarg - - 2. shortopts begins with '+' :=> REQUIRE_ORDER +#include <util/generic/noncopyable.h> + +// implementation of Opt class using last getopt + +/* + short-options syntax: + + opt-letter ::= + [^: ] + + opt-string ::= + '+'|'-'?({opt-letter}':'{0,2})* + + example: "AbCx:y:z::" + {A,b,C} options without argument + {x,y} options with argument + {z} option with optional argument + + 1. shortopts begins with '-' :=> RETURN_IN_ORDER + == non-option forces getopt to return 1 and to place non-option into optarg + + 2. shortopts begins with '+' :=> REQUIRE_ORDER GetEnv(_POSIX_OPTION_ORDER) :=> REQUIRE_ORDER - == 1st non-option forces getopt to return EOF - - 3. default :=> PERMUTE - == exchange options with non-options and place all options first - - 4. '--' command line argument forces getopt to stop parsing and to return EOF - in any case - - long options should begin by '+' sign - or when (_getopt_long_only = 1) by '-' sign - - struct option { - char *name : option name - int has_arg: 0 | 1 | 2 = without | with | optional argument - int *flag : if (flag != 0) then getopt returns 0 and stores val into *flag - int val : if (flag == 0) then getopt returns val - } - - Example: - - struct option my_opts[] = { - { "delete", 0, &deletion_flag, DEL }, -- returns 0, deletion_flag := DEL - { "add", 1, NULL, 'a' }, -- returns 'a', argument in optarg - { NULL } - } -*/ - -#define OPT_RETURN_IN_ORDER "-" + == 1st non-option forces getopt to return EOF + + 3. default :=> PERMUTE + == exchange options with non-options and place all options first + + 4. '--' command line argument forces getopt to stop parsing and to return EOF + in any case + + long options should begin by '+' sign + or when (_getopt_long_only = 1) by '-' sign + + struct option { + char *name : option name + int has_arg: 0 | 1 | 2 = without | with | optional argument + int *flag : if (flag != 0) then getopt returns 0 and stores val into *flag + int val : if (flag == 0) then getopt returns val + } + + Example: + + struct option my_opts[] = { + { "delete", 0, &deletion_flag, DEL }, -- returns 0, deletion_flag := DEL + { "add", 1, NULL, 'a' }, -- returns 'a', argument in optarg + { NULL } + } +*/ + +#define OPT_RETURN_IN_ORDER "-" #define OPT_REQUIRE_ORDER "+" #define OPT_DONT_STORE_ARG ((void*)0) - + class Opt : TNonCopyable { -public: +public: enum HasArg { WithoutArg, WithArg, PossibleArg }; - - struct Ion { + + struct Ion { const char* name; HasArg has_arg; int* flag; int val; - }; - -private: - THolder<NLastGetopt::TOpts> Opts_; - THolder<NLastGetopt::TOptsParser> OptsParser_; - const Ion* Ions_; - bool GotError_; + }; + +private: + THolder<NLastGetopt::TOpts> Opts_; + THolder<NLastGetopt::TOptsParser> OptsParser_; + const Ion* Ions_; + bool GotError_; void Init(int argc, char* argv[], const char* optString, const Ion* longOptions = nullptr, bool longOnly = false, bool isOpen = false); - -public: + +public: Opt(int argc, char* argv[], const char* optString, const Ion* longOptions = nullptr, bool longOnly = false, bool isOpen = false); Opt(int argc, const char* argv[], const char* optString, const Ion* longOptions = nullptr, bool longOnly = false, bool isOpen = false); - - // Get() means next - int Get(); - int Get(int* longOptionIndex); + + // Get() means next + int Get(); + int Get(int* longOptionIndex); int operator()() { - return Get(); - } - + return Get(); + } + const char* GetArg() const { return Arg; } - + TVector<TString> GetFreeArgs() const { return NLastGetopt::TOptsParseResult(&*Opts_, GetArgC(), GetArgV()).GetFreeArgs(); } - // obsolete, use GetArg() instead + // obsolete, use GetArg() instead char* Arg; /* option argument if any or NULL */ - + int Ind; /* command line index */ bool Err; /* flag to print error messages */ - - int GetArgC() const; - const char** GetArgV() const; - + + int GetArgC() const; + const char** GetArgV() const; + void DummyHelp(IOutputStream& os = Cerr); -}; - -// call before getopt. returns non-negative int, removing it from arguments (not found: -1) -// Example: returns 11 for "progname -11abc", -1 for "progname -a11" +}; + +// call before getopt. returns non-negative int, removing it from arguments (not found: -1) +// Example: returns 11 for "progname -11abc", -1 for "progname -a11" int opt_get_number(int& argc, char* argv[]); - + #define OPTION_HANDLING_PROLOG \ { \ int optlet; \ @@ -128,12 +128,12 @@ int opt_get_number(int& argc, char* argv[]); #define OPTION_HANDLE_END \ } \ break; - + #define OPTION_HANDLE(opt, handle) \ OPTION_HANDLE_BEGIN(opt) \ handle; \ OPTION_HANDLE_END - + #define OPTION_HANDLING_EPILOG \ default: \ ythrow yexception() << "unknown optlet"; \ diff --git a/library/cpp/getopt/small/opt2.h b/library/cpp/getopt/small/opt2.h index c81cf345a4..4d9d943237 100644 --- a/library/cpp/getopt/small/opt2.h +++ b/library/cpp/getopt/small/opt2.h @@ -111,11 +111,11 @@ public: void AddError(const char* message = nullptr); public: - // non-option args + // non-option args TVector<char*> Pos; bool HasErrors; - -private: + +private: bool BadPosCount; char UnknownOption; char* UnknownLongOption; diff --git a/library/cpp/getopt/small/posix_getopt.cpp b/library/cpp/getopt/small/posix_getopt.cpp index cae224133a..bd06f3499f 100644 --- a/library/cpp/getopt/small/posix_getopt.cpp +++ b/library/cpp/getopt/small/posix_getopt.cpp @@ -2,76 +2,76 @@ #include <util/generic/ptr.h> -#include <ctype.h> - -namespace NLastGetopt { - char* optarg; - int optind; - int optopt; - int opterr; - int optreset; - - static THolder<TOpts> Opts; - static THolder<TOptsParser> OptsParser; - +#include <ctype.h> + +namespace NLastGetopt { + char* optarg; + int optind; + int optopt; + int opterr; + int optreset; + + static THolder<TOpts> Opts; + static THolder<TOptsParser> OptsParser; + int getopt_long_impl(int argc, char* const* argv, const char* optstring, const struct option* longopts, int* longindex, bool long_only) { - if (!Opts || optreset == 1) { + if (!Opts || optreset == 1) { optarg = nullptr; - optind = 1; - opterr = 1; - optreset = 0; - Opts.Reset(new TOpts(TOpts::Default(optstring))); - - Opts->AllowSingleDashForLong_ = long_only; - + optind = 1; + opterr = 1; + optreset = 0; + Opts.Reset(new TOpts(TOpts::Default(optstring))); + + Opts->AllowSingleDashForLong_ = long_only; + for (const struct option* o = longopts; o != nullptr && o->name != nullptr; ++o) { - TOpt* opt; + TOpt* opt; if ((unsigned)o->val < 0x80 && isalnum(o->val)) { - opt = &Opts->CharOption(char(o->val)); + opt = &Opts->CharOption(char(o->val)); opt->AddLongName(o->name); - } else { - Opts->AddLongOption(o->name); - opt = const_cast<TOpt*>(&Opts->GetLongOption(o->name)); - } - opt->HasArg_ = EHasArg(o->has_arg); + } else { + Opts->AddLongOption(o->name); + opt = const_cast<TOpt*>(&Opts->GetLongOption(o->name)); + } + opt->HasArg_ = EHasArg(o->has_arg); opt->UserValue(o->flag); - } - + } + OptsParser.Reset(new TOptsParser(&*Opts, argc, (const char**)argv)); - } - + } + optarg = nullptr; - - try { - if (!OptsParser->Next()) { - return -1; - } else { + + try { + if (!OptsParser->Next()) { + return -1; + } else { optarg = (char*)OptsParser->CurVal(); optind = (int)OptsParser->Pos_; if (longindex && OptsParser->CurOpt()) *longindex = (int)Opts->IndexOf(OptsParser->CurOpt()); return OptsParser->CurOpt() ? OptsParser->CurOpt()->GetCharOr0() : 1; - } - } catch (const NLastGetopt::TException&) { - return '?'; - } - } - + } + } catch (const NLastGetopt::TException&) { + return '?'; + } + } + int getopt_long(int argc, char* const* argv, const char* optstring, const struct option* longopts, int* longindex) { - return getopt_long_impl(argc, argv, optstring, longopts, longindex, false); - } - - int getopt_long_only(int argc, char* const* argv, const char* optstring, + return getopt_long_impl(argc, argv, optstring, longopts, longindex, false); + } + + int getopt_long_only(int argc, char* const* argv, const char* optstring, const struct option* longopts, int* longindex) { - return getopt_long_impl(argc, argv, optstring, longopts, longindex, true); - } - - // XXX: leading colon is not supported - // XXX: updating optind by client is not supported - int getopt(int argc, char* const* argv, const char* optstring) { + return getopt_long_impl(argc, argv, optstring, longopts, longindex, true); + } + + // XXX: leading colon is not supported + // XXX: updating optind by client is not supported + int getopt(int argc, char* const* argv, const char* optstring) { return getopt_long(argc, argv, optstring, nullptr, nullptr); - } - -} + } + +} diff --git a/library/cpp/getopt/small/posix_getopt.h b/library/cpp/getopt/small/posix_getopt.h index d26fa96641..e6af1e0284 100644 --- a/library/cpp/getopt/small/posix_getopt.h +++ b/library/cpp/getopt/small/posix_getopt.h @@ -1,32 +1,32 @@ #pragma once - -// implementation of posix getopt using last getopt for demonstration purposes - -#include "last_getopt.h" - -namespace NLastGetopt { - extern char* optarg; - extern int optind; - extern int optopt; - extern int opterr; - extern int optreset; - - enum { - no_argument = NO_ARGUMENT, - required_argument = REQUIRED_ARGUMENT, - optional_argument = OPTIONAL_ARGUMENT, - }; - - struct option { - const char* name; - int has_arg; - int* flag; - int val; - }; - - int getopt(int argc, char* const* argv, const char* optstring); + +// implementation of posix getopt using last getopt for demonstration purposes + +#include "last_getopt.h" + +namespace NLastGetopt { + extern char* optarg; + extern int optind; + extern int optopt; + extern int opterr; + extern int optreset; + + enum { + no_argument = NO_ARGUMENT, + required_argument = REQUIRED_ARGUMENT, + optional_argument = OPTIONAL_ARGUMENT, + }; + + struct option { + const char* name; + int has_arg; + int* flag; + int val; + }; + + int getopt(int argc, char* const* argv, const char* optstring); int getopt_long(int argc, char* const* argv, const char* optstring, const struct option* longopts, int* longindex); - int getopt_long_only(int argc, char* const* argv, const char* optstring, + int getopt_long_only(int argc, char* const* argv, const char* optstring, const struct option* longopts, int* longindex); -} +} diff --git a/library/cpp/getopt/ut/last_getopt_ut.cpp b/library/cpp/getopt/ut/last_getopt_ut.cpp index 7d6a29f2a5..c99a1d053d 100644 --- a/library/cpp/getopt/ut/last_getopt_ut.cpp +++ b/library/cpp/getopt/ut/last_getopt_ut.cpp @@ -2,22 +2,22 @@ #include <library/cpp/colorizer/colors.h> #include <library/cpp/testing/unittest/registar.h> - + #include <util/generic/array_size.h> #include <util/string/subst.h> #include <util/string/vector.h> #include <util/string/split.h> -using namespace NLastGetopt; - -namespace { +using namespace NLastGetopt; + +namespace { struct TOptsNoDefault: public TOpts { TOptsNoDefault(const TStringBuf& optstring = TStringBuf()) : TOpts(optstring) { } - }; - + }; + class TOptsParseResultTestWrapper: public TOptsParseResultException { TVector<const char*> Argv_; @@ -30,101 +30,101 @@ namespace { }; using V = TVector<const char*>; -} - -struct TOptsParserTester { - TOptsNoDefault Opts_; +} + +struct TOptsParserTester { + TOptsNoDefault Opts_; TVector<const char*> Argv_; - - THolder<TOptsParser> Parser_; - - void Initialize() { - if (!Parser_) + + THolder<TOptsParser> Parser_; + + void Initialize() { + if (!Parser_) Parser_.Reset(new TOptsParser(&Opts_, (int)Argv_.size(), Argv_.data())); - } - - void Accept() { - Initialize(); - UNIT_ASSERT(Parser_->Next()); - } - - void AcceptOption() { - Accept(); + } + + void Accept() { + Initialize(); + UNIT_ASSERT(Parser_->Next()); + } + + void AcceptOption() { + Accept(); UNIT_ASSERT(!!Parser_->CurOpt()); - } - - void AcceptOption(char c) { - AcceptOption(); + } + + void AcceptOption(char c) { + AcceptOption(); UNIT_ASSERT(Parser_->CurOpt()->CharIs(c)); - } - + } + void AcceptOption(const TString& optName) { - AcceptOption(); + AcceptOption(); UNIT_ASSERT(Parser_->CurOpt()->NameIs(optName)); - } - - template <typename TOpt> + } + + template <typename TOpt> void AcceptOptionWithValue(TOpt optName, const TString& value) { - AcceptOption(optName); + AcceptOption(optName); UNIT_ASSERT_VALUES_EQUAL_C(value, Parser_->CurValStr(), "; option " << optName); - } - - template <typename TOpt> - void AcceptOptionWithoutValue(TOpt optName) { - AcceptOption(optName); + } + + template <typename TOpt> + void AcceptOptionWithoutValue(TOpt optName) { + AcceptOption(optName); UNIT_ASSERT_C(!Parser_->CurVal(), ": opt " << optName << " must have no param"); - } - + } + void AcceptFreeArgInOrder(const TString& expected) { - Accept(); + Accept(); UNIT_ASSERT(!Parser_->CurOpt()); UNIT_ASSERT_VALUES_EQUAL(expected, Parser_->CurValStr()); - } - - size_t Pos_; - - void AcceptEndOfOptions() { - Initialize(); - UNIT_ASSERT(!Parser_->Next()); - Pos_ = Parser_->Pos_; - - // pos must not be changed after last meaningful invocation of Next() - UNIT_ASSERT(!Parser_->Next()); - UNIT_ASSERT_VALUES_EQUAL(Pos_, Parser_->Pos_); - UNIT_ASSERT(!Parser_->Next()); - UNIT_ASSERT_VALUES_EQUAL(Pos_, Parser_->Pos_); - } - - void AcceptError() { - Initialize(); - try { - Parser_->Next(); - UNIT_FAIL("expecting exception"); - } catch (const TUsageException&) { - // expecting - } - } - - void AcceptUnexpectedOption() { - Initialize(); - size_t pos = Parser_->Pos_; - size_t sop = Parser_->Sop_; - AcceptError(); - UNIT_ASSERT_VALUES_EQUAL(pos, Parser_->Pos_); - UNIT_ASSERT_VALUES_EQUAL(sop, Parser_->Sop_); - } - + } + + size_t Pos_; + + void AcceptEndOfOptions() { + Initialize(); + UNIT_ASSERT(!Parser_->Next()); + Pos_ = Parser_->Pos_; + + // pos must not be changed after last meaningful invocation of Next() + UNIT_ASSERT(!Parser_->Next()); + UNIT_ASSERT_VALUES_EQUAL(Pos_, Parser_->Pos_); + UNIT_ASSERT(!Parser_->Next()); + UNIT_ASSERT_VALUES_EQUAL(Pos_, Parser_->Pos_); + } + + void AcceptError() { + Initialize(); + try { + Parser_->Next(); + UNIT_FAIL("expecting exception"); + } catch (const TUsageException&) { + // expecting + } + } + + void AcceptUnexpectedOption() { + Initialize(); + size_t pos = Parser_->Pos_; + size_t sop = Parser_->Sop_; + AcceptError(); + UNIT_ASSERT_VALUES_EQUAL(pos, Parser_->Pos_); + UNIT_ASSERT_VALUES_EQUAL(sop, Parser_->Sop_); + } + void AcceptFreeArg(const TString& expected) { - UNIT_ASSERT(Pos_ < Parser_->Argc_); - UNIT_ASSERT_VALUES_EQUAL(expected, Parser_->Argv_[Pos_]); - ++Pos_; - } - - void AcceptEndOfFreeArgs() { - UNIT_ASSERT_VALUES_EQUAL(Argv_.size(), Pos_); - } -}; - + UNIT_ASSERT(Pos_ < Parser_->Argc_); + UNIT_ASSERT_VALUES_EQUAL(expected, Parser_->Argv_[Pos_]); + ++Pos_; + } + + void AcceptEndOfFreeArgs() { + UNIT_ASSERT_VALUES_EQUAL(Argv_.size(), Pos_); + } +}; + namespace { bool gSimpleFlag = false; void SimpleHander(void) { @@ -134,37 +134,37 @@ namespace { Y_UNIT_TEST_SUITE(TLastGetoptTests) { Y_UNIT_TEST(TestEqual) { - TOptsNoDefault opts; - opts.AddLongOption("from"); - opts.AddLongOption("to"); + TOptsNoDefault opts; + opts.AddLongOption("from"); + opts.AddLongOption("to"); TOptsParseResultTestWrapper r(&opts, V({"copy", "--from=/", "--to=/etc"})); - - UNIT_ASSERT_VALUES_EQUAL("copy", r.GetProgramName()); - UNIT_ASSERT_VALUES_EQUAL("/", r.Get("from")); - UNIT_ASSERT_VALUES_EQUAL("/etc", r.Get("to")); - UNIT_ASSERT_VALUES_EQUAL("/etc", r.GetOrElse("to", "trash")); - UNIT_ASSERT(r.Has("from")); - UNIT_ASSERT(r.Has("to")); + + UNIT_ASSERT_VALUES_EQUAL("copy", r.GetProgramName()); + UNIT_ASSERT_VALUES_EQUAL("/", r.Get("from")); + UNIT_ASSERT_VALUES_EQUAL("/etc", r.Get("to")); + UNIT_ASSERT_VALUES_EQUAL("/etc", r.GetOrElse("to", "trash")); + UNIT_ASSERT(r.Has("from")); + UNIT_ASSERT(r.Has("to")); UNIT_ASSERT_EXCEPTION(r.Get("left"), TException); - } - + } + Y_UNIT_TEST(TestCharOptions) { - TOptsNoDefault opts; - opts.AddCharOption('R', NO_ARGUMENT); - opts.AddCharOption('l', NO_ARGUMENT); - opts.AddCharOption('h', NO_ARGUMENT); + TOptsNoDefault opts; + opts.AddCharOption('R', NO_ARGUMENT); + opts.AddCharOption('l', NO_ARGUMENT); + opts.AddCharOption('h', NO_ARGUMENT); TOptsParseResultTestWrapper r(&opts, V({"cp", "/etc", "-Rl", "/tmp/etc"})); - UNIT_ASSERT(r.Has('R')); - UNIT_ASSERT(r.Has('l')); - UNIT_ASSERT(!r.Has('h')); - + UNIT_ASSERT(r.Has('R')); + UNIT_ASSERT(r.Has('l')); + UNIT_ASSERT(!r.Has('h')); + UNIT_ASSERT_VALUES_EQUAL(2u, r.GetFreeArgs().size()); UNIT_ASSERT_VALUES_EQUAL(2u, r.GetFreeArgCount()); - UNIT_ASSERT_VALUES_EQUAL("/etc", r.GetFreeArgs()[0]); - UNIT_ASSERT_VALUES_EQUAL("/tmp/etc", r.GetFreeArgs()[1]); - } - + UNIT_ASSERT_VALUES_EQUAL("/etc", r.GetFreeArgs()[0]); + UNIT_ASSERT_VALUES_EQUAL("/tmp/etc", r.GetFreeArgs()[1]); + } + Y_UNIT_TEST(TestFreeArgs) { TOptsNoDefault opts; opts.SetFreeArgsNum(1, 3); @@ -185,167 +185,167 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { } Y_UNIT_TEST(TestCharOptionsRequiredOptional) { - TOptsNoDefault opts; - opts.AddCharOption('d', REQUIRED_ARGUMENT); - opts.AddCharOption('e', REQUIRED_ARGUMENT); - opts.AddCharOption('x', REQUIRED_ARGUMENT); - opts.AddCharOption('y', REQUIRED_ARGUMENT); - opts.AddCharOption('l', NO_ARGUMENT); + TOptsNoDefault opts; + opts.AddCharOption('d', REQUIRED_ARGUMENT); + opts.AddCharOption('e', REQUIRED_ARGUMENT); + opts.AddCharOption('x', REQUIRED_ARGUMENT); + opts.AddCharOption('y', REQUIRED_ARGUMENT); + opts.AddCharOption('l', NO_ARGUMENT); TOptsParseResultTestWrapper r(&opts, V({"cmd", "-ld11", "-e", "22", "-lllx33", "-y", "44"})); - UNIT_ASSERT_VALUES_EQUAL("11", r.Get('d')); - UNIT_ASSERT_VALUES_EQUAL("22", r.Get('e')); - UNIT_ASSERT_VALUES_EQUAL("33", r.Get('x')); - UNIT_ASSERT_VALUES_EQUAL("44", r.Get('y')); - } - + UNIT_ASSERT_VALUES_EQUAL("11", r.Get('d')); + UNIT_ASSERT_VALUES_EQUAL("22", r.Get('e')); + UNIT_ASSERT_VALUES_EQUAL("33", r.Get('x')); + UNIT_ASSERT_VALUES_EQUAL("44", r.Get('y')); + } + Y_UNIT_TEST(TestReturnInOrder) { - TOptsParserTester tester; - tester.Opts_.AddLongOption('v', "value"); - tester.Opts_.ArgPermutation_ = RETURN_IN_ORDER; - - tester.Argv_.push_back("cmd"); - tester.Argv_.push_back("--value=11"); - tester.Argv_.push_back("xx"); - tester.Argv_.push_back("-v12"); - tester.Argv_.push_back("yy"); - tester.Argv_.push_back("--"); - tester.Argv_.push_back("-v13"); - tester.Argv_.push_back("--"); - - tester.AcceptOptionWithValue("value", "11"); - tester.AcceptFreeArgInOrder("xx"); - tester.AcceptOptionWithValue('v', "12"); - tester.AcceptFreeArgInOrder("yy"); - tester.AcceptFreeArgInOrder("-v13"); - tester.AcceptFreeArgInOrder("--"); - tester.AcceptEndOfOptions(); - tester.AcceptEndOfFreeArgs(); - } - + TOptsParserTester tester; + tester.Opts_.AddLongOption('v', "value"); + tester.Opts_.ArgPermutation_ = RETURN_IN_ORDER; + + tester.Argv_.push_back("cmd"); + tester.Argv_.push_back("--value=11"); + tester.Argv_.push_back("xx"); + tester.Argv_.push_back("-v12"); + tester.Argv_.push_back("yy"); + tester.Argv_.push_back("--"); + tester.Argv_.push_back("-v13"); + tester.Argv_.push_back("--"); + + tester.AcceptOptionWithValue("value", "11"); + tester.AcceptFreeArgInOrder("xx"); + tester.AcceptOptionWithValue('v', "12"); + tester.AcceptFreeArgInOrder("yy"); + tester.AcceptFreeArgInOrder("-v13"); + tester.AcceptFreeArgInOrder("--"); + tester.AcceptEndOfOptions(); + tester.AcceptEndOfFreeArgs(); + } + Y_UNIT_TEST(TestRequireOrder) { - TOptsParserTester tester; - tester.Opts_.ArgPermutation_ = REQUIRE_ORDER; - tester.Opts_.AddLongOption('v', "value"); - - tester.Argv_.push_back("cmd"); - tester.Argv_.push_back("--value=11"); - tester.Argv_.push_back("xx"); - tester.Argv_.push_back("-v12"); - tester.Argv_.push_back("yy"); - - tester.AcceptOptionWithValue("value", "11"); - tester.AcceptEndOfOptions(); - - tester.AcceptFreeArg("xx"); - tester.AcceptFreeArg("-v12"); - tester.AcceptFreeArg("yy"); - tester.AcceptEndOfFreeArgs(); - } - + TOptsParserTester tester; + tester.Opts_.ArgPermutation_ = REQUIRE_ORDER; + tester.Opts_.AddLongOption('v', "value"); + + tester.Argv_.push_back("cmd"); + tester.Argv_.push_back("--value=11"); + tester.Argv_.push_back("xx"); + tester.Argv_.push_back("-v12"); + tester.Argv_.push_back("yy"); + + tester.AcceptOptionWithValue("value", "11"); + tester.AcceptEndOfOptions(); + + tester.AcceptFreeArg("xx"); + tester.AcceptFreeArg("-v12"); + tester.AcceptFreeArg("yy"); + tester.AcceptEndOfFreeArgs(); + } + Y_UNIT_TEST(TestPlusForLongOption) { - TOptsParserTester tester; - tester.Opts_.AddLongOption('v', "value"); - tester.Opts_.AllowPlusForLong_ = true; - tester.Argv_.push_back("cmd"); - tester.Argv_.push_back("+value=11"); - tester.Argv_.push_back("xx"); - tester.Argv_.push_back("-v12"); - tester.Argv_.push_back("yy"); - - tester.AcceptOptionWithValue("value", "11"); - tester.AcceptOptionWithValue("value", "12"); - tester.AcceptEndOfOptions(); - - tester.AcceptFreeArg("xx"); - tester.AcceptFreeArg("yy"); - tester.AcceptEndOfFreeArgs(); - } - + TOptsParserTester tester; + tester.Opts_.AddLongOption('v', "value"); + tester.Opts_.AllowPlusForLong_ = true; + tester.Argv_.push_back("cmd"); + tester.Argv_.push_back("+value=11"); + tester.Argv_.push_back("xx"); + tester.Argv_.push_back("-v12"); + tester.Argv_.push_back("yy"); + + tester.AcceptOptionWithValue("value", "11"); + tester.AcceptOptionWithValue("value", "12"); + tester.AcceptEndOfOptions(); + + tester.AcceptFreeArg("xx"); + tester.AcceptFreeArg("yy"); + tester.AcceptEndOfFreeArgs(); + } + Y_UNIT_TEST(TestBug1) { - TOptsParserTester tester; - tester.Opts_.AddCharOptions("A:b:cd:"); - - tester.Argv_.push_back("cmd"); - tester.Argv_.push_back("-A"); - tester.Argv_.push_back("aaaa"); - tester.Argv_.push_back("zz"); - tester.Argv_.push_back("-c"); - tester.Argv_.push_back("-d8"); - tester.Argv_.push_back("ww"); - - tester.AcceptOptionWithValue('A', "aaaa"); - tester.AcceptOptionWithoutValue('c'); - tester.AcceptOptionWithValue('d', "8"); - tester.AcceptEndOfOptions(); - - tester.AcceptFreeArg("zz"); - tester.AcceptFreeArg("ww"); - tester.AcceptEndOfFreeArgs(); - } - + TOptsParserTester tester; + tester.Opts_.AddCharOptions("A:b:cd:"); + + tester.Argv_.push_back("cmd"); + tester.Argv_.push_back("-A"); + tester.Argv_.push_back("aaaa"); + tester.Argv_.push_back("zz"); + tester.Argv_.push_back("-c"); + tester.Argv_.push_back("-d8"); + tester.Argv_.push_back("ww"); + + tester.AcceptOptionWithValue('A', "aaaa"); + tester.AcceptOptionWithoutValue('c'); + tester.AcceptOptionWithValue('d', "8"); + tester.AcceptEndOfOptions(); + + tester.AcceptFreeArg("zz"); + tester.AcceptFreeArg("ww"); + tester.AcceptEndOfFreeArgs(); + } + Y_UNIT_TEST(TestPermuteComplex) { - TOptsParserTester tester; - - tester.Opts_.AddCharOption('x').NoArgument(); - tester.Opts_.AddCharOption('y').RequiredArgument(); - tester.Opts_.AddCharOption('z').NoArgument(); - tester.Opts_.AddCharOption('w').RequiredArgument(); - tester.Opts_.ArgPermutation_ = PERMUTE; - - tester.Argv_.push_back("cmd"); - tester.Argv_.push_back("-x"); - tester.Argv_.push_back("-y"); - tester.Argv_.push_back("val"); - tester.Argv_.push_back("freearg1"); - tester.Argv_.push_back("-zw"); - tester.Argv_.push_back("val2"); - tester.Argv_.push_back("freearg2"); - - tester.AcceptOptionWithoutValue('x'); - tester.AcceptOptionWithValue('y', "val"); - tester.AcceptOptionWithoutValue('z'); - tester.AcceptOptionWithValue('w', "val2"); - tester.AcceptEndOfOptions(); - tester.AcceptFreeArg("freearg1"); - tester.AcceptFreeArg("freearg2"); - tester.AcceptEndOfFreeArgs(); - } - + TOptsParserTester tester; + + tester.Opts_.AddCharOption('x').NoArgument(); + tester.Opts_.AddCharOption('y').RequiredArgument(); + tester.Opts_.AddCharOption('z').NoArgument(); + tester.Opts_.AddCharOption('w').RequiredArgument(); + tester.Opts_.ArgPermutation_ = PERMUTE; + + tester.Argv_.push_back("cmd"); + tester.Argv_.push_back("-x"); + tester.Argv_.push_back("-y"); + tester.Argv_.push_back("val"); + tester.Argv_.push_back("freearg1"); + tester.Argv_.push_back("-zw"); + tester.Argv_.push_back("val2"); + tester.Argv_.push_back("freearg2"); + + tester.AcceptOptionWithoutValue('x'); + tester.AcceptOptionWithValue('y', "val"); + tester.AcceptOptionWithoutValue('z'); + tester.AcceptOptionWithValue('w', "val2"); + tester.AcceptEndOfOptions(); + tester.AcceptFreeArg("freearg1"); + tester.AcceptFreeArg("freearg2"); + tester.AcceptEndOfFreeArgs(); + } + Y_UNIT_TEST(TestFinalDashDash) { - TOptsParserTester tester; - tester.Opts_.AddLongOption("size"); - - tester.Argv_.push_back("cmd"); - tester.Argv_.push_back("--"); - - tester.AcceptEndOfOptions(); - tester.AcceptEndOfFreeArgs(); - } - + TOptsParserTester tester; + tester.Opts_.AddLongOption("size"); + + tester.Argv_.push_back("cmd"); + tester.Argv_.push_back("--"); + + tester.AcceptEndOfOptions(); + tester.AcceptEndOfFreeArgs(); + } + Y_UNIT_TEST(TestDashDashAfterDashDash) { - TOptsParserTester tester; - tester.Opts_.AddLongOption("size"); - - tester.Argv_.push_back("cmd"); - tester.Argv_.push_back("--"); - tester.Argv_.push_back("--"); - tester.Argv_.push_back("--"); - - tester.AcceptEndOfOptions(); - tester.AcceptFreeArg("--"); - tester.AcceptFreeArg("--"); - tester.AcceptEndOfFreeArgs(); - } - + TOptsParserTester tester; + tester.Opts_.AddLongOption("size"); + + tester.Argv_.push_back("cmd"); + tester.Argv_.push_back("--"); + tester.Argv_.push_back("--"); + tester.Argv_.push_back("--"); + + tester.AcceptEndOfOptions(); + tester.AcceptFreeArg("--"); + tester.AcceptFreeArg("--"); + tester.AcceptEndOfFreeArgs(); + } + Y_UNIT_TEST(TestUnexpectedUnknownOption) { - TOptsParserTester tester; - - tester.Argv_.push_back("cmd"); - tester.Argv_.push_back("-x"); - - tester.AcceptUnexpectedOption(); - } - + TOptsParserTester tester; + + tester.Argv_.push_back("cmd"); + tester.Argv_.push_back("-x"); + + tester.AcceptUnexpectedOption(); + } + Y_UNIT_TEST(TestDuplicatedOptionCrash) { // this test is broken, cause UNIT_ASSERT(false) always throws return; @@ -364,84 +364,84 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { } Y_UNIT_TEST(TestPositionWhenNoArgs) { - TOptsParserTester tester; - - tester.Argv_.push_back("cmd"); - - tester.Opts_.AddCharOption('c'); - - tester.AcceptEndOfOptions(); - + TOptsParserTester tester; + + tester.Argv_.push_back("cmd"); + + tester.Opts_.AddCharOption('c'); + + tester.AcceptEndOfOptions(); + UNIT_ASSERT_VALUES_EQUAL(1u, tester.Parser_->Pos_); - } - + } + Y_UNIT_TEST(TestExpectedUnknownCharOption) { - TOptsParserTester tester; - - tester.Argv_.push_back("cmd"); - tester.Argv_.push_back("-x"); - tester.Argv_.push_back("-y"); - tester.Argv_.push_back("val"); - tester.Argv_.push_back("freearg1"); - tester.Argv_.push_back("-zw"); - tester.Argv_.push_back("val2"); - tester.Argv_.push_back("freearg2"); - - tester.Opts_.AllowUnknownCharOptions_ = true; - - tester.AcceptOptionWithoutValue('x'); - tester.AcceptOptionWithValue('y', "val"); - tester.AcceptOptionWithoutValue('z'); - tester.AcceptOptionWithValue('w', "val2"); - tester.AcceptEndOfOptions(); - tester.AcceptFreeArg("freearg1"); - tester.AcceptFreeArg("freearg2"); - tester.AcceptEndOfFreeArgs(); - } - -#if 0 + TOptsParserTester tester; + + tester.Argv_.push_back("cmd"); + tester.Argv_.push_back("-x"); + tester.Argv_.push_back("-y"); + tester.Argv_.push_back("val"); + tester.Argv_.push_back("freearg1"); + tester.Argv_.push_back("-zw"); + tester.Argv_.push_back("val2"); + tester.Argv_.push_back("freearg2"); + + tester.Opts_.AllowUnknownCharOptions_ = true; + + tester.AcceptOptionWithoutValue('x'); + tester.AcceptOptionWithValue('y', "val"); + tester.AcceptOptionWithoutValue('z'); + tester.AcceptOptionWithValue('w', "val2"); + tester.AcceptEndOfOptions(); + tester.AcceptFreeArg("freearg1"); + tester.AcceptFreeArg("freearg2"); + tester.AcceptEndOfFreeArgs(); + } + +#if 0 Y_UNIT_TEST(TestRequiredParams) { - TOptsParserTester tester; - - tester.Argv_.push_back("cmd"); - tester.Argv_.push_back("--port=1231"); - tester.Argv_.push_back("asas"); - - tester.Opts_.AddLongOption("port"); - tester.Opts_.AddLongOption("home").Required(); - - tester.AcceptOptionWithValue("port", "1231"); - tester.AcceptError(); - } -#endif - + TOptsParserTester tester; + + tester.Argv_.push_back("cmd"); + tester.Argv_.push_back("--port=1231"); + tester.Argv_.push_back("asas"); + + tester.Opts_.AddLongOption("port"); + tester.Opts_.AddLongOption("home").Required(); + + tester.AcceptOptionWithValue("port", "1231"); + tester.AcceptError(); + } +#endif + Y_UNIT_TEST(TestStoreResult) { - TOptsNoDefault opts; + TOptsNoDefault opts; TString data; - int number; + int number; TMaybe<TString> optionalString0, optionalString1; TMaybe<int> optionalNumber0, optionalNumber1; - opts.AddLongOption('d', "data").StoreResult(&data); - opts.AddLongOption('n', "number").StoreResult(&number); + opts.AddLongOption('d', "data").StoreResult(&data); + opts.AddLongOption('n', "number").StoreResult(&number); opts.AddLongOption("optional-string-0").StoreResult(&optionalString0); opts.AddLongOption("optional-number-0").StoreResult(&optionalNumber0); opts.AddLongOption("optional-string-1").StoreResult(&optionalString1); opts.AddLongOption("optional-number-1").StoreResult(&optionalNumber1); TOptsParseResultTestWrapper r(&opts, V({"cmd", "--data=jjhh", "-n", "11", "--optional-number-1=8", "--optional-string-1=os1"})); - UNIT_ASSERT_VALUES_EQUAL("jjhh", data); - UNIT_ASSERT_VALUES_EQUAL(11, number); + UNIT_ASSERT_VALUES_EQUAL("jjhh", data); + UNIT_ASSERT_VALUES_EQUAL(11, number); UNIT_ASSERT(!optionalString0.Defined()); UNIT_ASSERT(!optionalNumber0.Defined()); UNIT_ASSERT_VALUES_EQUAL(*optionalString1, "os1"); UNIT_ASSERT_VALUES_EQUAL(*optionalNumber1, 8); - } - + } + Y_UNIT_TEST(TestStoreValue) { int a = 0, b = 0; size_t c = 0; EHasArg e = NO_ARGUMENT; - TOptsNoDefault opts; + TOptsNoDefault opts; opts.AddLongOption('a', "alpha").NoArgument().StoreValue(&a, 42); opts.AddLongOption('b', "beta").NoArgument().StoreValue(&b, 24); opts.AddLongOption('e', "enum").NoArgument().StoreValue(&e, REQUIRED_ARGUMENT).StoreValue(&c, 12345); @@ -472,17 +472,17 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { } Y_UNIT_TEST(TestDefaultValue) { - TOptsNoDefault opts; - opts.AddLongOption("path").DefaultValue("/etc"); + TOptsNoDefault opts; + opts.AddLongOption("path").DefaultValue("/etc"); int value = 42; opts.AddLongOption("value").StoreResult(&value).DefaultValue(32); TOptsParseResultTestWrapper r(&opts, V({"cmd", "dfdf"})); - UNIT_ASSERT_VALUES_EQUAL("/etc", r.Get("path")); + UNIT_ASSERT_VALUES_EQUAL("/etc", r.Get("path")); UNIT_ASSERT_VALUES_EQUAL(32, value); - } - + } + Y_UNIT_TEST(TestSplitValue) { - TOptsNoDefault opts; + TOptsNoDefault opts; TVector<TString> vals; opts.AddLongOption('s', "split").SplitHandler(&vals, ','); TOptsParseResultTestWrapper r(&opts, V({"prog", "--split=a,b,c"})); @@ -508,17 +508,17 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { } Y_UNIT_TEST(TestParseArgs) { - TOptsNoDefault o("AbCx:y:z::"); - UNIT_ASSERT_EQUAL(o.GetCharOption('A').HasArg_, NO_ARGUMENT); - UNIT_ASSERT_EQUAL(o.GetCharOption('b').HasArg_, NO_ARGUMENT); - UNIT_ASSERT_EQUAL(o.GetCharOption('C').HasArg_, NO_ARGUMENT); - UNIT_ASSERT_EQUAL(o.GetCharOption('x').HasArg_, REQUIRED_ARGUMENT); - UNIT_ASSERT_EQUAL(o.GetCharOption('y').HasArg_, REQUIRED_ARGUMENT); - UNIT_ASSERT_EQUAL(o.GetCharOption('z').HasArg_, OPTIONAL_ARGUMENT); - } - + TOptsNoDefault o("AbCx:y:z::"); + UNIT_ASSERT_EQUAL(o.GetCharOption('A').HasArg_, NO_ARGUMENT); + UNIT_ASSERT_EQUAL(o.GetCharOption('b').HasArg_, NO_ARGUMENT); + UNIT_ASSERT_EQUAL(o.GetCharOption('C').HasArg_, NO_ARGUMENT); + UNIT_ASSERT_EQUAL(o.GetCharOption('x').HasArg_, REQUIRED_ARGUMENT); + UNIT_ASSERT_EQUAL(o.GetCharOption('y').HasArg_, REQUIRED_ARGUMENT); + UNIT_ASSERT_EQUAL(o.GetCharOption('z').HasArg_, OPTIONAL_ARGUMENT); + } + Y_UNIT_TEST(TestRequiredOpts) { - TOptsNoDefault opts; + TOptsNoDefault opts; TOpt& opt_d = opts.AddCharOption('d'); // test 'not required' @@ -549,14 +549,14 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { }; Y_UNIT_TEST(TestHandlers) { { - TOptsNoDefault opts; + TOptsNoDefault opts; bool flag = false; opts.AddLongOption("flag").Handler0(HandlerStoreTrue(&flag)).NoArgument(); TOptsParseResultTestWrapper r(&opts, V({"cmd", "--flag"})); UNIT_ASSERT(flag); } { - TOptsNoDefault opts; + TOptsNoDefault opts; unsigned uval = 5; double fval = 0.0; opts.AddLongOption("flag1").RequiredArgument().StoreResult(&uval); @@ -702,17 +702,17 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { Y_UNIT_TEST(TestAppendTo) { TVector<int> ints; - - TOptsNoDefault opts; - opts.AddLongOption("size").AppendTo(&ints); - + + TOptsNoDefault opts; + opts.AddLongOption("size").AppendTo(&ints); + TOptsParseResultTestWrapper r(&opts, V({"cmd", "--size=17", "--size=19"})); - - UNIT_ASSERT_VALUES_EQUAL(size_t(2), ints.size()); - UNIT_ASSERT_VALUES_EQUAL(17, ints.at(0)); - UNIT_ASSERT_VALUES_EQUAL(19, ints.at(1)); - } - + + UNIT_ASSERT_VALUES_EQUAL(size_t(2), ints.size()); + UNIT_ASSERT_VALUES_EQUAL(17, ints.at(0)); + UNIT_ASSERT_VALUES_EQUAL(19, ints.at(1)); + } + Y_UNIT_TEST(TestEmplaceTo) { TVector<std::tuple<TString>> richPaths; @@ -791,4 +791,4 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { UNIT_ASSERT_VALUES_EQUAL(25, number); UNIT_ASSERT_VALUES_EQUAL(2, r.GetFreeArgCount()); } -} +} diff --git a/library/cpp/getopt/ut/opt2_ut.cpp b/library/cpp/getopt/ut/opt2_ut.cpp index facf0a6b0d..0e7464747c 100644 --- a/library/cpp/getopt/ut/opt2_ut.cpp +++ b/library/cpp/getopt/ut/opt2_ut.cpp @@ -1,13 +1,13 @@ #include <library/cpp/getopt/opt2.h> #include <library/cpp/testing/unittest/registar.h> - + //using namespace NLastGetopt; - + Y_UNIT_TEST_SUITE(Opt2Test) { Y_UNIT_TEST(TestSimple) { int argc = 8; - char* argv[] = { + char* argv[] = { (char*)"cmd", (char*)"--aaaa=aaaa", (char*)"zz", @@ -16,10 +16,10 @@ Y_UNIT_TEST_SUITE(Opt2Test) { (char*)"-c", (char*)"-d8", (char*)"ww", - }; - + }; + Opt2 opt(argc, argv, "A:b:cd:e:x:", 2, "aaaa=A"); - + const char* edef = "edef"; const char* a = opt.Arg('A', "<var_name> - usage of -A"); int b = opt.Int('b', "<var_name> - usage of -b", 2); @@ -27,21 +27,21 @@ Y_UNIT_TEST_SUITE(Opt2Test) { int d = opt.Int('d', "<var_name> - usage of -d", 13); const char* e = opt.Arg('e', "<unused> - only default is really used", edef); const TVector<const char*>& x = opt.MArg('x', "<var_name> - usage of -x"); - - UNIT_ASSERT(!opt.AutoUsage("<L> <M>")); - UNIT_ASSERT_VALUES_EQUAL("aaaa", a); - UNIT_ASSERT_VALUES_EQUAL(2, b); - UNIT_ASSERT(c); - UNIT_ASSERT_VALUES_EQUAL(8, d); + + UNIT_ASSERT(!opt.AutoUsage("<L> <M>")); + UNIT_ASSERT_VALUES_EQUAL("aaaa", a); + UNIT_ASSERT_VALUES_EQUAL(2, b); + UNIT_ASSERT(c); + UNIT_ASSERT_VALUES_EQUAL(8, d); UNIT_ASSERT_VALUES_EQUAL((void*)edef, e); - + UNIT_ASSERT_VALUES_EQUAL(2u, opt.Pos.size()); UNIT_ASSERT_STRINGS_EQUAL("zz", opt.Pos.at(0)); UNIT_ASSERT_VALUES_EQUAL((void*)argv[2], opt.Pos.at(0)); UNIT_ASSERT_STRINGS_EQUAL("ww", opt.Pos.at(1)); UNIT_ASSERT_STRINGS_EQUAL("1", x.at(0)); UNIT_ASSERT_STRINGS_EQUAL("2", x.at(1)); - } + } Y_UNIT_TEST(TestErrors1) { int argc = 4; @@ -60,4 +60,4 @@ Y_UNIT_TEST_SUITE(Opt2Test) { UNIT_ASSERT(c); UNIT_ASSERT_VALUES_EQUAL((void*)edef, e); } -} +} diff --git a/library/cpp/getopt/ut/opt_ut.cpp b/library/cpp/getopt/ut/opt_ut.cpp index 66122f6ae3..441aa493a0 100644 --- a/library/cpp/getopt/ut/opt_ut.cpp +++ b/library/cpp/getopt/ut/opt_ut.cpp @@ -2,19 +2,19 @@ #include <library/cpp/testing/unittest/registar.h> #include <util/string/vector.h> - + Y_UNIT_TEST_SUITE(OptTest) { Y_UNIT_TEST(TestSimple) { - int argc = 3; - char* argv[] = { + int argc = 3; + char* argv[] = { (char*)"cmd", (char*)"-x"}; - Opt opt(argc, argv, ""); - opt.Err = false; // be quiet - UNIT_ASSERT_VALUES_EQUAL('?', opt.Get()); - UNIT_ASSERT_VALUES_EQUAL(EOF, opt.Get()); - UNIT_ASSERT_VALUES_EQUAL(EOF, opt.Get()); - UNIT_ASSERT_VALUES_EQUAL(EOF, opt.Get()); - } + Opt opt(argc, argv, ""); + opt.Err = false; // be quiet + UNIT_ASSERT_VALUES_EQUAL('?', opt.Get()); + UNIT_ASSERT_VALUES_EQUAL(EOF, opt.Get()); + UNIT_ASSERT_VALUES_EQUAL(EOF, opt.Get()); + UNIT_ASSERT_VALUES_EQUAL(EOF, opt.Get()); + } Y_UNIT_TEST(TestFreeArguments) { Opt::Ion options[] = { @@ -49,4 +49,4 @@ Y_UNIT_TEST_SUITE(OptTest) { UNIT_ASSERT_VALUES_EQUAL(optionValue, "ARG2"); } } -} +} diff --git a/library/cpp/getopt/ut/posix_getopt_ut.cpp b/library/cpp/getopt/ut/posix_getopt_ut.cpp index 9235e7340d..b6d374bf28 100644 --- a/library/cpp/getopt/ut/posix_getopt_ut.cpp +++ b/library/cpp/getopt/ut/posix_getopt_ut.cpp @@ -1,119 +1,119 @@ #include <library/cpp/getopt/posix_getopt.h> #include <library/cpp/testing/unittest/registar.h> - -using namespace NLastGetopt; - + +using namespace NLastGetopt; + Y_UNIT_TEST_SUITE(TPosixGetoptTest) { Y_UNIT_TEST(TestSimple) { - int argc = 6; + int argc = 6; const char* argv0[] = {"program", "-b", "-f1", "-f", "2", "zzzz"}; char** const argv = (char**)argv0; - - NLastGetopt::optreset = 1; - UNIT_ASSERT_VALUES_EQUAL('b', NLastGetopt::getopt(argc, argv, "bf:")); - UNIT_ASSERT_VALUES_EQUAL('f', NLastGetopt::getopt(argc, argv, "bf:")); + + NLastGetopt::optreset = 1; + UNIT_ASSERT_VALUES_EQUAL('b', NLastGetopt::getopt(argc, argv, "bf:")); + UNIT_ASSERT_VALUES_EQUAL('f', NLastGetopt::getopt(argc, argv, "bf:")); UNIT_ASSERT_VALUES_EQUAL(NLastGetopt::optarg, TString("1")); - UNIT_ASSERT_VALUES_EQUAL('f', NLastGetopt::getopt(argc, argv, "bf:")); + UNIT_ASSERT_VALUES_EQUAL('f', NLastGetopt::getopt(argc, argv, "bf:")); UNIT_ASSERT_VALUES_EQUAL(NLastGetopt::optarg, TString("2")); - UNIT_ASSERT_VALUES_EQUAL(-1, NLastGetopt::getopt(argc, argv, "bf:")); - - UNIT_ASSERT_VALUES_EQUAL(5, NLastGetopt::optind); - } - + UNIT_ASSERT_VALUES_EQUAL(-1, NLastGetopt::getopt(argc, argv, "bf:")); + + UNIT_ASSERT_VALUES_EQUAL(5, NLastGetopt::optind); + } + Y_UNIT_TEST(TestLong) { - int daggerset = 0; - /* options descriptor */ - const NLastGetopt::option longopts[] = { + int daggerset = 0; + /* options descriptor */ + const NLastGetopt::option longopts[] = { {"buffy", no_argument, nullptr, 'b'}, {"fluoride", required_argument, nullptr, 'f'}, {"daggerset", no_argument, &daggerset, 1}, {nullptr, 0, nullptr, 0}}; - - int argc = 7; + + int argc = 7; const char* argv0[] = {"program", "-b", "--buffy", "-f1", "--fluoride=2", "--daggerset", "zzzz"}; char** const argv = (char**)argv0; - - int longIndex; - - NLastGetopt::optreset = 1; - UNIT_ASSERT_VALUES_EQUAL('b', NLastGetopt::getopt_long(argc, argv, "bf:", longopts, &longIndex)); - UNIT_ASSERT_VALUES_EQUAL(0, longIndex); + + int longIndex; + + NLastGetopt::optreset = 1; + UNIT_ASSERT_VALUES_EQUAL('b', NLastGetopt::getopt_long(argc, argv, "bf:", longopts, &longIndex)); + UNIT_ASSERT_VALUES_EQUAL(0, longIndex); UNIT_ASSERT_VALUES_EQUAL('b', NLastGetopt::getopt_long(argc, argv, "bf:", longopts, nullptr)); - UNIT_ASSERT_VALUES_EQUAL('f', NLastGetopt::getopt_long(argc, argv, "bf:", longopts, &longIndex)); - UNIT_ASSERT_VALUES_EQUAL(1, longIndex); + UNIT_ASSERT_VALUES_EQUAL('f', NLastGetopt::getopt_long(argc, argv, "bf:", longopts, &longIndex)); + UNIT_ASSERT_VALUES_EQUAL(1, longIndex); UNIT_ASSERT_VALUES_EQUAL('f', NLastGetopt::getopt_long(argc, argv, "bf:", longopts, nullptr)); UNIT_ASSERT_VALUES_EQUAL(0, NLastGetopt::getopt_long(argc, argv, "bf:", longopts, nullptr)); UNIT_ASSERT_VALUES_EQUAL(-1, NLastGetopt::getopt_long(argc, argv, "bf:", longopts, nullptr)); - - UNIT_ASSERT_VALUES_EQUAL(6, NLastGetopt::optind); - } - + + UNIT_ASSERT_VALUES_EQUAL(6, NLastGetopt::optind); + } + Y_UNIT_TEST(TestLongPermutation) { - int daggerset = 0; - /* options descriptor */ - const NLastGetopt::option longopts[] = { + int daggerset = 0; + /* options descriptor */ + const NLastGetopt::option longopts[] = { {"buffy", no_argument, nullptr, 'b'}, {"fluoride", required_argument, nullptr, 'f'}, {"daggerset", no_argument, &daggerset, 1}, {nullptr, 0, nullptr, 0}}; - - int argc = 7; + + int argc = 7; const char* argv0[] = {"program", "aa", "-b", "bb", "cc", "--buffy", "dd"}; char** const argv = (char**)argv0; - - NLastGetopt::optreset = 1; + + NLastGetopt::optreset = 1; UNIT_ASSERT_VALUES_EQUAL('b', NLastGetopt::getopt_long(argc, argv, "bf:", longopts, nullptr)); UNIT_ASSERT_VALUES_EQUAL('b', NLastGetopt::getopt_long(argc, argv, "bf:", longopts, nullptr)); UNIT_ASSERT_VALUES_EQUAL(-1, NLastGetopt::getopt_long(argc, argv, "bf:", longopts, nullptr)); - - UNIT_ASSERT_VALUES_EQUAL(3, NLastGetopt::optind); - } - + + UNIT_ASSERT_VALUES_EQUAL(3, NLastGetopt::optind); + } + Y_UNIT_TEST(TestNoOptionsOptionsWithDoubleDash) { - const NLastGetopt::option longopts[] = { + const NLastGetopt::option longopts[] = { {"buffy", no_argument, nullptr, 'b'}, {"fluoride", no_argument, nullptr, 'f'}, {nullptr, 0, nullptr, 0}}; - - int argc = 2; + + int argc = 2; const char* argv0[] = {"program", "--bf"}; char** const argv = (char**)argv0; - - NLastGetopt::optreset = 1; + + NLastGetopt::optreset = 1; UNIT_ASSERT_VALUES_EQUAL('?', NLastGetopt::getopt_long(argc, argv, "bf", longopts, nullptr)); - } - + } + Y_UNIT_TEST(TestLongOnly) { - const NLastGetopt::option longopts[] = { + const NLastGetopt::option longopts[] = { {"foo", no_argument, nullptr, 'F'}, {"fluoride", no_argument, nullptr, 'f'}, {"ogogo", no_argument, nullptr, 'o'}, {nullptr, 0, nullptr, 0}}; - - int argc = 4; + + int argc = 4; const char* argv0[] = {"program", "--foo", "-foo", "-fo"}; char** const argv = (char**)argv0; - - NLastGetopt::optreset = 1; + + NLastGetopt::optreset = 1; UNIT_ASSERT_VALUES_EQUAL('F', NLastGetopt::getopt_long_only(argc, argv, "fo", longopts, nullptr)); UNIT_ASSERT_VALUES_EQUAL('F', NLastGetopt::getopt_long_only(argc, argv, "fo", longopts, nullptr)); UNIT_ASSERT_VALUES_EQUAL('f', NLastGetopt::getopt_long_only(argc, argv, "fo", longopts, nullptr)); UNIT_ASSERT_VALUES_EQUAL('o', NLastGetopt::getopt_long_only(argc, argv, "fo", longopts, nullptr)); UNIT_ASSERT_VALUES_EQUAL(-1, NLastGetopt::getopt_long_only(argc, argv, "fo", longopts, nullptr)); - } - + } + Y_UNIT_TEST(TestLongWithoutOnlySingleDashNowAllowed) { - const NLastGetopt::option longopts[] = { + const NLastGetopt::option longopts[] = { {"foo", no_argument, nullptr, 'F'}, {"zoo", no_argument, nullptr, 'z'}, {nullptr, 0, nullptr, 0}}; - - int argc = 2; + + int argc = 2; const char* argv0[] = {"program", "-foo"}; char** const argv = (char**)argv0; - - NLastGetopt::optreset = 1; + + NLastGetopt::optreset = 1; UNIT_ASSERT_VALUES_EQUAL('?', NLastGetopt::getopt_long(argc, argv, "z", longopts, nullptr)); - } -} + } +} diff --git a/library/cpp/http/fetch/httpfsm.h b/library/cpp/http/fetch/httpfsm.h index e79fd7a152..c4abdcd0d2 100644 --- a/library/cpp/http/fetch/httpfsm.h +++ b/library/cpp/http/fetch/httpfsm.h @@ -3,7 +3,7 @@ #include "httpheader.h" #include <util/system/maxlen.h> -#include <util/datetime/parser.h> +#include <util/datetime/parser.h> #include <time.h> @@ -19,10 +19,10 @@ struct THttpHeaderParser { return execute((unsigned char*)inBuf, (int)len); } - int Execute(TStringBuf str) { - return Execute(str.data(), str.size()); - } - + int Execute(TStringBuf str) { + return Execute(str.data(), str.size()); + } + int Init(THttpHeader* h) { int ret = Init((THttpBaseHeader*)(h)); hd = h; diff --git a/library/cpp/http/fetch/httpfsm.rl6 b/library/cpp/http/fetch/httpfsm.rl6 index 2712c013bb..eab0328b18 100644 --- a/library/cpp/http/fetch/httpfsm.rl6 +++ b/library/cpp/http/fetch/httpfsm.rl6 @@ -4,7 +4,7 @@ #include <library/cpp/charset/doccodes.h> #include <library/cpp/charset/codepage.h> #include <library/cpp/http/misc/httpcodes.h> -#include <util/datetime/base.h> +#include <util/datetime/base.h> #include <util/generic/ylimits.h> #include <algorithm> // max @@ -15,8 +15,8 @@ #pragma warning(disable: 4702) // unreachable code #endif -#define c(i) I = i; -#define m(i) I = std::max(I, (long)i); +#define c(i) I = i; +#define m(i) I = std::max(I, (long)i); static inline int X(unsigned char c) { return (c >= 'A' ? ((c & 0xdf) - 'A' + 10) : (c - '0')); @@ -40,7 +40,7 @@ static inline void setguarded(x &val, long cnt) { machine http_header_parser; include HttpDateTimeParser "../../../../util/datetime/parser.rl6"; - + alphtype unsigned char; ################# 2.2 Basic Rules ################# @@ -61,8 +61,8 @@ text = (text_char | lw)*; any_text = (any_text_char | lw)*; def = lws ':' lws; -action clear_buf { buflen = 0; } -action update_buf { if (buflen < sizeof(buf)) buf[buflen++] = fc; } +action clear_buf { buflen = 0; } +action update_buf { if (buflen < sizeof(buf)) buf[buflen++] = fc; } ################################################### ############ response status line ################# @@ -123,14 +123,14 @@ action set_connection { setguarded(base_hd->connection_closed, I); } c_token = "close"i %{m(1)} | "keep-alive"i %{m(0)}; c_tokenlist = c_token (lws ',' lws c_token)?; -connection = "connection"i def %beg_connection c_tokenlist eoh %set_connection; +connection = "connection"i def %beg_connection c_tokenlist eoh %set_connection; ################# content-encoding ################ -action beg_content_encoding { I = HTTP_COMPRESSION_ERROR; } +action beg_content_encoding { I = HTTP_COMPRESSION_ERROR; } action set_content_encoding { base_hd->compression_method = ((base_hd->compression_method == HTTP_COMPRESSION_UNSET || base_hd->compression_method == I) ? - I : (int)HTTP_COMPRESSION_ERROR); } + I : (int)HTTP_COMPRESSION_ERROR); } ce_tokenlist = "identity"i %{c(HTTP_COMPRESSION_IDENTITY)} | "gzip"i %{c(HTTP_COMPRESSION_GZIP)} @@ -138,7 +138,7 @@ ce_tokenlist = "identity"i %{c(HTTP_COMPRESSION_IDENTITY)} | "deflate"i %{c(HTTP_COMPRESSION_DEFLATE)} | "compress"i %{c(HTTP_COMPRESSION_COMPRESS)} | "x-compress"i %{c(HTTP_COMPRESSION_COMPRESS)}; -content_encoding = "content-encoding"i def %beg_content_encoding ce_tokenlist eoh %set_content_encoding; +content_encoding = "content-encoding"i def %beg_content_encoding ce_tokenlist eoh %set_content_encoding; ################# transfer-encoding ############### action beg_encoding { guard(base_hd->transfer_chunked); } @@ -146,13 +146,13 @@ action set_encoding { setguarded(base_hd->transfer_chunked, I); } e_tokenlist = "identity"i %{c(0)} | "chunked"i %{c(1)}; -transfer_encoding = "transfer-encoding"i def %beg_encoding e_tokenlist eoh %set_encoding; +transfer_encoding = "transfer-encoding"i def %beg_encoding e_tokenlist eoh %set_encoding; ################# content-length ################## action beg_content_length { guard(base_hd->content_length); } action set_content_length { setguarded(base_hd->content_length, I); } -content_length = "content-length"i def %beg_content_length int eoh %set_content_length; +content_length = "content-length"i def %beg_content_length int eoh %set_content_length; ################# content-range ################### action beg_content_range_start { guard(base_hd->content_range_start); I = -1; } @@ -162,9 +162,9 @@ action set_content_range_end { setguarded(base_hd->content_range_end, I); } action beg_content_range_el { guard(base_hd->content_range_entity_length); I = -1; } action set_content_range_el { setguarded(base_hd->content_range_entity_length, I); } -content_range = "content-range"i def "bytes"i sp %beg_content_range_start int '-' %set_content_range_start - %beg_content_range_end int '/' %set_content_range_end - %beg_content_range_el int eoh %set_content_range_el; +content_range = "content-range"i def "bytes"i sp %beg_content_range_start int '-' %set_content_range_start + %beg_content_range_end int '/' %set_content_range_end + %beg_content_range_el int eoh %set_content_range_el; ################# accept-ranges ################### action beg_accept_ranges { @@ -177,12 +177,12 @@ action set_accept_ranges { if (hd) setguarded(hd->accept_ranges, I); } ar_tokenlist = "bytes"i %{c(1)} | "none"i %{c(0)}; -accept_ranges = "accept-ranges"i def %beg_accept_ranges ar_tokenlist eoh %set_accept_ranges; +accept_ranges = "accept-ranges"i def %beg_accept_ranges ar_tokenlist eoh %set_accept_ranges; ################# content-type #################### action beg_mime { guard(base_hd->mime_type); } action set_mime { setguarded(base_hd->mime_type, I); } -action set_charset { +action set_charset { if (buflen < FETCHER_URL_MAX) { buf[buflen++] = 0; base_hd->charset = EncodingHintByName((const char*)buf); @@ -232,12 +232,12 @@ mime_type = "text/plain"i %{c(MIME_TEXT)} ; -charset_name = token_char+ >clear_buf $update_buf; -mime_param = "charset"i ws* '=' ws* '"'? charset_name '"'? %set_charset @2 +charset_name = token_char+ >clear_buf $update_buf; +mime_param = "charset"i ws* '=' ws* '"'? charset_name '"'? %set_charset @2 | token ws* '=' ws* '"'? token '"'? @1 | text $0; mime_parms = (lws ';' lws mime_param)*; -content_type = "content-type"i def %beg_mime mime_type mime_parms eoh %set_mime; +content_type = "content-type"i def %beg_mime mime_type mime_parms eoh %set_mime; ################# last modified ################### action beg_modtime { guard(base_hd->http_time); } @@ -245,10 +245,10 @@ action set_modtime { setguarded(base_hd->http_time, DateTimeFields.ToTimeT(-1)); } -last_modified = "last-modified"i def %beg_modtime http_date eoh %set_modtime; +last_modified = "last-modified"i def %beg_modtime http_date eoh %set_modtime; ################# location ######################## -action set_location { +action set_location { while (buflen > 0 && (buf[buflen - 1] == ' ' || buf[buflen - 1] == '\t')) { buflen --; } @@ -350,16 +350,16 @@ action set_squid_error { squid_error = "X-Yandex-Squid-Error"i def any_text eoh %set_squid_error; ################# auth ######################## -action init_auth { +action init_auth { if (auth_hd) auth_hd->use_auth=true; } -action update_auth_buf +action update_auth_buf { if (auth_hd && buflen < sizeof(buf)) buf[buflen++] = *fpc; } quoted_str = /"/ (text_char - /"/)* /"/ >2; -auth_quoted_str = ( /"/ ( ( text_char - /"/ )* >clear_buf $update_auth_buf ) /"/ ) > 2; +auth_quoted_str = ( /"/ ( ( text_char - /"/ )* >clear_buf $update_auth_buf ) /"/ ) > 2; # do not support auth-int, too heavy procedure @@ -394,7 +394,7 @@ auth_param = auth_good_param @1 | auth_params = auth_param ( ws* /,/ ws* auth_param )*; -digest_challenge = ("digest"i %init_auth ws+ auth_params) | +digest_challenge = ("digest"i %init_auth ws+ auth_params) | ((token-"digest"i) text); auth = "www-authenticate"i def digest_challenge eoh; @@ -597,7 +597,7 @@ request_header = message_header $0 | request_priority @1; ################# main ############################ -action accepted { lastchar = (char*)fpc; return 2; } +action accepted { lastchar = (char*)fpc; return 2; } main := ((response_status_line ('\r'? response_header)*) | (request_status_line ('\r' ? request_header)*)) @@ -628,10 +628,10 @@ machine http_chunk_parser; alphtype unsigned char; -action clear_hex { cnt64 = 0; } -action update_hex { cnt64 = 16 * cnt64 + X(fc); if(cnt64 > Max<int>()) return -2; } -action set_chunk { chunk_length = static_cast<int>(cnt64); } -action accepted { lastchar = (char*)fpc; return 2; } +action clear_hex { cnt64 = 0; } +action update_hex { cnt64 = 16 * cnt64 + X(fc); if(cnt64 > Max<int>()) return -2; } +action set_chunk { chunk_length = static_cast<int>(cnt64); } +action accepted { lastchar = (char*)fpc; return 2; } eol = '\r'? '\n'; ws = [ \t]; @@ -648,7 +648,7 @@ token = token_char+; text = (text_char | lw)*; def = lws ':' lws; -hex = (xdigit+) >clear_hex $update_hex; +hex = (xdigit+) >clear_hex $update_hex; quoted_string = '"' ((text_char - '"') $0 | '\\"' @1)* '"'; chunk_ext_val = token | quoted_string; @@ -658,9 +658,9 @@ chunk_extension = ws* (';' chunk_ext_name ws* '=' ws* chunk_ext_val ws*)*; entity_header = token def text eoh; trailer = entity_header*; -chunk = (hex - '0'+) chunk_extension? %set_chunk; +chunk = (hex - '0'+) chunk_extension? %set_chunk; last_chunk = '0'+ chunk_extension? eol trailer; -main := eol (chunk $0 | last_chunk @1) eol @accepted; +main := eol (chunk $0 | last_chunk @1) eol @accepted; }%% diff --git a/library/cpp/http/fetch/httpfsm_ut.cpp b/library/cpp/http/fetch/httpfsm_ut.cpp index 3320a850d0..b018e80101 100644 --- a/library/cpp/http/fetch/httpfsm_ut.cpp +++ b/library/cpp/http/fetch/httpfsm_ut.cpp @@ -5,7 +5,7 @@ #include <util/generic/ptr.h> #include <library/cpp/charset/doccodes.h> #include <library/cpp/testing/unittest/registar.h> - + class THttpHeaderParserTestSuite: public TTestBase { UNIT_TEST_SUITE(THttpHeaderParserTestSuite); UNIT_TEST(TestRequestHeader); @@ -63,10 +63,10 @@ public: void TestMimeType(); void TestRepeatedContentEncoding(); }; - + void THttpHeaderParserTestSuite::TestStart() { httpHeaderParser.Reset(new THttpHeaderParser()); -} +} void THttpHeaderParserTestSuite::TestFinish() { httpHeaderParser.Reset(); diff --git a/library/cpp/http/fetch/ya.make b/library/cpp/http/fetch/ya.make index 8f2db959d1..7737127463 100644 --- a/library/cpp/http/fetch/ya.make +++ b/library/cpp/http/fetch/ya.make @@ -20,7 +20,7 @@ SRCS( httpheader.cpp httpload.cpp exthttpcodes.cpp - httpfsm.rl6 + httpfsm.rl6 httpagent.h httpfetcher.h httpheader.h diff --git a/library/cpp/http/misc/httpdate.cpp b/library/cpp/http/misc/httpdate.cpp index d0754d2001..4a3031bbf4 100644 --- a/library/cpp/http/misc/httpdate.cpp +++ b/library/cpp/http/misc/httpdate.cpp @@ -36,9 +36,9 @@ #include <ctime> #include <util/system/compat.h> /* stricmp */ -#include <util/system/yassert.h> +#include <util/system/yassert.h> #include "httpdate.h" -#include <util/datetime/base.h> +#include <util/datetime/base.h> static const char *wkdays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" diff --git a/library/cpp/http/misc/httpdate.h b/library/cpp/http/misc/httpdate.h index 9b839223d5..04876f38fe 100644 --- a/library/cpp/http/misc/httpdate.h +++ b/library/cpp/http/misc/httpdate.h @@ -8,13 +8,13 @@ #define BAD_DATE ((time_t)-1) inline time_t parse_http_date(const TStringBuf& datestring) { - try { + try { return TInstant::ParseHttpDeprecated(datestring).TimeT(); - } catch (const TDateTimeParseException&) { - return BAD_DATE; - } -} - + } catch (const TDateTimeParseException&) { + return BAD_DATE; + } +} + int format_http_date(char buf[], size_t size, time_t when); char* format_http_date(time_t when, char* buf, size_t len); diff --git a/library/cpp/http/misc/httpreqdata.h b/library/cpp/http/misc/httpreqdata.h index a273399859..16e59c4d78 100644 --- a/library/cpp/http/misc/httpreqdata.h +++ b/library/cpp/http/misc/httpreqdata.h @@ -12,7 +12,7 @@ #include <util/generic/hash.h> #include <util/system/yassert.h> #include <util/generic/string.h> -#include <util/datetime/base.h> +#include <util/datetime/base.h> #include <util/generic/buffer.h> using THttpHeadersContainer = THashMap<TString, TString, TCIOps, TCIOps>; diff --git a/library/cpp/http/server/http.cpp b/library/cpp/http/server/http.cpp index 4ef72ad921..128583bdd7 100644 --- a/library/cpp/http/server/http.cpp +++ b/library/cpp/http/server/http.cpp @@ -42,7 +42,7 @@ namespace { struct TShouldStop { }; - + struct TWakeupPollAble: public IPollAble { void OnPollEvent(TInstant) override { throw TShouldStop(); @@ -187,14 +187,14 @@ public: // Start the listener thread ListenerRunningOK = false; - // throws on error - TPipeHandle::Pipe(ListenWakeupReadFd, ListenWakeupWriteFd); - - SetNonBlock(ListenWakeupWriteFd, true); - SetNonBlock(ListenWakeupReadFd, true); - - Poller->WaitRead(ListenWakeupReadFd, &WakeupPollAble); - + // throws on error + TPipeHandle::Pipe(ListenWakeupReadFd, ListenWakeupWriteFd); + + SetNonBlock(ListenWakeupWriteFd, true); + SetNonBlock(ListenWakeupReadFd, true); + + Poller->WaitRead(ListenWakeupReadFd, &WakeupPollAble); + ListenStartEvent.Reset(); try { ListenThread.Reset(new TThread(ListenSocketFunction, this)); @@ -220,8 +220,8 @@ public: } void Stop() { - Shutdown(); - + Shutdown(); + TGuard<TMutex> g(StopMutex); if (ListenThread) { ListenThread->Join(); @@ -238,8 +238,8 @@ public: } void Shutdown() { - ListenWakeupWriteFd.Write("", 1); - // ignore result + ListenWakeupWriteFd.Write("", 1); + // ignore result } void AddRequest(TAutoPtr<TClientRequest> req, bool fail) { @@ -443,8 +443,8 @@ public: } THolder<TThread> ListenThread; - TPipeHandle ListenWakeupReadFd; - TPipeHandle ListenWakeupWriteFd; + TPipeHandle ListenWakeupReadFd; + TPipeHandle ListenWakeupWriteFd; TSystemEvent ListenStartEvent; TMtpQueueRef Requests; TMtpQueueRef FailRequests; diff --git a/library/cpp/lfalloc/ya.make b/library/cpp/lfalloc/ya.make index 0ac987b52e..cace05f9d8 100644 --- a/library/cpp/lfalloc/ya.make +++ b/library/cpp/lfalloc/ya.make @@ -16,10 +16,10 @@ ELSE() ) ENDIF() -PEERDIR( +PEERDIR( library/cpp/malloc/api -) - +) + SET(IDE_FOLDER "util") END() diff --git a/library/cpp/lfalloc/yt/ya.make b/library/cpp/lfalloc/yt/ya.make index ddd657d2ab..8c1a4f8a72 100644 --- a/library/cpp/lfalloc/yt/ya.make +++ b/library/cpp/lfalloc/yt/ya.make @@ -20,10 +20,10 @@ ELSE() ) ENDIF() -PEERDIR( +PEERDIR( library/cpp/malloc/api -) - +) + SET(IDE_FOLDER "util") END() diff --git a/library/cpp/lwtrace/all.h b/library/cpp/lwtrace/all.h index 0b286ceb95..d7aa57c49d 100644 --- a/library/cpp/lwtrace/all.h +++ b/library/cpp/lwtrace/all.h @@ -4,7 +4,7 @@ #include "event.h" #include "preprocessor.h" #include "probe.h" -#include "start.h" +#include "start.h" // // Full documentation: https://wiki.yandex-team.ru/development/poisk/arcadia/library/lwtrace/ diff --git a/library/cpp/lwtrace/kill_action.cpp b/library/cpp/lwtrace/kill_action.cpp index cd3316e90d..2b74dc4587 100644 --- a/library/cpp/lwtrace/kill_action.cpp +++ b/library/cpp/lwtrace/kill_action.cpp @@ -1,21 +1,21 @@ #include "kill_action.h" - -#ifndef _win_ -#include <sys/types.h> -#include <signal.h> -#endif - + +#ifndef _win_ +#include <sys/types.h> +#include <signal.h> +#endif + #include <stdlib.h> - -using namespace NLWTrace; -using namespace NLWTrace::NPrivate; - + +using namespace NLWTrace; +using namespace NLWTrace::NPrivate; + bool TKillActionExecutor::DoExecute(TOrbit&, const TParams&) { -#ifdef _win_ - abort(); -#else - int r = kill(getpid(), SIGABRT); +#ifdef _win_ + abort(); +#else + int r = kill(getpid(), SIGABRT); Y_VERIFY(r == 0, "kill failed"); return true; -#endif -} +#endif +} diff --git a/library/cpp/lwtrace/kill_action.h b/library/cpp/lwtrace/kill_action.h index 16cc6b1a76..14da9ffd50 100644 --- a/library/cpp/lwtrace/kill_action.h +++ b/library/cpp/lwtrace/kill_action.h @@ -1,7 +1,7 @@ -#pragma once - -#include "probe.h" - +#pragma once + +#include "probe.h" + namespace NLWTrace { namespace NPrivate { class TKillActionExecutor: public IExecutor { @@ -10,6 +10,6 @@ namespace NLWTrace { } bool DoExecute(TOrbit& orbit, const TParams& params) override; }; - + } } diff --git a/library/cpp/lwtrace/preprocessor.h b/library/cpp/lwtrace/preprocessor.h index ca6559aac8..40865467b2 100644 --- a/library/cpp/lwtrace/preprocessor.h +++ b/library/cpp/lwtrace/preprocessor.h @@ -3,18 +3,18 @@ #include "check.h" #include "perf.h" #include "symbol.h" - + #include <util/generic/hide_ptr.h> #include <util/system/platform.h> #include <stddef.h> //size_t -#ifdef _win_ -#ifndef LWTRACE_DISABLE -#define LWTRACE_DISABLE -#endif // LWTRACE_DISABLE -#endif // _win_ - +#ifdef _win_ +#ifndef LWTRACE_DISABLE +#define LWTRACE_DISABLE +#endif // LWTRACE_DISABLE +#endif // _win_ + // Maximum number of executors that can be attached to a probe #define LWTRACE_MAX_ACTIONS 100 diff --git a/library/cpp/lwtrace/protos/lwtrace.proto b/library/cpp/lwtrace/protos/lwtrace.proto index 74890b1952..0051095719 100644 --- a/library/cpp/lwtrace/protos/lwtrace.proto +++ b/library/cpp/lwtrace/protos/lwtrace.proto @@ -44,9 +44,9 @@ message TLogAction { uint32 MaxRecords = 4; // Do not write more than MaxRecords records to the log (count from the trace beginning, not start) } -message TPrintToStderrAction { -} - +message TPrintToStderrAction { +} + message TKillAction { } diff --git a/library/cpp/lwtrace/protos/ya.make b/library/cpp/lwtrace/protos/ya.make index 1b9fd06c75..503d5e515f 100644 --- a/library/cpp/lwtrace/protos/ya.make +++ b/library/cpp/lwtrace/protos/ya.make @@ -5,7 +5,7 @@ OWNER(serxa) INCLUDE_TAGS(GO_PROTO) SRCS( - lwtrace.proto + lwtrace.proto ) END() diff --git a/library/cpp/lwtrace/start.cpp b/library/cpp/lwtrace/start.cpp index 1dd231ccea..121d5472b6 100644 --- a/library/cpp/lwtrace/start.cpp +++ b/library/cpp/lwtrace/start.cpp @@ -1,19 +1,19 @@ #include "start.h" - + #include "all.h" #include <google/protobuf/text_format.h> - -#include <util/generic/singleton.h> -#include <util/stream/file.h> + +#include <util/generic/singleton.h> +#include <util/stream/file.h> #include <util/stream/output.h> #include <util/system/env.h> - + #include <stdlib.h> - -using namespace NLWTrace; - -namespace { + +using namespace NLWTrace; + +namespace { struct TTraceManagerHolder { TManager TraceManager; TTraceManagerHolder() @@ -42,16 +42,16 @@ void NLWTrace::StartLwtraceFromEnv() { TString path = GetEnv("LWTRACE"); if (!path) { - return; - } - - try { + return; + } + + try { TraceFromEnv(path); - } catch (...) { - Cerr << "failed to load lwtrace script: " << CurrentExceptionMessage() << "\n"; - abort(); - } -} + } catch (...) { + Cerr << "failed to load lwtrace script: " << CurrentExceptionMessage() << "\n"; + abort(); + } +} void NLWTrace::StartLwtraceFromEnv(std::function<void(TManager&)> prepare) { TString path = GetEnv("LWTRACE"); diff --git a/library/cpp/lwtrace/start.h b/library/cpp/lwtrace/start.h index 4c360f4625..2755212bff 100644 --- a/library/cpp/lwtrace/start.h +++ b/library/cpp/lwtrace/start.h @@ -1,11 +1,11 @@ -#pragma once - +#pragma once + #include <functional> -namespace NLWTrace { +namespace NLWTrace { class TManager; - + void StartLwtraceFromEnv(); void StartLwtraceFromEnv(std::function<void(TManager&)> prepare); - -} + +} diff --git a/library/cpp/lwtrace/stderr_writer.cpp b/library/cpp/lwtrace/stderr_writer.cpp index 8d635d42f6..6e5654c338 100644 --- a/library/cpp/lwtrace/stderr_writer.cpp +++ b/library/cpp/lwtrace/stderr_writer.cpp @@ -1,19 +1,19 @@ -#include "stderr_writer.h" +#include "stderr_writer.h" #include <util/stream/str.h> - -using namespace NLWTrace; - + +using namespace NLWTrace; + bool TStderrActionExecutor::DoExecute(TOrbit&, const TParams& params) { TString ParamValues[LWTRACE_MAX_PARAMS]; - Probe->Event.Signature.SerializeParams(params, ParamValues); - + Probe->Event.Signature.SerializeParams(params, ParamValues); + TStringStream ss; ss << Probe->Event.GetProvider() << "." << Probe->Event.Name; - for (ui32 i = 0; i < Probe->Event.Signature.ParamCount; ++i) { + for (ui32 i = 0; i < Probe->Event.Signature.ParamCount; ++i) { ss << " " << Probe->Event.Signature.ParamNames[i] << "=" << ParamValues[i]; - } + } ss << "\n"; Cerr << ss.Str(); - return true; -} + return true; +} diff --git a/library/cpp/lwtrace/stderr_writer.h b/library/cpp/lwtrace/stderr_writer.h index b1375cbd27..b17fc3136e 100644 --- a/library/cpp/lwtrace/stderr_writer.h +++ b/library/cpp/lwtrace/stderr_writer.h @@ -1,19 +1,19 @@ -#pragma once - -#include "probe.h" - -namespace NLWTrace { +#pragma once + +#include "probe.h" + +namespace NLWTrace { class TStderrActionExecutor: public IExecutor { private: TProbe* const Probe; - + public: explicit TStderrActionExecutor(TProbe* probe) : Probe(probe) { } - + bool DoExecute(TOrbit& orbit, const TParams& params) override; }; -} +} diff --git a/library/cpp/lwtrace/ya.make b/library/cpp/lwtrace/ya.make index fb7b59629b..d9accb3006 100644 --- a/library/cpp/lwtrace/ya.make +++ b/library/cpp/lwtrace/ya.make @@ -10,7 +10,7 @@ SRCS( check.cpp control.cpp custom_action.cpp - kill_action.cpp + kill_action.cpp log_shuttle.cpp perf.cpp probes.cpp diff --git a/library/cpp/malloc/api/malloc.cpp b/library/cpp/malloc/api/malloc.cpp index 6f646033b7..eed1c58a38 100644 --- a/library/cpp/malloc/api/malloc.cpp +++ b/library/cpp/malloc/api/malloc.cpp @@ -1,8 +1,8 @@ #include <stdlib.h> #include <stdio.h> -#include "malloc.h" - +#include "malloc.h" + namespace { bool SetEmptyParam(const char*, const char*) { return false; diff --git a/library/cpp/malloc/api/malloc.h b/library/cpp/malloc/api/malloc.h index 3185cb3769..ebd545d6dd 100644 --- a/library/cpp/malloc/api/malloc.h +++ b/library/cpp/malloc/api/malloc.h @@ -1,25 +1,25 @@ -#pragma once - +#pragma once + #include <string.h> #include <util/system/compiler.h> -namespace NMalloc { - struct TMallocInfo { - TMallocInfo(); +namespace NMalloc { + struct TMallocInfo { + TMallocInfo(); - const char* Name; + const char* Name; bool (*SetParam)(const char* param, const char* value); const char* (*GetParam)(const char* param); bool (*CheckParam)(const char* param, bool defaultValue); - }; - + }; + extern volatile bool IsAllocatorCorrupted; void AbortFromCorruptedAllocator(const char* errorMessage = nullptr); - // this function should be implemented by malloc implementations - TMallocInfo MallocInfo(); + // this function should be implemented by malloc implementations + TMallocInfo MallocInfo(); struct TAllocHeader { void* Block; @@ -29,4 +29,4 @@ namespace NMalloc { AllocSize = size | signature; } }; -} +} diff --git a/library/cpp/malloc/api/ut/ut.cpp b/library/cpp/malloc/api/ut/ut.cpp index d806b6f637..7eccd0bf8d 100644 --- a/library/cpp/malloc/api/ut/ut.cpp +++ b/library/cpp/malloc/api/ut/ut.cpp @@ -1,10 +1,10 @@ #include <library/cpp/testing/unittest/registar.h> - + #include <library/cpp/malloc/api/malloc.h> - + Y_UNIT_TEST_SUITE(MallocApi) { Y_UNIT_TEST(ToStream) { - TStringStream ss; - ss << NMalloc::MallocInfo(); - } -} + TStringStream ss; + ss << NMalloc::MallocInfo(); + } +} diff --git a/library/cpp/malloc/api/ut/ya.make b/library/cpp/malloc/api/ut/ya.make index 8ce4ce20cf..e57225b45d 100644 --- a/library/cpp/malloc/api/ut/ya.make +++ b/library/cpp/malloc/api/ut/ya.make @@ -1,13 +1,13 @@ UNITTEST() - -OWNER(nga) - + +OWNER(nga) + PEERDIR( library/cpp/malloc/api/helpers ) -SRCS( - ut.cpp -) - -END() +SRCS( + ut.cpp +) + +END() diff --git a/library/cpp/malloc/api/ya.make b/library/cpp/malloc/api/ya.make index fdf6c294ea..0ebaa0c589 100644 --- a/library/cpp/malloc/api/ya.make +++ b/library/cpp/malloc/api/ya.make @@ -1,11 +1,11 @@ -LIBRARY() - +LIBRARY() + NO_UTIL() - -OWNER(nga) - -SRCS( - malloc.cpp -) - -END() + +OWNER(nga) + +SRCS( + malloc.cpp +) + +END() diff --git a/library/cpp/malloc/jemalloc/malloc-info.cpp b/library/cpp/malloc/jemalloc/malloc-info.cpp index 060cce9fa9..2643ca4766 100644 --- a/library/cpp/malloc/jemalloc/malloc-info.cpp +++ b/library/cpp/malloc/jemalloc/malloc-info.cpp @@ -1,5 +1,5 @@ #include <library/cpp/malloc/api/malloc.h> - + using namespace NMalloc; #if defined(_MSC_VER) @@ -12,7 +12,7 @@ TMallocInfo NMalloc::MallocInfo() { #include <strings.h> #include <stdlib.h> #include <inttypes.h> - + #include <contrib/libs/jemalloc/include/jemalloc/jemalloc.h> namespace { @@ -55,11 +55,11 @@ namespace { } } -TMallocInfo NMalloc::MallocInfo() { - TMallocInfo r; - r.Name = "jemalloc"; +TMallocInfo NMalloc::MallocInfo() { + TMallocInfo r; + r.Name = "jemalloc"; r.SetParam = JESetParam; r.GetParam = JEGetParam; - return r; -} + return r; +} #endif diff --git a/library/cpp/malloc/jemalloc/ya.make b/library/cpp/malloc/jemalloc/ya.make index 0398578d6c..99db474eab 100644 --- a/library/cpp/malloc/jemalloc/ya.make +++ b/library/cpp/malloc/jemalloc/ya.make @@ -1,9 +1,9 @@ -LIBRARY() - +LIBRARY() + NO_UTIL() - -OWNER(nga) - + +OWNER(nga) + IF (OS_ANDROID) PEERDIR( library/cpp/malloc/system @@ -17,5 +17,5 @@ ELSE() malloc-info.cpp ) ENDIF() - -END() + +END() diff --git a/library/cpp/malloc/ya.make b/library/cpp/malloc/ya.make index 045d1e24f2..0ec9db71d2 100644 --- a/library/cpp/malloc/ya.make +++ b/library/cpp/malloc/ya.make @@ -1,4 +1,4 @@ -RECURSE( +RECURSE( api api/helpers api/ut @@ -13,7 +13,7 @@ RECURSE( mimalloc/link_test hu hu/link_test -) +) IF (NOT OS_WINDOWS) RECURSE( diff --git a/library/cpp/messagebus/acceptor.cpp b/library/cpp/messagebus/acceptor.cpp index d54be57fd9..64a38619c2 100644 --- a/library/cpp/messagebus/acceptor.cpp +++ b/library/cpp/messagebus/acceptor.cpp @@ -1,127 +1,127 @@ #include "acceptor.h" - -#include "key_value_printer.h" -#include "mb_lwtrace.h" + +#include "key_value_printer.h" +#include "mb_lwtrace.h" #include "network.h" - + #include <util/network/init.h> #include <util/system/defaults.h> #include <util/system/error.h> #include <util/system/yassert.h> - -LWTRACE_USING(LWTRACE_MESSAGEBUS_PROVIDER) - -using namespace NActor; -using namespace NBus; -using namespace NBus::NPrivate; - -TAcceptor::TAcceptor(TBusSessionImpl* session, ui64 acceptorId, SOCKET socket, const TNetAddr& addr) - : TActor<TAcceptor>(session->Queue->WorkQueue.Get()) - , AcceptorId(acceptorId) - , Session(session) + +LWTRACE_USING(LWTRACE_MESSAGEBUS_PROVIDER) + +using namespace NActor; +using namespace NBus; +using namespace NBus::NPrivate; + +TAcceptor::TAcceptor(TBusSessionImpl* session, ui64 acceptorId, SOCKET socket, const TNetAddr& addr) + : TActor<TAcceptor>(session->Queue->WorkQueue.Get()) + , AcceptorId(acceptorId) + , Session(session) , GranStatus(session->Config.Secret.StatusFlushPeriod) -{ - SetNonBlock(socket, true); - - Channel = Session->ReadEventLoop.Register(socket, this); - Channel->EnableRead(); - - Stats.AcceptorId = acceptorId; - Stats.Fd = socket; - Stats.ListenAddr = addr; - +{ + SetNonBlock(socket, true); + + Channel = Session->ReadEventLoop.Register(socket, this); + Channel->EnableRead(); + + Stats.AcceptorId = acceptorId; + Stats.Fd = socket; + Stats.ListenAddr = addr; + SendStatus(TInstant::Now()); -} - -void TAcceptor::Act(TDefaultTag) { - EShutdownState state = ShutdownState.State.Get(); - - if (state == SS_SHUTDOWN_COMPLETE) { - return; - } - +} + +void TAcceptor::Act(TDefaultTag) { + EShutdownState state = ShutdownState.State.Get(); + + if (state == SS_SHUTDOWN_COMPLETE) { + return; + } + TInstant now = TInstant::Now(); - if (state == SS_SHUTDOWN_COMMAND) { - if (!!Channel) { - Channel->Unregister(); - Channel.Drop(); - Stats.Fd = INVALID_SOCKET; - } - + if (state == SS_SHUTDOWN_COMMAND) { + if (!!Channel) { + Channel->Unregister(); + Channel.Drop(); + Stats.Fd = INVALID_SOCKET; + } + SendStatus(now); - - Session->GetDeadAcceptorStatusQueue()->EnqueueAndSchedule(Stats); - Stats.ResetIncremental(); - - ShutdownState.CompleteShutdown(); - return; - } - - THolder<TOpaqueAddr> addr(new TOpaqueAddr()); - SOCKET acceptedSocket = accept(Channel->GetSocket(), addr->MutableAddr(), addr->LenPtr()); - - int acceptErrno = LastSystemError(); - - if (acceptedSocket == INVALID_SOCKET) { - if (LastSystemError() != EWOULDBLOCK) { - Stats.LastAcceptErrorErrno = acceptErrno; - Stats.LastAcceptErrorInstant = now; - ++Stats.AcceptErrorCount; - } - } else { - TSocketHolder s(acceptedSocket); - try { - SetKeepAlive(s, true); - SetNoDelay(s, Session->Config.TcpNoDelay); - SetSockOptTcpCork(s, Session->Config.TcpCork); - SetCloseOnExec(s, true); - SetNonBlock(s, true); + + Session->GetDeadAcceptorStatusQueue()->EnqueueAndSchedule(Stats); + Stats.ResetIncremental(); + + ShutdownState.CompleteShutdown(); + return; + } + + THolder<TOpaqueAddr> addr(new TOpaqueAddr()); + SOCKET acceptedSocket = accept(Channel->GetSocket(), addr->MutableAddr(), addr->LenPtr()); + + int acceptErrno = LastSystemError(); + + if (acceptedSocket == INVALID_SOCKET) { + if (LastSystemError() != EWOULDBLOCK) { + Stats.LastAcceptErrorErrno = acceptErrno; + Stats.LastAcceptErrorInstant = now; + ++Stats.AcceptErrorCount; + } + } else { + TSocketHolder s(acceptedSocket); + try { + SetKeepAlive(s, true); + SetNoDelay(s, Session->Config.TcpNoDelay); + SetSockOptTcpCork(s, Session->Config.TcpCork); + SetCloseOnExec(s, true); + SetNonBlock(s, true); if (Session->Config.SocketToS >= 0) { SetSocketToS(s, addr.Get(), Session->Config.SocketToS); } - } catch (...) { - // It means that connection was reset just now - // TODO: do something better - goto skipAccept; - } - - { - TOnAccept onAccept; - onAccept.s = s.Release(); - onAccept.addr = TNetAddr(addr.Release()); - onAccept.now = now; - - LWPROBE(Accepted, ToString(onAccept.addr)); - - Session->GetOnAcceptQueue()->EnqueueAndSchedule(onAccept); - + } catch (...) { + // It means that connection was reset just now + // TODO: do something better + goto skipAccept; + } + + { + TOnAccept onAccept; + onAccept.s = s.Release(); + onAccept.addr = TNetAddr(addr.Release()); + onAccept.now = now; + + LWPROBE(Accepted, ToString(onAccept.addr)); + + Session->GetOnAcceptQueue()->EnqueueAndSchedule(onAccept); + Stats.LastAcceptSuccessInstant = now; - ++Stats.AcceptSuccessCount; - } - + ++Stats.AcceptSuccessCount; + } + skipAccept:; - } - - Channel->EnableRead(); - + } + + Channel->EnableRead(); + SendStatus(now); -} - +} + void TAcceptor::SendStatus(TInstant now) { GranStatus.Listen.Update(Stats, now); -} - -void TAcceptor::HandleEvent(SOCKET socket, void* cookie) { +} + +void TAcceptor::HandleEvent(SOCKET socket, void* cookie) { Y_UNUSED(socket); Y_UNUSED(cookie); - - GetActor()->Schedule(); -} - -void TAcceptor::Shutdown() { - ShutdownState.ShutdownCommand(); - GetActor()->Schedule(); - - ShutdownState.ShutdownComplete.WaitI(); -} + + GetActor()->Schedule(); +} + +void TAcceptor::Shutdown() { + ShutdownState.ShutdownCommand(); + GetActor()->Schedule(); + + ShutdownState.ShutdownComplete.WaitI(); +} diff --git a/library/cpp/messagebus/acceptor.h b/library/cpp/messagebus/acceptor.h index 602381839e..57cb010bf2 100644 --- a/library/cpp/messagebus/acceptor.h +++ b/library/cpp/messagebus/acceptor.h @@ -1,12 +1,12 @@ -#pragma once - +#pragma once + #include "acceptor_status.h" #include "defs.h" -#include "event_loop.h" -#include "netaddr.h" -#include "session_impl.h" -#include "shutdown_state.h" - +#include "event_loop.h" +#include "netaddr.h" +#include "session_impl.h" +#include "shutdown_state.h" + #include <library/cpp/messagebus/actor/actor.h> #include <util/system/event.h> @@ -18,43 +18,43 @@ namespace NBus { private ::NActor::TActor<TAcceptor> { friend struct TBusSessionImpl; friend class ::NActor::TActor<TAcceptor>; - + public: TAcceptor(TBusSessionImpl* session, ui64 acceptorId, SOCKET socket, const TNetAddr& addr); - + void HandleEvent(SOCKET socket, void* cookie) override; - + void Shutdown(); - + inline ::NActor::TActor<TAcceptor>* GetActor() { return this; } - + private: void SendStatus(TInstant now); void Act(::NActor::TDefaultTag); - + private: const ui64 AcceptorId; - + TBusSessionImpl* const Session; NEventLoop::TChannelPtr Channel; - + TAcceptorStatus Stats; - + TAtomicShutdownState ShutdownState; - + struct TGranStatus { TGranStatus(TDuration gran) : Listen(gran) { } - + TGranUp<TAcceptorStatus> Listen; }; - + TGranStatus GranStatus; - }; + }; } } diff --git a/library/cpp/messagebus/acceptor_status.cpp b/library/cpp/messagebus/acceptor_status.cpp index 3b0725a46b..5006ff68ae 100644 --- a/library/cpp/messagebus/acceptor_status.cpp +++ b/library/cpp/messagebus/acceptor_status.cpp @@ -1,68 +1,68 @@ #include "acceptor_status.h" - -#include "key_value_printer.h" - + +#include "key_value_printer.h" + #include <util/stream/format.h> #include <util/stream/output.h> - -using namespace NBus; -using namespace NBus::NPrivate; - -TAcceptorStatus::TAcceptorStatus() - : Summary(false) - , AcceptorId(0) - , Fd(INVALID_SOCKET) -{ - ResetIncremental(); -} - -void TAcceptorStatus::ResetIncremental() { - AcceptSuccessCount = 0; - AcceptErrorCount = 0; - LastAcceptErrorErrno = 0; - LastAcceptErrorInstant = TInstant(); - LastAcceptSuccessInstant = TInstant(); -} - -TAcceptorStatus& TAcceptorStatus::operator+=(const TAcceptorStatus& that) { + +using namespace NBus; +using namespace NBus::NPrivate; + +TAcceptorStatus::TAcceptorStatus() + : Summary(false) + , AcceptorId(0) + , Fd(INVALID_SOCKET) +{ + ResetIncremental(); +} + +void TAcceptorStatus::ResetIncremental() { + AcceptSuccessCount = 0; + AcceptErrorCount = 0; + LastAcceptErrorErrno = 0; + LastAcceptErrorInstant = TInstant(); + LastAcceptSuccessInstant = TInstant(); +} + +TAcceptorStatus& TAcceptorStatus::operator+=(const TAcceptorStatus& that) { Y_ASSERT(Summary); Y_ASSERT(AcceptorId == 0); - - AcceptSuccessCount += that.AcceptSuccessCount; - LastAcceptSuccessInstant = Max(LastAcceptSuccessInstant, that.LastAcceptSuccessInstant); - - AcceptErrorCount += that.AcceptErrorCount; - if (that.LastAcceptErrorInstant > LastAcceptErrorInstant) { - LastAcceptErrorInstant = that.LastAcceptErrorInstant; - LastAcceptErrorErrno = that.LastAcceptErrorErrno; - } - - return *this; -} - + + AcceptSuccessCount += that.AcceptSuccessCount; + LastAcceptSuccessInstant = Max(LastAcceptSuccessInstant, that.LastAcceptSuccessInstant); + + AcceptErrorCount += that.AcceptErrorCount; + if (that.LastAcceptErrorInstant > LastAcceptErrorInstant) { + LastAcceptErrorInstant = that.LastAcceptErrorInstant; + LastAcceptErrorErrno = that.LastAcceptErrorErrno; + } + + return *this; +} + TString TAcceptorStatus::PrintToString() const { - TStringStream ss; - - if (!Summary) { - ss << "acceptor (" << AcceptorId << "), fd=" << Fd << ", addr=" << ListenAddr << Endl; - } - - TKeyValuePrinter p; - - p.AddRow("accept error count", LeftPad(AcceptErrorCount, 4)); - - if (AcceptErrorCount > 0) { - p.AddRow("last accept error", + TStringStream ss; + + if (!Summary) { + ss << "acceptor (" << AcceptorId << "), fd=" << Fd << ", addr=" << ListenAddr << Endl; + } + + TKeyValuePrinter p; + + p.AddRow("accept error count", LeftPad(AcceptErrorCount, 4)); + + if (AcceptErrorCount > 0) { + p.AddRow("last accept error", TString() + LastSystemErrorText(LastAcceptErrorErrno) + " at " + LastAcceptErrorInstant.ToString()); - } - - p.AddRow("accept success count", LeftPad(AcceptSuccessCount, 4)); - if (AcceptSuccessCount > 0) { - p.AddRow("last accept success", + } + + p.AddRow("accept success count", LeftPad(AcceptSuccessCount, 4)); + if (AcceptSuccessCount > 0) { + p.AddRow("last accept success", TString() + "at " + LastAcceptSuccessInstant.ToString()); - } - - ss << p.PrintToString(); - - return ss.Str(); -} + } + + ss << p.PrintToString(); + + return ss.Str(); +} diff --git a/library/cpp/messagebus/acceptor_status.h b/library/cpp/messagebus/acceptor_status.h index 40be70107d..6aa1404f4d 100644 --- a/library/cpp/messagebus/acceptor_status.h +++ b/library/cpp/messagebus/acceptor_status.h @@ -1,35 +1,35 @@ -#pragma once - +#pragma once + #include "netaddr.h" -#include <util/network/init.h> - +#include <util/network/init.h> + namespace NBus { namespace NPrivate { struct TAcceptorStatus { bool Summary; - + ui64 AcceptorId; - + SOCKET Fd; - + TNetAddr ListenAddr; - + unsigned AcceptSuccessCount; TInstant LastAcceptSuccessInstant; - + unsigned AcceptErrorCount; TInstant LastAcceptErrorInstant; int LastAcceptErrorErrno; - + void ResetIncremental(); - + TAcceptorStatus(); - + TAcceptorStatus& operator+=(const TAcceptorStatus& that); - + TString PrintToString() const; }; - + } } diff --git a/library/cpp/messagebus/actor/actor.h b/library/cpp/messagebus/actor/actor.h index 6c05d474ae..9b8f20298a 100644 --- a/library/cpp/messagebus/actor/actor.h +++ b/library/cpp/messagebus/actor/actor.h @@ -1,100 +1,100 @@ -#pragma once - +#pragma once + #include "executor.h" -#include "tasks.h" -#include "what_thread_does.h" - +#include "tasks.h" +#include "what_thread_does.h" + #include <util/system/yassert.h> -namespace NActor { +namespace NActor { class IActor: protected IWorkItem { public: // TODO: make private TTasks Tasks; - + public: virtual void ScheduleHereV() = 0; virtual void ScheduleV() = 0; virtual void ScheduleHereAtMostOnceV() = 0; - + // TODO: make private virtual void RefV() = 0; virtual void UnRefV() = 0; - + // mute warnings ~IActor() override { } }; - + struct TDefaultTag {}; - + template <typename TThis, typename TTag = TDefaultTag> class TActor: public IActor { private: TExecutor* const Executor; - + public: TActor(TExecutor* executor) : Executor(executor) { } - + void AddTaskFromActorLoop() { bool schedule = Tasks.AddTask(); // TODO: check thread id Y_ASSERT(!schedule); } - + /** - * Schedule actor. - * - * If actor is sleeping, then actor will be executed right now. - * If actor is executing right now, it will be executed one more time. - * If this method is called multiple time, actor will be re-executed no more than one more time. - */ + * Schedule actor. + * + * If actor is sleeping, then actor will be executed right now. + * If actor is executing right now, it will be executed one more time. + * If this method is called multiple time, actor will be re-executed no more than one more time. + */ void Schedule() { if (Tasks.AddTask()) { EnqueueWork(); } - } - + } + /** - * Schedule actor, execute it in current thread. - * - * If actor is running, continue executing where it is executing. - * If actor is sleeping, execute it in current thread. - * - * Operation is useful for tasks that are likely to complete quickly. - */ + * Schedule actor, execute it in current thread. + * + * If actor is running, continue executing where it is executing. + * If actor is sleeping, execute it in current thread. + * + * Operation is useful for tasks that are likely to complete quickly. + */ void ScheduleHere() { if (Tasks.AddTask()) { Loop(); } - } - + } + /** - * Schedule actor, execute in current thread no more than once. - * - * If actor is running, continue executing where it is executing. - * If actor is sleeping, execute one iteration here, and if actor got new tasks, - * reschedule it in worker pool. - */ + * Schedule actor, execute in current thread no more than once. + * + * If actor is running, continue executing where it is executing. + * If actor is sleeping, execute one iteration here, and if actor got new tasks, + * reschedule it in worker pool. + */ void ScheduleHereAtMostOnce() { if (Tasks.AddTask()) { bool fetched = Tasks.FetchTask(); Y_VERIFY(fetched, "happens"); - + DoAct(); - + // if someone added more tasks, schedule them if (Tasks.FetchTask()) { bool added = Tasks.AddTask(); Y_VERIFY(!added, "happens"); EnqueueWork(); } - } - } - + } + } + void ScheduleHereV() override { ScheduleHere(); } @@ -110,35 +110,35 @@ namespace NActor { void UnRefV() override { GetThis()->UnRef(); } - + private: TThis* GetThis() { return static_cast<TThis*>(this); } - + void EnqueueWork() { GetThis()->Ref(); Executor->EnqueueWork({this}); } - + void DoAct() { WHAT_THREAD_DOES_PUSH_POP_CURRENT_FUNC(); - + GetThis()->Act(TTag()); } - + void Loop() { // TODO: limit number of iterations while (Tasks.FetchTask()) { DoAct(); } - } - + } + void DoWork() override { Y_ASSERT(GetThis()->RefCount() >= 1); Loop(); GetThis()->UnRef(); } }; - + } diff --git a/library/cpp/messagebus/actor/actor_ut.cpp b/library/cpp/messagebus/actor/actor_ut.cpp index 3f6d72ccdc..b76ab55bfa 100644 --- a/library/cpp/messagebus/actor/actor_ut.cpp +++ b/library/cpp/messagebus/actor/actor_ut.cpp @@ -1,157 +1,157 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "actor.h" -#include "queue_in_actor.h" - + +#include "actor.h" +#include "queue_in_actor.h" + #include <library/cpp/messagebus/misc/test_sync.h> #include <util/generic/object_counter.h> #include <util/system/event.h> -using namespace NActor; - -template <typename TThis> +using namespace NActor; + +template <typename TThis> struct TTestActorBase: public TAtomicRefCount<TThis>, public TActor<TThis> { - TTestSync Started; - TTestSync Acted; - - TTestActorBase(TExecutor* executor) - : TActor<TThis>(executor) + TTestSync Started; + TTestSync Acted; + + TTestActorBase(TExecutor* executor) + : TActor<TThis>(executor) { } - - void Act(TDefaultTag) { - Started.Inc(); - static_cast<TThis*>(this)->Act2(); - Acted.Inc(); - } -}; - + + void Act(TDefaultTag) { + Started.Inc(); + static_cast<TThis*>(this)->Act2(); + Acted.Inc(); + } +}; + struct TNopActor: public TTestActorBase<TNopActor> { - TObjectCounter<TNopActor> AllocCounter; - - TNopActor(TExecutor* executor) - : TTestActorBase<TNopActor>(executor) + TObjectCounter<TNopActor> AllocCounter; + + TNopActor(TExecutor* executor) + : TTestActorBase<TNopActor>(executor) { } - - void Act2() { - } -}; - + + void Act2() { + } +}; + struct TWaitForSignalActor: public TTestActorBase<TWaitForSignalActor> { - TWaitForSignalActor(TExecutor* executor) - : TTestActorBase<TWaitForSignalActor>(executor) + TWaitForSignalActor(TExecutor* executor) + : TTestActorBase<TWaitForSignalActor>(executor) { } - + TSystemEvent WaitFor; - - void Act2() { - WaitFor.Wait(); - } -}; - + + void Act2() { + WaitFor.Wait(); + } +}; + struct TDecrementAndSendActor: public TTestActorBase<TDecrementAndSendActor>, public TQueueInActor<TDecrementAndSendActor, int> { TSystemEvent Done; - - TDecrementAndSendActor* Next; - - TDecrementAndSendActor(TExecutor* executor) - : TTestActorBase<TDecrementAndSendActor>(executor) + + TDecrementAndSendActor* Next; + + TDecrementAndSendActor(TExecutor* executor) + : TTestActorBase<TDecrementAndSendActor>(executor) , Next(nullptr) { } - - void ProcessItem(TDefaultTag, TDefaultTag, int n) { - if (n == 0) { - Done.Signal(); - } else { - Next->EnqueueAndSchedule(n - 1); - } - } - - void Act(TDefaultTag) { - DequeueAll(); - } -}; - -struct TObjectCountChecker { - TObjectCountChecker() { - CheckCounts(); - } - - ~TObjectCountChecker() { - CheckCounts(); - } - - void CheckCounts() { - UNIT_ASSERT_VALUES_EQUAL(TAtomicBase(0), TObjectCounter<TNopActor>::ObjectCount()); - UNIT_ASSERT_VALUES_EQUAL(TAtomicBase(0), TObjectCounter<TWaitForSignalActor>::ObjectCount()); - UNIT_ASSERT_VALUES_EQUAL(TAtomicBase(0), TObjectCounter<TDecrementAndSendActor>::ObjectCount()); - } -}; - + + void ProcessItem(TDefaultTag, TDefaultTag, int n) { + if (n == 0) { + Done.Signal(); + } else { + Next->EnqueueAndSchedule(n - 1); + } + } + + void Act(TDefaultTag) { + DequeueAll(); + } +}; + +struct TObjectCountChecker { + TObjectCountChecker() { + CheckCounts(); + } + + ~TObjectCountChecker() { + CheckCounts(); + } + + void CheckCounts() { + UNIT_ASSERT_VALUES_EQUAL(TAtomicBase(0), TObjectCounter<TNopActor>::ObjectCount()); + UNIT_ASSERT_VALUES_EQUAL(TAtomicBase(0), TObjectCounter<TWaitForSignalActor>::ObjectCount()); + UNIT_ASSERT_VALUES_EQUAL(TAtomicBase(0), TObjectCounter<TDecrementAndSendActor>::ObjectCount()); + } +}; + Y_UNIT_TEST_SUITE(TActor) { Y_UNIT_TEST(Simple) { - TObjectCountChecker objectCountChecker; - - TExecutor executor(4); - - TIntrusivePtr<TNopActor> actor(new TNopActor(&executor)); - - actor->Schedule(); - - actor->Acted.WaitFor(1u); - } - + TObjectCountChecker objectCountChecker; + + TExecutor executor(4); + + TIntrusivePtr<TNopActor> actor(new TNopActor(&executor)); + + actor->Schedule(); + + actor->Acted.WaitFor(1u); + } + Y_UNIT_TEST(ScheduleAfterStart) { - TObjectCountChecker objectCountChecker; - - TExecutor executor(4); - - TIntrusivePtr<TWaitForSignalActor> actor(new TWaitForSignalActor(&executor)); - - actor->Schedule(); - - actor->Started.WaitFor(1); - - actor->Schedule(); - - actor->WaitFor.Signal(); - - // make sure Act is called second time - actor->Acted.WaitFor(2u); - } - - void ComplexImpl(int queueSize, int actorCount) { - TObjectCountChecker objectCountChecker; - - TExecutor executor(queueSize); - + TObjectCountChecker objectCountChecker; + + TExecutor executor(4); + + TIntrusivePtr<TWaitForSignalActor> actor(new TWaitForSignalActor(&executor)); + + actor->Schedule(); + + actor->Started.WaitFor(1); + + actor->Schedule(); + + actor->WaitFor.Signal(); + + // make sure Act is called second time + actor->Acted.WaitFor(2u); + } + + void ComplexImpl(int queueSize, int actorCount) { + TObjectCountChecker objectCountChecker; + + TExecutor executor(queueSize); + TVector<TIntrusivePtr<TDecrementAndSendActor>> actors; - for (int i = 0; i < actorCount; ++i) { - actors.push_back(new TDecrementAndSendActor(&executor)); - } - - for (int i = 0; i < actorCount; ++i) { - actors.at(i)->Next = &*actors.at((i + 1) % actorCount); - } - - for (int i = 0; i < actorCount; ++i) { - actors.at(i)->EnqueueAndSchedule(10000); - } - - for (int i = 0; i < actorCount; ++i) { - actors.at(i)->Done.WaitI(); - } - } - + for (int i = 0; i < actorCount; ++i) { + actors.push_back(new TDecrementAndSendActor(&executor)); + } + + for (int i = 0; i < actorCount; ++i) { + actors.at(i)->Next = &*actors.at((i + 1) % actorCount); + } + + for (int i = 0; i < actorCount; ++i) { + actors.at(i)->EnqueueAndSchedule(10000); + } + + for (int i = 0; i < actorCount; ++i) { + actors.at(i)->Done.WaitI(); + } + } + Y_UNIT_TEST(ComplexContention) { - ComplexImpl(4, 6); - } - + ComplexImpl(4, 6); + } + Y_UNIT_TEST(ComplexNoContention) { - ComplexImpl(6, 4); - } -} + ComplexImpl(6, 4); + } +} diff --git a/library/cpp/messagebus/actor/executor.cpp b/library/cpp/messagebus/actor/executor.cpp index fbd76a86ba..7a2227a458 100644 --- a/library/cpp/messagebus/actor/executor.cpp +++ b/library/cpp/messagebus/actor/executor.cpp @@ -1,95 +1,95 @@ #include "executor.h" - -#include "thread_extra.h" -#include "what_thread_does.h" -#include "what_thread_does_guard.h" - + +#include "thread_extra.h" +#include "what_thread_does.h" +#include "what_thread_does_guard.h" + #include <util/generic/utility.h> #include <util/random/random.h> #include <util/stream/str.h> #include <util/system/tls.h> #include <util/system/yassert.h> - + #include <array> -using namespace NActor; -using namespace NActor::NPrivate; - -namespace { - struct THistoryInternal { - struct TRecord { +using namespace NActor; +using namespace NActor::NPrivate; + +namespace { + struct THistoryInternal { + struct TRecord { TAtomic MaxQueueSize; - + TRecord() : MaxQueueSize() { } - - TExecutorHistory::THistoryRecord Capture() { - TExecutorHistory::THistoryRecord r; + + TExecutorHistory::THistoryRecord Capture() { + TExecutorHistory::THistoryRecord r; r.MaxQueueSize = AtomicGet(MaxQueueSize); - return r; - } - }; - - ui64 Start; - ui64 LastTime; - + return r; + } + }; + + ui64 Start; + ui64 LastTime; + std::array<TRecord, 3600> Records; - - THistoryInternal() { - Start = TInstant::Now().Seconds(); - LastTime = Start - 1; - } - - TRecord& GetRecordForTime(ui64 time) { - return Records[time % Records.size()]; - } - - TRecord& GetNowRecord(ui64 now) { - for (ui64 t = LastTime + 1; t <= now; ++t) { - GetRecordForTime(t) = TRecord(); - } - LastTime = now; - return GetRecordForTime(now); - } - - TExecutorHistory Capture() { - TExecutorHistory history; - ui64 now = TInstant::Now().Seconds(); - ui64 lastHistoryRecord = now - 1; - ui32 historySize = Min<ui32>(lastHistoryRecord - Start, Records.size() - 1); - history.HistoryRecords.resize(historySize); - for (ui32 i = 0; i < historySize; ++i) { - history.HistoryRecords[i] = GetRecordForTime(lastHistoryRecord - historySize + i).Capture(); - } - history.LastHistoryRecordSecond = lastHistoryRecord; - return history; - } - }; - -} - + + THistoryInternal() { + Start = TInstant::Now().Seconds(); + LastTime = Start - 1; + } + + TRecord& GetRecordForTime(ui64 time) { + return Records[time % Records.size()]; + } + + TRecord& GetNowRecord(ui64 now) { + for (ui64 t = LastTime + 1; t <= now; ++t) { + GetRecordForTime(t) = TRecord(); + } + LastTime = now; + return GetRecordForTime(now); + } + + TExecutorHistory Capture() { + TExecutorHistory history; + ui64 now = TInstant::Now().Seconds(); + ui64 lastHistoryRecord = now - 1; + ui32 historySize = Min<ui32>(lastHistoryRecord - Start, Records.size() - 1); + history.HistoryRecords.resize(historySize); + for (ui32 i = 0; i < historySize; ++i) { + history.HistoryRecords[i] = GetRecordForTime(lastHistoryRecord - historySize + i).Capture(); + } + history.LastHistoryRecordSecond = lastHistoryRecord; + return history; + } + }; + +} + Y_POD_STATIC_THREAD(TExecutor*) ThreadCurrentExecutor; - -static const char* NoLocation = "nowhere"; - -struct TExecutorWorkerThreadLocalData { - ui32 MaxQueueSize; -}; - -static TExecutorWorkerThreadLocalData WorkerNoThreadLocalData; + +static const char* NoLocation = "nowhere"; + +struct TExecutorWorkerThreadLocalData { + ui32 MaxQueueSize; +}; + +static TExecutorWorkerThreadLocalData WorkerNoThreadLocalData; Y_POD_STATIC_THREAD(TExecutorWorkerThreadLocalData) WorkerThreadLocalData; - -namespace NActor { + +namespace NActor { struct TExecutorWorker { TExecutor* const Executor; TThread Thread; const char** WhatThreadDoesLocation; TExecutorWorkerThreadLocalData* ThreadLocalData; - + TExecutorWorker(TExecutor* executor) : Executor(executor) , Thread(RunThreadProc, this) @@ -98,241 +98,241 @@ namespace NActor { { Thread.Start(); } - + void Run() { WhatThreadDoesLocation = ::WhatThreadDoesLocation(); AtomicSet(ThreadLocalData, &::WorkerThreadLocalData); WHAT_THREAD_DOES_PUSH_POP_CURRENT_FUNC(); Executor->RunWorker(); } - + static void* RunThreadProc(void* thiz0) { TExecutorWorker* thiz = (TExecutorWorker*)thiz0; thiz->Run(); return nullptr; } }; - + struct TExecutor::TImpl { TExecutor* const Executor; THistoryInternal History; - + TSystemEvent HelperStopSignal; TThread HelperThread; - + TImpl(TExecutor* executor) : Executor(executor) , HelperThread(HelperThreadProc, this) { } - + void RunHelper() { ui64 nowSeconds = TInstant::Now().Seconds(); for (;;) { TInstant nextStop = TInstant::Seconds(nowSeconds + 1) + TDuration::MilliSeconds(RandomNumber<ui32>(1000)); - + if (HelperStopSignal.WaitD(nextStop)) { return; } - + nowSeconds = nextStop.Seconds(); - + THistoryInternal::TRecord& record = History.GetNowRecord(nowSeconds); - + ui32 maxQueueSize = Executor->GetMaxQueueSizeAndClear(); if (maxQueueSize > record.MaxQueueSize) { AtomicSet(record.MaxQueueSize, maxQueueSize); } - } - } - + } + } + static void* HelperThreadProc(void* impl0) { TImpl* impl = (TImpl*)impl0; impl->RunHelper(); return nullptr; } }; - + +} + +static TExecutor::TConfig MakeConfig(unsigned workerCount) { + TExecutor::TConfig config; + config.WorkerCount = workerCount; + return config; +} + +TExecutor::TExecutor(size_t workerCount) + : Config(MakeConfig(workerCount)) +{ + Init(); +} + +TExecutor::TExecutor(const TExecutor::TConfig& config) + : Config(config) +{ + Init(); } - -static TExecutor::TConfig MakeConfig(unsigned workerCount) { - TExecutor::TConfig config; - config.WorkerCount = workerCount; - return config; -} - -TExecutor::TExecutor(size_t workerCount) - : Config(MakeConfig(workerCount)) -{ - Init(); -} - -TExecutor::TExecutor(const TExecutor::TConfig& config) - : Config(config) -{ - Init(); -} - -void TExecutor::Init() { - Impl.Reset(new TImpl(this)); - + +void TExecutor::Init() { + Impl.Reset(new TImpl(this)); + AtomicSet(ExitWorkers, 0); - + Y_VERIFY(Config.WorkerCount > 0); - - for (size_t i = 0; i < Config.WorkerCount; i++) { - WorkerThreads.push_back(new TExecutorWorker(this)); - } - - Impl->HelperThread.Start(); -} - -TExecutor::~TExecutor() { - Stop(); -} - -void TExecutor::Stop() { + + for (size_t i = 0; i < Config.WorkerCount; i++) { + WorkerThreads.push_back(new TExecutorWorker(this)); + } + + Impl->HelperThread.Start(); +} + +TExecutor::~TExecutor() { + Stop(); +} + +void TExecutor::Stop() { AtomicSet(ExitWorkers, 1); - - Impl->HelperStopSignal.Signal(); - Impl->HelperThread.Join(); - - { - TWhatThreadDoesAcquireGuard<TMutex> guard(WorkMutex, "executor: acquiring lock for Stop"); - WorkAvailable.BroadCast(); - } - - for (size_t i = 0; i < WorkerThreads.size(); i++) { - WorkerThreads[i]->Thread.Join(); - } - - // TODO: make queue empty at this point - ProcessWorkQueueHere(); -} - + + Impl->HelperStopSignal.Signal(); + Impl->HelperThread.Join(); + + { + TWhatThreadDoesAcquireGuard<TMutex> guard(WorkMutex, "executor: acquiring lock for Stop"); + WorkAvailable.BroadCast(); + } + + for (size_t i = 0; i < WorkerThreads.size(); i++) { + WorkerThreads[i]->Thread.Join(); + } + + // TODO: make queue empty at this point + ProcessWorkQueueHere(); +} + void TExecutor::EnqueueWork(TArrayRef<IWorkItem* const> wis) { - if (wis.empty()) - return; - + if (wis.empty()) + return; + if (Y_UNLIKELY(AtomicGet(ExitWorkers) != 0)) { Y_VERIFY(WorkItems.Empty(), "executor %s: cannot add tasks after queue shutdown", Config.Name); - } - - TWhatThreadDoesPushPop pp("executor: EnqueueWork"); - - WorkItems.PushAll(wis); - - { - if (wis.size() == 1) { - TWhatThreadDoesAcquireGuard<TMutex> g(WorkMutex, "executor: acquiring lock for EnqueueWork"); - WorkAvailable.Signal(); - } else { - TWhatThreadDoesAcquireGuard<TMutex> g(WorkMutex, "executor: acquiring lock for EnqueueWork"); - WorkAvailable.BroadCast(); - } - } -} - + } + + TWhatThreadDoesPushPop pp("executor: EnqueueWork"); + + WorkItems.PushAll(wis); + + { + if (wis.size() == 1) { + TWhatThreadDoesAcquireGuard<TMutex> g(WorkMutex, "executor: acquiring lock for EnqueueWork"); + WorkAvailable.Signal(); + } else { + TWhatThreadDoesAcquireGuard<TMutex> g(WorkMutex, "executor: acquiring lock for EnqueueWork"); + WorkAvailable.BroadCast(); + } + } +} + size_t TExecutor::GetWorkQueueSize() const { - return WorkItems.Size(); -} - + return WorkItems.Size(); +} + using namespace NTSAN; -ui32 TExecutor::GetMaxQueueSizeAndClear() const { - ui32 max = 0; - for (unsigned i = 0; i < WorkerThreads.size(); ++i) { +ui32 TExecutor::GetMaxQueueSizeAndClear() const { + ui32 max = 0; + for (unsigned i = 0; i < WorkerThreads.size(); ++i) { TExecutorWorkerThreadLocalData* wtls = RelaxedLoad(&WorkerThreads[i]->ThreadLocalData); max = Max<ui32>(max, RelaxedLoad(&wtls->MaxQueueSize)); RelaxedStore<ui32>(&wtls->MaxQueueSize, 0); - } - return max; -} - + } + return max; +} + TString TExecutor::GetStatus() const { - return GetStatusRecordInternal().Status; -} - + return GetStatusRecordInternal().Status; +} + TString TExecutor::GetStatusSingleLine() const { - TStringStream ss; - ss << "work items: " << GetWorkQueueSize(); - return ss.Str(); -} - + TStringStream ss; + ss << "work items: " << GetWorkQueueSize(); + return ss.Str(); +} + TExecutorStatus TExecutor::GetStatusRecordInternal() const { - TExecutorStatus r; - - r.WorkQueueSize = GetWorkQueueSize(); - - { - TStringStream ss; - ss << "work items: " << GetWorkQueueSize() << "\n"; - ss << "workers:\n"; - for (unsigned i = 0; i < WorkerThreads.size(); ++i) { + TExecutorStatus r; + + r.WorkQueueSize = GetWorkQueueSize(); + + { + TStringStream ss; + ss << "work items: " << GetWorkQueueSize() << "\n"; + ss << "workers:\n"; + for (unsigned i = 0; i < WorkerThreads.size(); ++i) { ss << "-- " << AtomicGet(*AtomicGet(WorkerThreads[i]->WhatThreadDoesLocation)) << "\n"; - } - r.Status = ss.Str(); - } - - r.History = Impl->History.Capture(); - - return r; -} - + } + r.Status = ss.Str(); + } + + r.History = Impl->History.Capture(); + + return r; +} + bool TExecutor::IsInExecutorThread() const { - return ThreadCurrentExecutor == this; -} - -TAutoPtr<IWorkItem> TExecutor::DequeueWork() { - IWorkItem* wi = reinterpret_cast<IWorkItem*>(1); - size_t queueSize = Max<size_t>(); - if (!WorkItems.TryPop(&wi, &queueSize)) { - TWhatThreadDoesAcquireGuard<TMutex> g(WorkMutex, "executor: acquiring lock for DequeueWork"); - while (!WorkItems.TryPop(&wi, &queueSize)) { + return ThreadCurrentExecutor == this; +} + +TAutoPtr<IWorkItem> TExecutor::DequeueWork() { + IWorkItem* wi = reinterpret_cast<IWorkItem*>(1); + size_t queueSize = Max<size_t>(); + if (!WorkItems.TryPop(&wi, &queueSize)) { + TWhatThreadDoesAcquireGuard<TMutex> g(WorkMutex, "executor: acquiring lock for DequeueWork"); + while (!WorkItems.TryPop(&wi, &queueSize)) { if (AtomicGet(ExitWorkers) != 0) return nullptr; - - TWhatThreadDoesPushPop pp("waiting for work on condvar"); - WorkAvailable.Wait(WorkMutex); - } - } + + TWhatThreadDoesPushPop pp("waiting for work on condvar"); + WorkAvailable.Wait(WorkMutex); + } + } auto& wtls = TlsRef(WorkerThreadLocalData); if (queueSize > RelaxedLoad(&wtls.MaxQueueSize)) { RelaxedStore<ui32>(&wtls.MaxQueueSize, queueSize); - } - - return wi; -} - -void TExecutor::RunWorkItem(TAutoPtr<IWorkItem> wi) { - WHAT_THREAD_DOES_PUSH_POP_CURRENT_FUNC(); - wi.Release()->DoWork(); -} - -void TExecutor::ProcessWorkQueueHere() { - IWorkItem* wi; - while (WorkItems.TryPop(&wi)) { - RunWorkItem(wi); - } -} - -void TExecutor::RunWorker() { + } + + return wi; +} + +void TExecutor::RunWorkItem(TAutoPtr<IWorkItem> wi) { + WHAT_THREAD_DOES_PUSH_POP_CURRENT_FUNC(); + wi.Release()->DoWork(); +} + +void TExecutor::ProcessWorkQueueHere() { + IWorkItem* wi; + while (WorkItems.TryPop(&wi)) { + RunWorkItem(wi); + } +} + +void TExecutor::RunWorker() { Y_VERIFY(!ThreadCurrentExecutor, "state check"); - ThreadCurrentExecutor = this; - + ThreadCurrentExecutor = this; + SetCurrentThreadName("wrkr"); - - for (;;) { - TAutoPtr<IWorkItem> wi = DequeueWork(); - if (!wi) { - break; - } - // Note for messagebus users: make sure program crashes - // on uncaught exception in thread, otherewise messagebus may just hang on error. - RunWorkItem(wi); - } - + + for (;;) { + TAutoPtr<IWorkItem> wi = DequeueWork(); + if (!wi) { + break; + } + // Note for messagebus users: make sure program crashes + // on uncaught exception in thread, otherewise messagebus may just hang on error. + RunWorkItem(wi); + } + ThreadCurrentExecutor = (TExecutor*)nullptr; -} +} diff --git a/library/cpp/messagebus/actor/executor.h b/library/cpp/messagebus/actor/executor.h index 2a30580ff1..7292d8be53 100644 --- a/library/cpp/messagebus/actor/executor.h +++ b/library/cpp/messagebus/actor/executor.h @@ -1,16 +1,16 @@ -#pragma once - +#pragma once + #include "ring_buffer_with_spin_lock.h" #include <util/generic/array_ref.h> -#include <util/generic/vector.h> -#include <util/system/condvar.h> -#include <util/system/event.h> +#include <util/generic/vector.h> +#include <util/system/condvar.h> +#include <util/system/event.h> #include <util/system/mutex.h> #include <util/system/thread.h> -#include <util/thread/lfqueue.h> - -namespace NActor { +#include <util/thread/lfqueue.h> + +namespace NActor { namespace NPrivate { struct TExecutorHistory { struct THistoryRecord { @@ -18,88 +18,88 @@ namespace NActor { }; TVector<THistoryRecord> HistoryRecords; ui64 LastHistoryRecordSecond; - + ui64 FirstHistoryRecordSecond() const { return LastHistoryRecordSecond - HistoryRecords.size() + 1; } }; - + struct TExecutorStatus { size_t WorkQueueSize = 0; TExecutorHistory History; TString Status; - }; + }; } - + class IWorkItem { public: virtual ~IWorkItem() { - } + } virtual void DoWork(/* must release this */) = 0; - }; - + }; + struct TExecutorWorker; - + class TExecutor: public TAtomicRefCount<TExecutor> { friend struct TExecutorWorker; - + public: struct TConfig { size_t WorkerCount; const char* Name; - + TConfig() : WorkerCount(1) , Name() { } }; - + private: struct TImpl; THolder<TImpl> Impl; - + const TConfig Config; - + TAtomic ExitWorkers; - + TVector<TAutoPtr<TExecutorWorker>> WorkerThreads; - + TRingBufferWithSpinLock<IWorkItem*> WorkItems; - + TMutex WorkMutex; TCondVar WorkAvailable; - + public: explicit TExecutor(size_t workerCount); TExecutor(const TConfig& config); ~TExecutor(); - + void Stop(); - + void EnqueueWork(TArrayRef<IWorkItem* const> w); - + size_t GetWorkQueueSize() const; TString GetStatus() const; TString GetStatusSingleLine() const; NPrivate::TExecutorStatus GetStatusRecordInternal() const; - + bool IsInExecutorThread() const; - + private: void Init(); - + TAutoPtr<IWorkItem> DequeueWork(); - + void ProcessWorkQueueHere(); - + inline void RunWorkItem(TAutoPtr<IWorkItem>); - + void RunWorker(); - + ui32 GetMaxQueueSizeAndClear() const; }; - + using TExecutorPtr = TIntrusivePtr<TExecutor>; - + } diff --git a/library/cpp/messagebus/actor/queue_for_actor.h b/library/cpp/messagebus/actor/queue_for_actor.h index b64a2a27a2..40fa536b82 100644 --- a/library/cpp/messagebus/actor/queue_for_actor.h +++ b/library/cpp/messagebus/actor/queue_for_actor.h @@ -1,65 +1,65 @@ -#pragma once - -#include <util/generic/vector.h> -#include <util/system/yassert.h> -#include <util/thread/lfstack.h> -#include <util/thread/singleton.h> - -// TODO: include from correct directory -#include "temp_tls_vector.h" - -namespace NActor { +#pragma once + +#include <util/generic/vector.h> +#include <util/system/yassert.h> +#include <util/thread/lfstack.h> +#include <util/thread/singleton.h> + +// TODO: include from correct directory +#include "temp_tls_vector.h" + +namespace NActor { namespace NPrivate { struct TTagForTl {}; - + } - + template <typename T> class TQueueForActor { private: TLockFreeStack<T> Queue; - + public: ~TQueueForActor() { Y_VERIFY(Queue.IsEmpty()); } - + bool IsEmpty() { return Queue.IsEmpty(); } - + void Enqueue(const T& value) { Queue.Enqueue(value); } - + template <typename TCollection> void EnqueueAll(const TCollection& all) { Queue.EnqueueAll(all); } - + void Clear() { TVector<T> tmp; Queue.DequeueAll(&tmp); } - + template <typename TFunc> void DequeueAll(const TFunc& func // TODO: , std::enable_if_t<TFunctionParamCount<TFunc>::Value == 1>* = 0 ) { TTempTlsVector<T> temp; - + Queue.DequeueAllSingleConsumer(temp.GetVector()); - + for (typename TVector<T>::reverse_iterator i = temp.GetVector()->rbegin(); i != temp.GetVector()->rend(); ++i) { func(*i); } - + temp.Clear(); - + if (temp.Capacity() * sizeof(T) > 64 * 1024) { temp.Shrink(); } - } + } template <typename TFunc> void DequeueAllLikelyEmpty(const TFunc& func) { @@ -70,5 +70,5 @@ namespace NActor { DequeueAll(func); } }; - + } diff --git a/library/cpp/messagebus/actor/queue_in_actor.h b/library/cpp/messagebus/actor/queue_in_actor.h index f93eb03070..9865996532 100644 --- a/library/cpp/messagebus/actor/queue_in_actor.h +++ b/library/cpp/messagebus/actor/queue_in_actor.h @@ -1,80 +1,80 @@ -#pragma once - -#include "actor.h" -#include "queue_for_actor.h" - +#pragma once + +#include "actor.h" +#include "queue_for_actor.h" + #include <functional> -namespace NActor { +namespace NActor { template <typename TItem> class IQueueInActor { public: virtual void EnqueueAndScheduleV(const TItem& item) = 0; virtual void DequeueAllV() = 0; virtual void DequeueAllLikelyEmptyV() = 0; - + virtual ~IQueueInActor() { } }; - + template <typename TThis, typename TItem, typename TActorTag = TDefaultTag, typename TQueueTag = TDefaultTag> class TQueueInActor: public IQueueInActor<TItem> { typedef TQueueInActor<TThis, TItem, TActorTag, TQueueTag> TSelf; - + public: // TODO: make protected TQueueForActor<TItem> QueueInActor; - + private: TActor<TThis, TActorTag>* GetActor() { return GetThis(); } - + TThis* GetThis() { return static_cast<TThis*>(this); } - + void ProcessItem(const TItem& item) { GetThis()->ProcessItem(TActorTag(), TQueueTag(), item); } - + public: void EnqueueAndNoSchedule(const TItem& item) { QueueInActor.Enqueue(item); } - + void EnqueueAndSchedule(const TItem& item) { EnqueueAndNoSchedule(item); GetActor()->Schedule(); } - + void EnqueueAndScheduleV(const TItem& item) override { EnqueueAndSchedule(item); } - + void Clear() { QueueInActor.Clear(); } - + void DequeueAll() { QueueInActor.DequeueAll(std::bind(&TSelf::ProcessItem, this, std::placeholders::_1)); } - + void DequeueAllV() override { return DequeueAll(); } - + void DequeueAllLikelyEmpty() { QueueInActor.DequeueAllLikelyEmpty(std::bind(&TSelf::ProcessItem, this, std::placeholders::_1)); } - + void DequeueAllLikelyEmptyV() override { return DequeueAllLikelyEmpty(); } - + bool IsEmpty() { return QueueInActor.IsEmpty(); } }; - + } diff --git a/library/cpp/messagebus/actor/ring_buffer.h b/library/cpp/messagebus/actor/ring_buffer.h index a0e2f481bf..ec5706f7c7 100644 --- a/library/cpp/messagebus/actor/ring_buffer.h +++ b/library/cpp/messagebus/actor/ring_buffer.h @@ -1,135 +1,135 @@ -#pragma once - +#pragma once + #include <util/generic/array_ref.h> #include <util/generic/maybe.h> #include <util/generic/utility.h> #include <util/generic/vector.h> -#include <util/system/yassert.h> - -template <typename T> -struct TRingBuffer { -private: - ui32 CapacityPow; - ui32 CapacityMask; - ui32 Capacity; - ui32 WritePos; - ui32 ReadPos; +#include <util/system/yassert.h> + +template <typename T> +struct TRingBuffer { +private: + ui32 CapacityPow; + ui32 CapacityMask; + ui32 Capacity; + ui32 WritePos; + ui32 ReadPos; TVector<T> Data; - - void StateCheck() const { + + void StateCheck() const { Y_ASSERT(Capacity == Data.size()); Y_ASSERT(Capacity == (1u << CapacityPow)); Y_ASSERT((Capacity & CapacityMask) == 0u); Y_ASSERT(Capacity - CapacityMask == 1u); Y_ASSERT(WritePos < Capacity); Y_ASSERT(ReadPos < Capacity); - } - - size_t Writable() const { - return (Capacity + ReadPos - WritePos - 1) & CapacityMask; - } - - void ReserveWritable(ui32 sz) { - if (sz <= Writable()) - return; - - ui32 newCapacityPow = CapacityPow; + } + + size_t Writable() const { + return (Capacity + ReadPos - WritePos - 1) & CapacityMask; + } + + void ReserveWritable(ui32 sz) { + if (sz <= Writable()) + return; + + ui32 newCapacityPow = CapacityPow; while ((1u << newCapacityPow) < sz + ui32(Size()) + 1u) { - ++newCapacityPow; - } - ui32 newCapacity = 1u << newCapacityPow; - ui32 newCapacityMask = newCapacity - 1u; + ++newCapacityPow; + } + ui32 newCapacity = 1u << newCapacityPow; + ui32 newCapacityMask = newCapacity - 1u; TVector<T> newData(newCapacity); - ui32 oldSize = Size(); - // Copy old elements - for (size_t i = 0; i < oldSize; ++i) { - newData[i] = Get(i); - } - - CapacityPow = newCapacityPow; - Capacity = newCapacity; - CapacityMask = newCapacityMask; - Data.swap(newData); - ReadPos = 0; - WritePos = oldSize; - - StateCheck(); - } - - const T& Get(ui32 i) const { - return Data[(ReadPos + i) & CapacityMask]; - } - -public: - TRingBuffer() - : CapacityPow(0) - , CapacityMask(0) - , Capacity(1 << CapacityPow) - , WritePos(0) - , ReadPos(0) - , Data(Capacity) - { - StateCheck(); - } - - size_t Size() const { - return (Capacity + WritePos - ReadPos) & CapacityMask; - } - - bool Empty() const { - return WritePos == ReadPos; - } - + ui32 oldSize = Size(); + // Copy old elements + for (size_t i = 0; i < oldSize; ++i) { + newData[i] = Get(i); + } + + CapacityPow = newCapacityPow; + Capacity = newCapacity; + CapacityMask = newCapacityMask; + Data.swap(newData); + ReadPos = 0; + WritePos = oldSize; + + StateCheck(); + } + + const T& Get(ui32 i) const { + return Data[(ReadPos + i) & CapacityMask]; + } + +public: + TRingBuffer() + : CapacityPow(0) + , CapacityMask(0) + , Capacity(1 << CapacityPow) + , WritePos(0) + , ReadPos(0) + , Data(Capacity) + { + StateCheck(); + } + + size_t Size() const { + return (Capacity + WritePos - ReadPos) & CapacityMask; + } + + bool Empty() const { + return WritePos == ReadPos; + } + void PushAll(TArrayRef<const T> value) { - ReserveWritable(value.size()); - - ui32 secondSize; - ui32 firstSize; - - if (WritePos + value.size() <= Capacity) { - firstSize = value.size(); - secondSize = 0; - } else { - firstSize = Capacity - WritePos; - secondSize = value.size() - firstSize; - } - - for (size_t i = 0; i < firstSize; ++i) { + ReserveWritable(value.size()); + + ui32 secondSize; + ui32 firstSize; + + if (WritePos + value.size() <= Capacity) { + firstSize = value.size(); + secondSize = 0; + } else { + firstSize = Capacity - WritePos; + secondSize = value.size() - firstSize; + } + + for (size_t i = 0; i < firstSize; ++i) { Data[WritePos + i] = value[i]; - } - - for (size_t i = 0; i < secondSize; ++i) { + } + + for (size_t i = 0; i < secondSize; ++i) { Data[i] = value[firstSize + i]; - } - - WritePos = (WritePos + value.size()) & CapacityMask; - StateCheck(); - } - - void Push(const T& t) { + } + + WritePos = (WritePos + value.size()) & CapacityMask; + StateCheck(); + } + + void Push(const T& t) { PushAll(MakeArrayRef(&t, 1)); - } - - bool TryPop(T* r) { - StateCheck(); - if (Empty()) { - return false; - } - *r = Data[ReadPos]; - ReadPos = (ReadPos + 1) & CapacityMask; - return true; - } - - TMaybe<T> TryPop() { - T tmp; - if (TryPop(&tmp)) { - return tmp; - } else { - return TMaybe<T>(); - } - } - - T Pop() { - return *TryPop(); - } -}; + } + + bool TryPop(T* r) { + StateCheck(); + if (Empty()) { + return false; + } + *r = Data[ReadPos]; + ReadPos = (ReadPos + 1) & CapacityMask; + return true; + } + + TMaybe<T> TryPop() { + T tmp; + if (TryPop(&tmp)) { + return tmp; + } else { + return TMaybe<T>(); + } + } + + T Pop() { + return *TryPop(); + } +}; diff --git a/library/cpp/messagebus/actor/ring_buffer_ut.cpp b/library/cpp/messagebus/actor/ring_buffer_ut.cpp index 9b2f46957b..bdb379b3a9 100644 --- a/library/cpp/messagebus/actor/ring_buffer_ut.cpp +++ b/library/cpp/messagebus/actor/ring_buffer_ut.cpp @@ -1,60 +1,60 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "ring_buffer.h" - + +#include "ring_buffer.h" + #include <util/random/random.h> Y_UNIT_TEST_SUITE(RingBuffer) { - struct TRingBufferTester { - TRingBuffer<unsigned> RingBuffer; - - unsigned NextPush; - unsigned NextPop; - + struct TRingBufferTester { + TRingBuffer<unsigned> RingBuffer; + + unsigned NextPush; + unsigned NextPop; + TRingBufferTester() : NextPush() , NextPop() { } - - void Push() { - //Cerr << "push " << NextPush << "\n"; - RingBuffer.Push(NextPush); - NextPush += 1; - } - - void Pop() { - //Cerr << "pop " << NextPop << "\n"; - unsigned popped = RingBuffer.Pop(); - UNIT_ASSERT_VALUES_EQUAL(NextPop, popped); - NextPop += 1; - } - - bool Empty() const { - UNIT_ASSERT_VALUES_EQUAL(RingBuffer.Size(), NextPush - NextPop); - UNIT_ASSERT_VALUES_EQUAL(RingBuffer.Empty(), RingBuffer.Size() == 0); - return RingBuffer.Empty(); - } - }; - - void Iter() { - TRingBufferTester rb; - - while (rb.NextPush < 1000) { - rb.Push(); - while (!rb.Empty() && RandomNumber<bool>()) { - rb.Pop(); - } - } - - while (!rb.Empty()) { - rb.Pop(); - } - } - + + void Push() { + //Cerr << "push " << NextPush << "\n"; + RingBuffer.Push(NextPush); + NextPush += 1; + } + + void Pop() { + //Cerr << "pop " << NextPop << "\n"; + unsigned popped = RingBuffer.Pop(); + UNIT_ASSERT_VALUES_EQUAL(NextPop, popped); + NextPop += 1; + } + + bool Empty() const { + UNIT_ASSERT_VALUES_EQUAL(RingBuffer.Size(), NextPush - NextPop); + UNIT_ASSERT_VALUES_EQUAL(RingBuffer.Empty(), RingBuffer.Size() == 0); + return RingBuffer.Empty(); + } + }; + + void Iter() { + TRingBufferTester rb; + + while (rb.NextPush < 1000) { + rb.Push(); + while (!rb.Empty() && RandomNumber<bool>()) { + rb.Pop(); + } + } + + while (!rb.Empty()) { + rb.Pop(); + } + } + Y_UNIT_TEST(Random) { - for (unsigned i = 0; i < 100; ++i) { - Iter(); - } - } -} + for (unsigned i = 0; i < 100; ++i) { + Iter(); + } + } +} diff --git a/library/cpp/messagebus/actor/ring_buffer_with_spin_lock.h b/library/cpp/messagebus/actor/ring_buffer_with_spin_lock.h index d05dec8577..f0b7cd90e4 100644 --- a/library/cpp/messagebus/actor/ring_buffer_with_spin_lock.h +++ b/library/cpp/messagebus/actor/ring_buffer_with_spin_lock.h @@ -1,91 +1,91 @@ -#pragma once - +#pragma once + #include "ring_buffer.h" -#include <util/system/spinlock.h> - -template <typename T> -class TRingBufferWithSpinLock { -private: - TRingBuffer<T> RingBuffer; - TSpinLock SpinLock; +#include <util/system/spinlock.h> + +template <typename T> +class TRingBufferWithSpinLock { +private: + TRingBuffer<T> RingBuffer; + TSpinLock SpinLock; TAtomic CachedSize; -public: - TRingBufferWithSpinLock() +public: + TRingBufferWithSpinLock() : CachedSize(0) { } - - void Push(const T& t) { - PushAll(t); - } - + + void Push(const T& t) { + PushAll(t); + } + void PushAll(TArrayRef<const T> collection) { - if (collection.empty()) { - return; - } - - TGuard<TSpinLock> Guard(SpinLock); - RingBuffer.PushAll(collection); + if (collection.empty()) { + return; + } + + TGuard<TSpinLock> Guard(SpinLock); + RingBuffer.PushAll(collection); AtomicSet(CachedSize, RingBuffer.Size()); - } - + } + bool TryPop(T* r, size_t* sizePtr = nullptr) { if (AtomicGet(CachedSize) == 0) { - return false; - } - - bool ok; - size_t size; - { - TGuard<TSpinLock> Guard(SpinLock); - ok = RingBuffer.TryPop(r); - size = RingBuffer.Size(); + return false; + } + + bool ok; + size_t size; + { + TGuard<TSpinLock> Guard(SpinLock); + ok = RingBuffer.TryPop(r); + size = RingBuffer.Size(); AtomicSet(CachedSize, size); - } - if (!!sizePtr) { - *sizePtr = size; - } - return ok; - } - - TMaybe<T> TryPop() { - T tmp; - if (TryPop(&tmp)) { - return tmp; - } else { - return TMaybe<T>(); - } - } - + } + if (!!sizePtr) { + *sizePtr = size; + } + return ok; + } + + TMaybe<T> TryPop() { + T tmp; + if (TryPop(&tmp)) { + return tmp; + } else { + return TMaybe<T>(); + } + } + bool PushAllAndTryPop(TArrayRef<const T> collection, T* r) { - if (collection.size() == 0) { - return TryPop(r); - } else { + if (collection.size() == 0) { + return TryPop(r); + } else { if (AtomicGet(CachedSize) == 0) { - *r = collection[0]; - if (collection.size() > 1) { - TGuard<TSpinLock> guard(SpinLock); + *r = collection[0]; + if (collection.size() > 1) { + TGuard<TSpinLock> guard(SpinLock); RingBuffer.PushAll(MakeArrayRef(collection.data() + 1, collection.size() - 1)); AtomicSet(CachedSize, RingBuffer.Size()); - } - } else { - TGuard<TSpinLock> guard(SpinLock); - RingBuffer.PushAll(collection); - *r = RingBuffer.Pop(); + } + } else { + TGuard<TSpinLock> guard(SpinLock); + RingBuffer.PushAll(collection); + *r = RingBuffer.Pop(); AtomicSet(CachedSize, RingBuffer.Size()); - } - return true; - } - } - - bool Empty() const { + } + return true; + } + } + + bool Empty() const { return AtomicGet(CachedSize) == 0; - } - - size_t Size() const { - TGuard<TSpinLock> Guard(SpinLock); - return RingBuffer.Size(); - } -}; + } + + size_t Size() const { + TGuard<TSpinLock> Guard(SpinLock); + return RingBuffer.Size(); + } +}; diff --git a/library/cpp/messagebus/actor/tasks.h b/library/cpp/messagebus/actor/tasks.h index 3eab200b38..31d35931d2 100644 --- a/library/cpp/messagebus/actor/tasks.h +++ b/library/cpp/messagebus/actor/tasks.h @@ -1,9 +1,9 @@ -#pragma once - +#pragma once + #include <util/system/atomic.h> -#include <util/system/yassert.h> - -namespace NActor { +#include <util/system/yassert.h> + +namespace NActor { class TTasks { enum { // order of values is important @@ -11,27 +11,27 @@ namespace NActor { E_RUNNING_NO_TASKS, E_RUNNING_GOT_TASKS, }; - + private: TAtomic State; - + public: TTasks() : State(E_WAITING) { - } - + } + // @return true iff caller have to either schedule task or execute it bool AddTask() { // High contention case optimization: AtomicGet is cheaper than AtomicSwap. if (E_RUNNING_GOT_TASKS == AtomicGet(State)) { return false; } - + TAtomicBase oldState = AtomicSwap(&State, E_RUNNING_GOT_TASKS); return oldState == E_WAITING; - } - + } + // called by executor // @return true iff we have to recheck queues bool FetchTask() { @@ -44,5 +44,5 @@ namespace NActor { Y_FAIL("unknown"); } }; - + } diff --git a/library/cpp/messagebus/actor/tasks_ut.cpp b/library/cpp/messagebus/actor/tasks_ut.cpp index 8468109a7d..d80e8451a5 100644 --- a/library/cpp/messagebus/actor/tasks_ut.cpp +++ b/library/cpp/messagebus/actor/tasks_ut.cpp @@ -1,37 +1,37 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "tasks.h" - -using namespace NActor; - + +#include "tasks.h" + +using namespace NActor; + Y_UNIT_TEST_SUITE(TTasks) { Y_UNIT_TEST(AddTask_FetchTask_Simple) { - TTasks tasks; - - UNIT_ASSERT(tasks.AddTask()); - UNIT_ASSERT(!tasks.AddTask()); - UNIT_ASSERT(!tasks.AddTask()); - - UNIT_ASSERT(tasks.FetchTask()); - UNIT_ASSERT(!tasks.FetchTask()); - - UNIT_ASSERT(tasks.AddTask()); - } - + TTasks tasks; + + UNIT_ASSERT(tasks.AddTask()); + UNIT_ASSERT(!tasks.AddTask()); + UNIT_ASSERT(!tasks.AddTask()); + + UNIT_ASSERT(tasks.FetchTask()); + UNIT_ASSERT(!tasks.FetchTask()); + + UNIT_ASSERT(tasks.AddTask()); + } + Y_UNIT_TEST(AddTask_FetchTask_AddTask) { - TTasks tasks; - - UNIT_ASSERT(tasks.AddTask()); - UNIT_ASSERT(!tasks.AddTask()); - - UNIT_ASSERT(tasks.FetchTask()); - UNIT_ASSERT(!tasks.AddTask()); - UNIT_ASSERT(tasks.FetchTask()); - UNIT_ASSERT(!tasks.AddTask()); - UNIT_ASSERT(!tasks.AddTask()); - UNIT_ASSERT(tasks.FetchTask()); - UNIT_ASSERT(!tasks.FetchTask()); - - UNIT_ASSERT(tasks.AddTask()); - } -} + TTasks tasks; + + UNIT_ASSERT(tasks.AddTask()); + UNIT_ASSERT(!tasks.AddTask()); + + UNIT_ASSERT(tasks.FetchTask()); + UNIT_ASSERT(!tasks.AddTask()); + UNIT_ASSERT(tasks.FetchTask()); + UNIT_ASSERT(!tasks.AddTask()); + UNIT_ASSERT(!tasks.AddTask()); + UNIT_ASSERT(tasks.FetchTask()); + UNIT_ASSERT(!tasks.FetchTask()); + + UNIT_ASSERT(tasks.AddTask()); + } +} diff --git a/library/cpp/messagebus/actor/temp_tls_vector.h b/library/cpp/messagebus/actor/temp_tls_vector.h index 5c535dd07c..675d92f5b0 100644 --- a/library/cpp/messagebus/actor/temp_tls_vector.h +++ b/library/cpp/messagebus/actor/temp_tls_vector.h @@ -1,34 +1,34 @@ -#pragma once - +#pragma once + #include "thread_extra.h" #include <util/generic/vector.h> -#include <util/system/yassert.h> - +#include <util/system/yassert.h> + template <typename T, typename TTag = void, template <typename, class> class TVectorType = TVector> -class TTempTlsVector { -private: - struct TTagForTls {}; - +class TTempTlsVector { +private: + struct TTagForTls {}; + TVectorType<T, std::allocator<T>>* Vector; -public: +public: TVectorType<T, std::allocator<T>>* GetVector() { - return Vector; - } - - TTempTlsVector() { + return Vector; + } + + TTempTlsVector() { Vector = FastTlsSingletonWithTag<TVectorType<T, std::allocator<T>>, TTagForTls>(); Y_ASSERT(Vector->empty()); - } - - ~TTempTlsVector() { + } + + ~TTempTlsVector() { Clear(); } void Clear() { - Vector->clear(); - } + Vector->clear(); + } size_t Capacity() const noexcept { return Vector->capacity(); @@ -37,4 +37,4 @@ public: void Shrink() { Vector->shrink_to_fit(); } -}; +}; diff --git a/library/cpp/messagebus/actor/thread_extra.cpp b/library/cpp/messagebus/actor/thread_extra.cpp index 6472dd92f4..048480f255 100644 --- a/library/cpp/messagebus/actor/thread_extra.cpp +++ b/library/cpp/messagebus/actor/thread_extra.cpp @@ -2,29 +2,29 @@ #include <util/stream/str.h> #include <util/system/execpath.h> -#include <util/system/platform.h> -#include <util/system/thread.h> - -namespace { +#include <util/system/platform.h> +#include <util/system/thread.h> + +namespace { #ifdef _linux_ TString GetExecName() { TString execPath = GetExecPath(); - size_t lastSlash = execPath.find_last_of('/'); + size_t lastSlash = execPath.find_last_of('/'); if (lastSlash == TString::npos) { - return execPath; - } else { - return execPath.substr(lastSlash + 1); - } - } + return execPath; + } else { + return execPath.substr(lastSlash + 1); + } + } #endif -} - +} + void SetCurrentThreadName(const char* name) { -#ifdef _linux_ - TStringStream linuxName; - linuxName << GetExecName() << "." << name; +#ifdef _linux_ + TStringStream linuxName; + linuxName << GetExecName() << "." << name; TThread::SetCurrentThreadName(linuxName.Str().data()); -#else +#else TThread::SetCurrentThreadName(name); -#endif -} +#endif +} diff --git a/library/cpp/messagebus/actor/thread_extra.h b/library/cpp/messagebus/actor/thread_extra.h index 002b2d8d5f..b5aa151618 100644 --- a/library/cpp/messagebus/actor/thread_extra.h +++ b/library/cpp/messagebus/actor/thread_extra.h @@ -1,7 +1,7 @@ -#pragma once - -#include <util/thread/singleton.h> - +#pragma once + +#include <util/thread/singleton.h> + namespace NTSAN { template <typename T> inline void RelaxedStore(volatile T* a, T x) { @@ -25,7 +25,7 @@ namespace NTSAN { } void SetCurrentThreadName(const char* name); - + namespace NThreadExtra { namespace NPrivate { template <typename TValue, typename TTag> @@ -34,8 +34,8 @@ namespace NThreadExtra { }; } } - -template <typename TValue, typename TTag> -static inline TValue* FastTlsSingletonWithTag() { + +template <typename TValue, typename TTag> +static inline TValue* FastTlsSingletonWithTag() { return &FastTlsSingleton< ::NThreadExtra::NPrivate::TValueHolder<TValue, TTag>>()->Value; -} +} diff --git a/library/cpp/messagebus/actor/what_thread_does.cpp b/library/cpp/messagebus/actor/what_thread_does.cpp index 94e0c0f64f..bebb6a888c 100644 --- a/library/cpp/messagebus/actor/what_thread_does.cpp +++ b/library/cpp/messagebus/actor/what_thread_does.cpp @@ -1,22 +1,22 @@ #include "what_thread_does.h" - + #include "thread_extra.h" - + #include <util/system/tls.h> Y_POD_STATIC_THREAD(const char*) WhatThreadDoes; - + const char* PushWhatThreadDoes(const char* what) { const char* r = NTSAN::RelaxedLoad(&WhatThreadDoes); NTSAN::RelaxedStore(&WhatThreadDoes, what); - return r; -} - + return r; +} + void PopWhatThreadDoes(const char* prev) { NTSAN::RelaxedStore(&WhatThreadDoes, prev); -} - +} + const char** WhatThreadDoesLocation() { - return &WhatThreadDoes; -} + return &WhatThreadDoes; +} diff --git a/library/cpp/messagebus/actor/what_thread_does.h b/library/cpp/messagebus/actor/what_thread_does.h index 325528fc55..235d2c3700 100644 --- a/library/cpp/messagebus/actor/what_thread_does.h +++ b/library/cpp/messagebus/actor/what_thread_does.h @@ -1,28 +1,28 @@ -#pragma once - -const char* PushWhatThreadDoes(const char* what); -void PopWhatThreadDoes(const char* prev); -const char** WhatThreadDoesLocation(); - -struct TWhatThreadDoesPushPop { -private: - const char* Prev; - -public: - TWhatThreadDoesPushPop(const char* what) { - Prev = PushWhatThreadDoes(what); - } - - ~TWhatThreadDoesPushPop() { - PopWhatThreadDoes(Prev); - } -}; - -#ifdef __GNUC__ -#define WHAT_THREAD_DOES_FUNCTION __PRETTY_FUNCTION__ -#else -#define WHAT_THREAD_DOES_FUNCTION __FUNCTION__ -#endif - -#define WHAT_THREAD_DOES_PUSH_POP_CURRENT_FUNC() \ - TWhatThreadDoesPushPop whatThreadDoesPushPopCurrentFunc(WHAT_THREAD_DOES_FUNCTION) +#pragma once + +const char* PushWhatThreadDoes(const char* what); +void PopWhatThreadDoes(const char* prev); +const char** WhatThreadDoesLocation(); + +struct TWhatThreadDoesPushPop { +private: + const char* Prev; + +public: + TWhatThreadDoesPushPop(const char* what) { + Prev = PushWhatThreadDoes(what); + } + + ~TWhatThreadDoesPushPop() { + PopWhatThreadDoes(Prev); + } +}; + +#ifdef __GNUC__ +#define WHAT_THREAD_DOES_FUNCTION __PRETTY_FUNCTION__ +#else +#define WHAT_THREAD_DOES_FUNCTION __FUNCTION__ +#endif + +#define WHAT_THREAD_DOES_PUSH_POP_CURRENT_FUNC() \ + TWhatThreadDoesPushPop whatThreadDoesPushPopCurrentFunc(WHAT_THREAD_DOES_FUNCTION) diff --git a/library/cpp/messagebus/actor/what_thread_does_guard.h b/library/cpp/messagebus/actor/what_thread_does_guard.h index f0888f0a8d..f104e9e173 100644 --- a/library/cpp/messagebus/actor/what_thread_does_guard.h +++ b/library/cpp/messagebus/actor/what_thread_does_guard.h @@ -1,40 +1,40 @@ -#pragma once - -#include "what_thread_does.h" - -template <class T> -class TWhatThreadDoesAcquireGuard: public TNonCopyable { +#pragma once + +#include "what_thread_does.h" + +template <class T> +class TWhatThreadDoesAcquireGuard: public TNonCopyable { public: inline TWhatThreadDoesAcquireGuard(const T& t, const char* acquire) noexcept { Init(&t, acquire); } - + inline TWhatThreadDoesAcquireGuard(const T* t, const char* acquire) noexcept { Init(t, acquire); } - + inline ~TWhatThreadDoesAcquireGuard() { Release(); } - + inline void Release() noexcept { if (WasAcquired()) { const_cast<T*>(T_)->Release(); T_ = nullptr; - } + } } - + inline bool WasAcquired() const noexcept { return T_ != nullptr; } - + private: inline void Init(const T* t, const char* acquire) noexcept { T_ = const_cast<T*>(t); TWhatThreadDoesPushPop pp(acquire); T_->Acquire(); } - + private: T* T_; -}; +}; diff --git a/library/cpp/messagebus/actor/what_thread_does_guard_ut.cpp b/library/cpp/messagebus/actor/what_thread_does_guard_ut.cpp index 74137f8f90..e4b218a7ca 100644 --- a/library/cpp/messagebus/actor/what_thread_does_guard_ut.cpp +++ b/library/cpp/messagebus/actor/what_thread_does_guard_ut.cpp @@ -1,13 +1,13 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "what_thread_does_guard.h" - + +#include "what_thread_does_guard.h" + #include <util/system/mutex.h> Y_UNIT_TEST_SUITE(WhatThreadDoesGuard) { Y_UNIT_TEST(Simple) { - TMutex mutex; - - TWhatThreadDoesAcquireGuard<TMutex> guard(mutex, "acquiring my mutex"); - } -} + TMutex mutex; + + TWhatThreadDoesAcquireGuard<TMutex> guard(mutex, "acquiring my mutex"); + } +} diff --git a/library/cpp/messagebus/actor/ya.make b/library/cpp/messagebus/actor/ya.make index 1ea37f5b48..59bd1b0b99 100644 --- a/library/cpp/messagebus/actor/ya.make +++ b/library/cpp/messagebus/actor/ya.make @@ -1,11 +1,11 @@ -LIBRARY(messagebus_actor) - +LIBRARY(messagebus_actor) + OWNER(g:messagebus) - -SRCS( - executor.cpp - thread_extra.cpp - what_thread_does.cpp -) - -END() + +SRCS( + executor.cpp + thread_extra.cpp + what_thread_does.cpp +) + +END() diff --git a/library/cpp/messagebus/all.lwt b/library/cpp/messagebus/all.lwt index f37103a238..0f04be4b2c 100644 --- a/library/cpp/messagebus/all.lwt +++ b/library/cpp/messagebus/all.lwt @@ -1,8 +1,8 @@ -Blocks { - ProbeDesc { - Group: "MessagebusRare" - } - Action { - PrintToStderrAction {} - } -} +Blocks { + ProbeDesc { + Group: "MessagebusRare" + } + Action { + PrintToStderrAction {} + } +} diff --git a/library/cpp/messagebus/all/ya.make b/library/cpp/messagebus/all/ya.make index 3810cf36e5..ffa2dbfabc 100644 --- a/library/cpp/messagebus/all/ya.make +++ b/library/cpp/messagebus/all/ya.make @@ -1,5 +1,5 @@ OWNER(g:messagebus) - + RECURSE_ROOT_RELATIVE( library/python/messagebus library/cpp/messagebus/debug_receiver @@ -7,4 +7,4 @@ RECURSE_ROOT_RELATIVE( library/cpp/messagebus/rain_check library/cpp/messagebus/test library/cpp/messagebus/www -) +) diff --git a/library/cpp/messagebus/async_result.h b/library/cpp/messagebus/async_result.h index 05a1a70f16..d24dde284a 100644 --- a/library/cpp/messagebus/async_result.h +++ b/library/cpp/messagebus/async_result.h @@ -1,54 +1,54 @@ -#pragma once - -#include <util/generic/maybe.h> -#include <util/generic/noncopyable.h> +#pragma once + +#include <util/generic/maybe.h> +#include <util/generic/noncopyable.h> #include <util/system/condvar.h> #include <util/system/mutex.h> #include <util/system/yassert.h> #include <functional> - -// probably this thing should have been called TFuture -template <typename T> -class TAsyncResult : TNonCopyable { -private: - TMutex Mutex; - TCondVar CondVar; - - TMaybe<T> Result; - - typedef void TOnResult(const T&); - + +// probably this thing should have been called TFuture +template <typename T> +class TAsyncResult : TNonCopyable { +private: + TMutex Mutex; + TCondVar CondVar; + + TMaybe<T> Result; + + typedef void TOnResult(const T&); + std::function<TOnResult> OnResult; - -public: - void SetResult(const T& result) { - TGuard<TMutex> guard(Mutex); + +public: + void SetResult(const T& result) { + TGuard<TMutex> guard(Mutex); Y_VERIFY(!Result, "cannot set result twice"); - Result = result; - CondVar.BroadCast(); - - if (!!OnResult) { - OnResult(result); - } - } - - const T& GetResult() { - TGuard<TMutex> guard(Mutex); - while (!Result) { - CondVar.Wait(Mutex); - } - return *Result; - } - - template <typename TFunc> + Result = result; + CondVar.BroadCast(); + + if (!!OnResult) { + OnResult(result); + } + } + + const T& GetResult() { + TGuard<TMutex> guard(Mutex); + while (!Result) { + CondVar.Wait(Mutex); + } + return *Result; + } + + template <typename TFunc> void AndThen(const TFunc& onResult) { - TGuard<TMutex> guard(Mutex); - if (!!Result) { - onResult(*Result); - } else { + TGuard<TMutex> guard(Mutex); + if (!!Result) { + onResult(*Result); + } else { Y_ASSERT(!OnResult); OnResult = std::function<TOnResult>(onResult); - } - } -}; + } + } +}; diff --git a/library/cpp/messagebus/async_result_ut.cpp b/library/cpp/messagebus/async_result_ut.cpp index 93f010d1f5..2e96492afd 100644 --- a/library/cpp/messagebus/async_result_ut.cpp +++ b/library/cpp/messagebus/async_result_ut.cpp @@ -1,37 +1,37 @@ - + #include <library/cpp/testing/unittest/registar.h> - -#include "async_result.h" - -namespace { - void SetValue(int* location, const int& value) { - *location = value; - } - -} - + +#include "async_result.h" + +namespace { + void SetValue(int* location, const int& value) { + *location = value; + } + +} + Y_UNIT_TEST_SUITE(TAsyncResult) { Y_UNIT_TEST(AndThen_Here) { - TAsyncResult<int> r; - - int var = 1; - - r.SetResult(17); - + TAsyncResult<int> r; + + int var = 1; + + r.SetResult(17); + r.AndThen(std::bind(&SetValue, &var, std::placeholders::_1)); - - UNIT_ASSERT_VALUES_EQUAL(17, var); - } - + + UNIT_ASSERT_VALUES_EQUAL(17, var); + } + Y_UNIT_TEST(AndThen_Later) { - TAsyncResult<int> r; - - int var = 1; - + TAsyncResult<int> r; + + int var = 1; + r.AndThen(std::bind(&SetValue, &var, std::placeholders::_1)); - - r.SetResult(17); - - UNIT_ASSERT_VALUES_EQUAL(17, var); - } -} + + r.SetResult(17); + + UNIT_ASSERT_VALUES_EQUAL(17, var); + } +} diff --git a/library/cpp/messagebus/base.h b/library/cpp/messagebus/base.h index adb4ea33b6..79fccc312e 100644 --- a/library/cpp/messagebus/base.h +++ b/library/cpp/messagebus/base.h @@ -1,11 +1,11 @@ #pragma once - + #include <util/system/defaults.h> -namespace NBus { +namespace NBus { /// millis since epoch using TBusInstant = ui64; /// returns time in milliseconds TBusInstant Now(); - -} + +} diff --git a/library/cpp/messagebus/cc_semaphore.h b/library/cpp/messagebus/cc_semaphore.h index 17d3b3bf32..0df8a3d664 100644 --- a/library/cpp/messagebus/cc_semaphore.h +++ b/library/cpp/messagebus/cc_semaphore.h @@ -1,36 +1,36 @@ -#pragma once - -#include "latch.h" - -template <typename TThis> -class TComplexConditionSemaphore { -private: - TLatch Latch; - -public: - void Updated() { - if (GetThis()->TryWait()) { - Latch.Unlock(); - } - } - - void Wait() { - while (!GetThis()->TryWait()) { - Latch.Lock(); - if (GetThis()->TryWait()) { - Latch.Unlock(); - return; - } - Latch.Wait(); - } - } - +#pragma once + +#include "latch.h" + +template <typename TThis> +class TComplexConditionSemaphore { +private: + TLatch Latch; + +public: + void Updated() { + if (GetThis()->TryWait()) { + Latch.Unlock(); + } + } + + void Wait() { + while (!GetThis()->TryWait()) { + Latch.Lock(); + if (GetThis()->TryWait()) { + Latch.Unlock(); + return; + } + Latch.Wait(); + } + } + bool IsLocked() { return Latch.IsLocked(); } - -private: - TThis* GetThis() { - return static_cast<TThis*>(this); - } -}; + +private: + TThis* GetThis() { + return static_cast<TThis*>(this); + } +}; diff --git a/library/cpp/messagebus/cc_semaphore_ut.cpp b/library/cpp/messagebus/cc_semaphore_ut.cpp index 5359ce2f7f..206bb7c96a 100644 --- a/library/cpp/messagebus/cc_semaphore_ut.cpp +++ b/library/cpp/messagebus/cc_semaphore_ut.cpp @@ -1,45 +1,45 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "cc_semaphore.h" - + +#include "cc_semaphore.h" + #include <util/system/atomic.h> -namespace { +namespace { struct TTestSemaphore: public TComplexConditionSemaphore<TTestSemaphore> { - TAtomic Current; - + TAtomic Current; + TTestSemaphore() : Current(0) { } - - bool TryWait() { - return AtomicGet(Current) > 0; - } - - void Aquire() { - Wait(); - AtomicDecrement(Current); - } - - void Release() { - AtomicIncrement(Current); - Updated(); - } - }; -} - + + bool TryWait() { + return AtomicGet(Current) > 0; + } + + void Aquire() { + Wait(); + AtomicDecrement(Current); + } + + void Release() { + AtomicIncrement(Current); + Updated(); + } + }; +} + Y_UNIT_TEST_SUITE(TComplexConditionSemaphore) { Y_UNIT_TEST(Simple) { - TTestSemaphore sema; - UNIT_ASSERT(!sema.TryWait()); - sema.Release(); - UNIT_ASSERT(sema.TryWait()); - sema.Release(); - UNIT_ASSERT(sema.TryWait()); - sema.Aquire(); - UNIT_ASSERT(sema.TryWait()); - sema.Aquire(); - UNIT_ASSERT(!sema.TryWait()); - } -} + TTestSemaphore sema; + UNIT_ASSERT(!sema.TryWait()); + sema.Release(); + UNIT_ASSERT(sema.TryWait()); + sema.Release(); + UNIT_ASSERT(sema.TryWait()); + sema.Aquire(); + UNIT_ASSERT(sema.TryWait()); + sema.Aquire(); + UNIT_ASSERT(!sema.TryWait()); + } +} diff --git a/library/cpp/messagebus/codegen.h b/library/cpp/messagebus/codegen.h index 678d42eb44..83e969e811 100644 --- a/library/cpp/messagebus/codegen.h +++ b/library/cpp/messagebus/codegen.h @@ -1,4 +1,4 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/config/codegen.h> - + diff --git a/library/cpp/messagebus/config/codegen.h b/library/cpp/messagebus/config/codegen.h index 5508fefc92..97ddada005 100644 --- a/library/cpp/messagebus/config/codegen.h +++ b/library/cpp/messagebus/config/codegen.h @@ -1,10 +1,10 @@ -#pragma once - -#define COMMA , - -#define STRUCT_FIELD_GEN(name, type, ...) type name; - -#define STRUCT_FIELD_INIT(name, type, defa) name(defa) -#define STRUCT_FIELD_INIT_DEFAULT(name, type, ...) name() - -#define STRUCT_FIELD_PRINT(name, ...) ss << #name << "=" << name << "\n"; +#pragma once + +#define COMMA , + +#define STRUCT_FIELD_GEN(name, type, ...) type name; + +#define STRUCT_FIELD_INIT(name, type, defa) name(defa) +#define STRUCT_FIELD_INIT_DEFAULT(name, type, ...) name() + +#define STRUCT_FIELD_PRINT(name, ...) ss << #name << "=" << name << "\n"; diff --git a/library/cpp/messagebus/config/defs.h b/library/cpp/messagebus/config/defs.h index 10820f83fd..92b1df9969 100644 --- a/library/cpp/messagebus/config/defs.h +++ b/library/cpp/messagebus/config/defs.h @@ -1,23 +1,23 @@ -#pragma once +#pragma once // unique tag to fix pragma once gcc glueing: ./library/cpp/messagebus/defs.h - + #include "codegen.h" #include "netaddr.h" #include <library/cpp/deprecated/enum_codegen/enum_codegen.h> -#include <util/generic/list.h> +#include <util/generic/list.h> #include <utility> - -// For historical reasons TCrawlerModule need to access -// APIs that should be private. -class TCrawlerModule; - -struct TDebugReceiverHandler; - -namespace NBus { + +// For historical reasons TCrawlerModule need to access +// APIs that should be private. +class TCrawlerModule; + +struct TDebugReceiverHandler; + +namespace NBus { namespace NPrivate { class TAcceptor; struct TBusSessionImpl; @@ -27,15 +27,15 @@ namespace NBus { class TRemoteServerConnection; class TRemoteClientConnection; class TBusSyncSourceSessionImpl; - + struct TBusMessagePtrAndHeader; - + struct TSessionDumpStatus; - + struct TClientRequestImpl; - + } - + class TBusSession; struct TBusServerSession; struct TBusClientSession; @@ -47,36 +47,36 @@ namespace NBus { struct TBusQueueConfig; struct TBusSessionConfig; struct TBusHeader; - + class IThreadHandler; - + using TBusKey = ui64; using TBusMessageList = TList<TBusMessage*>; using TBusKeyVec = TVector<std::pair<TBusKey, TBusKey>>; - + using TBusMessageQueuePtr = TIntrusivePtr<TBusMessageQueue>; - + class TBusModule; - + using TBusData = TString; using TBusService = const char*; - + #define YBUS_KEYMIN TBusKey(0L) #define YBUS_KEYMAX TBusKey(-1L) #define YBUS_KEYLOCAL TBusKey(7L) -#define YBUS_KEYINVALID TBusKey(99999999L) - +#define YBUS_KEYINVALID TBusKey(99999999L) + // Check that generated id is valid for remote message inline bool IsBusKeyValid(TBusKey key) { return key != YBUS_KEYINVALID && key != YBUS_KEYMAX && key > YBUS_KEYLOCAL; } #define YBUS_VERSION 0 - + #define YBUS_INFINITE (1u << 30u) - + #define YBUS_STATUS_BASIC 0x0000 #define YBUS_STATUS_CONNS 0x0001 -#define YBUS_STATUS_INFLIGHT 0x0002 - +#define YBUS_STATUS_INFLIGHT 0x0002 + } diff --git a/library/cpp/messagebus/config/netaddr.cpp b/library/cpp/messagebus/config/netaddr.cpp index 3c6311ab15..962ac538e2 100644 --- a/library/cpp/messagebus/config/netaddr.cpp +++ b/library/cpp/messagebus/config/netaddr.cpp @@ -1,7 +1,7 @@ #include "netaddr.h" -#include <util/network/address.h> - +#include <util/network/address.h> + #include <cstdlib> namespace NBus { @@ -15,8 +15,8 @@ namespace NBus { return "EIP_VERSION_6"; } Y_FAIL(); - } - + } + int ToAddrFamily(EIpVersion ipVersion) { switch (ipVersion) { case EIP_VERSION_ANY: @@ -83,8 +83,8 @@ namespace NBus { default: Y_FAIL("unreachable"); } - } - + } + TAutoPtr<IRemoteAddr> MakeAddress(const TNetworkAddress& na, EIpVersion requireVersion, EIpVersion preferVersion) { TAutoPtr<IRemoteAddr> addr; for (TNetworkAddress::TIterator it = na.Begin(); it != na.End(); ++it) { @@ -95,9 +95,9 @@ namespace NBus { addr.Reset(new TNetworkAddressRef(na, &*it)); } } - } + } return addr; - } + } TAutoPtr<IRemoteAddr> MakeAddress(TStringBuf host, int port, EIpVersion requireVersion, EIpVersion preferVersion) { TString hostString(host); TNetworkAddress na(hostString, port); @@ -136,17 +136,17 @@ namespace NBus { if (!Ptr) { ythrow TNetAddr::TError() << "cannot resolve into " << Describe(requireVersion); } - } - + } + TNetAddr::TNetAddr(const TNetworkAddress& na, const TAddrInfo& ai) : Ptr(new TNetworkAddressRef(na, ai)) { } - + const sockaddr* TNetAddr::Addr() const { return Ptr->Addr(); } - + socklen_t TNetAddr::Len() const { return Ptr->Len(); } @@ -169,14 +169,14 @@ namespace NBus { bool TNetAddr::IsIpv6() const { return Ptr->Addr()->sa_family == AF_INET6; - } - + } + bool TNetAddr::operator==(const TNetAddr& rhs) const { return Ptr == rhs.Ptr || Compare(*Ptr, *rhs.Ptr); } - -} - + +} + template <> void Out<NBus::TNetAddr>(IOutputStream& out, const NBus::TNetAddr& addr) { Out<NAddr::IRemoteAddr>(out, addr); diff --git a/library/cpp/messagebus/config/netaddr.h b/library/cpp/messagebus/config/netaddr.h index 3f8c80cde5..b79c0cc355 100644 --- a/library/cpp/messagebus/config/netaddr.h +++ b/library/cpp/messagebus/config/netaddr.h @@ -29,7 +29,7 @@ namespace NBus { const char* ToCString(EIpVersion); int ToAddrFamily(EIpVersion); - + /// Hold referenced pointer to address description structure (ex. sockaddr_storage) /// It's make possible to work with IPv4 / IPv6 addresses simultaneously class TNetAddr: public IRemoteAddr { @@ -62,7 +62,7 @@ namespace NBus { private: TAtomicSharedPtr<IRemoteAddr> Ptr; }; - + using TSockAddrInVector = TVector<TNetAddr>; struct TNetAddrHostPortHash { diff --git a/library/cpp/messagebus/config/session_config.cpp b/library/cpp/messagebus/config/session_config.cpp index fefd61c8f4..fbbbb106c9 100644 --- a/library/cpp/messagebus/config/session_config.cpp +++ b/library/cpp/messagebus/config/session_config.cpp @@ -1,31 +1,31 @@ -#include "session_config.h" - +#include "session_config.h" + #include <util/generic/strbuf.h> #include <util/string/hex.h> - -using namespace NBus; - -TBusSessionConfig::TSecret::TSecret() - : TimeoutPeriod(TDuration::Seconds(1)) - , StatusFlushPeriod(TDuration::MilliSeconds(400)) -{ -} - -TBusSessionConfig::TBusSessionConfig() - : BUS_SESSION_CONFIG_MAP(STRUCT_FIELD_INIT, COMMA) + +using namespace NBus; + +TBusSessionConfig::TSecret::TSecret() + : TimeoutPeriod(TDuration::Seconds(1)) + , StatusFlushPeriod(TDuration::MilliSeconds(400)) +{ +} + +TBusSessionConfig::TBusSessionConfig() + : BUS_SESSION_CONFIG_MAP(STRUCT_FIELD_INIT, COMMA) { } - + TString TBusSessionConfig::PrintToString() const { - TStringStream ss; - BUS_SESSION_CONFIG_MAP(STRUCT_FIELD_PRINT, ) - return ss.Str(); -} - -static int ParseDurationForMessageBus(const char* option) { - return TDuration::Parse(option).MilliSeconds(); -} - + TStringStream ss; + BUS_SESSION_CONFIG_MAP(STRUCT_FIELD_PRINT, ) + return ss.Str(); +} + +static int ParseDurationForMessageBus(const char* option) { + return TDuration::Parse(option).MilliSeconds(); +} + static int ParseToSForMessageBus(const char* option) { int tos; TStringBuf str(option); @@ -42,21 +42,21 @@ static int ParseToSForMessageBus(const char* option) { template <class T> static T ParseWithKmgSuffixT(const char* option) { - TStringBuf str(option); + TStringBuf str(option); T multiplier = 1; if (str.EndsWith('k')) { - multiplier = 1024; + multiplier = 1024; str = str.Head(str.size() - 1); } else if (str.EndsWith('m')) { - multiplier = 1024 * 1024; + multiplier = 1024 * 1024; str = str.Head(str.size() - 1); } else if (str.EndsWith('g')) { - multiplier = 1024 * 1024 * 1024; + multiplier = 1024 * 1024 * 1024; str = str.Head(str.size() - 1); - } + } return FromString<T>(str) * multiplier; -} - +} + static ui64 ParseWithKmgSuffix(const char* option) { return ParseWithKmgSuffixT<ui64>(option); } @@ -90,7 +90,7 @@ void TBusSessionConfig::ConfigureLastGetopt(NLastGetopt::TOpts& opts, opts.AddLongOption(prefix + "max-in-flight") .RequiredArgument("COUNT") .DefaultValue(ToString(MaxInFlight)) - .StoreMappedResultT<const char*>(&MaxInFlight, &ParseWithKmgSuffix); + .StoreMappedResultT<const char*>(&MaxInFlight, &ParseWithKmgSuffix); opts.AddLongOption(prefix + "max-in-flight-by-size") .RequiredArgument("BYTES") .DefaultValue( @@ -116,7 +116,7 @@ void TBusSessionConfig::ConfigureLastGetopt(NLastGetopt::TOpts& opts, opts.AddLongOption(prefix + "max-buffer-size") .RequiredArgument("BYTES") .DefaultValue(ToString(MaxBufferSize)) - .StoreMappedResultT<const char*>(&MaxBufferSize, &ParseWithKmgSuffix); + .StoreMappedResultT<const char*>(&MaxBufferSize, &ParseWithKmgSuffix); opts.AddLongOption(prefix + "max-message-size") .RequiredArgument("BYTES") .DefaultValue(ToString(MaxMessageSize)) @@ -149,9 +149,9 @@ void TBusSessionConfig::ConfigureLastGetopt(NLastGetopt::TOpts& opts, opts.AddLongOption(prefix + "on-message-in-pool") .RequiredArgument("BOOL") .DefaultValue(ToString(ExecuteOnMessageInWorkerPool)) - .StoreResult(&ExecuteOnMessageInWorkerPool); + .StoreResult(&ExecuteOnMessageInWorkerPool); opts.AddLongOption(prefix + "on-reply-in-pool") .RequiredArgument("BOOL") .DefaultValue(ToString(ExecuteOnReplyInWorkerPool)) - .StoreResult(&ExecuteOnReplyInWorkerPool); -} + .StoreResult(&ExecuteOnReplyInWorkerPool); +} diff --git a/library/cpp/messagebus/config/session_config.h b/library/cpp/messagebus/config/session_config.h index 7b02dbcd4e..84753350a9 100644 --- a/library/cpp/messagebus/config/session_config.h +++ b/library/cpp/messagebus/config/session_config.h @@ -1,13 +1,13 @@ -#pragma once - +#pragma once + #include "codegen.h" -#include "defs.h" - +#include "defs.h" + #include <library/cpp/getopt/last_getopt.h> - + #include <util/generic/string.h> - -namespace NBus { + +namespace NBus { #define BUS_SESSION_CONFIG_MAP(XX, comma) \ XX(Name, TString, "") \ comma \ @@ -35,31 +35,31 @@ namespace NBus { XX(ExecuteOnReplyInWorkerPool, bool, true) comma \ XX(ReusePort, bool, false) comma \ XX(ListenPort, unsigned, 0) /* TODO: server only */ - + //////////////////////////////////////////////////////////////////// /// \brief Configuration for client and server session struct TBusSessionConfig { BUS_SESSION_CONFIG_MAP(STRUCT_FIELD_GEN, ) - + struct TSecret { TDuration TimeoutPeriod; TDuration StatusFlushPeriod; - + TSecret(); }; - + // secret options are available, but you shouldn't probably use them TSecret Secret; - + /// initialized with default settings TBusSessionConfig(); - + TString PrintToString() const; - + void ConfigureLastGetopt(NLastGetopt::TOpts&, const TString& prefix = "mb-"); }; - + using TBusClientSessionConfig = TBusSessionConfig; using TBusServerSessionConfig = TBusSessionConfig; - -} // NBus + +} // NBus diff --git a/library/cpp/messagebus/connection.cpp b/library/cpp/messagebus/connection.cpp index 2b9a915150..07580ce18a 100644 --- a/library/cpp/messagebus/connection.cpp +++ b/library/cpp/messagebus/connection.cpp @@ -1,16 +1,16 @@ #include "connection.h" - -#include "remote_client_connection.h" - + +#include "remote_client_connection.h" + #include <util/generic/cast.h> - -using namespace NBus; -using namespace NBus::NPrivate; - -void TBusClientConnectionPtrOps::Ref(TBusClientConnection* c) { - return CheckedCast<TRemoteClientConnection*>(c)->Ref(); -} - -void TBusClientConnectionPtrOps::UnRef(TBusClientConnection* c) { - return CheckedCast<TRemoteClientConnection*>(c)->UnRef(); -} + +using namespace NBus; +using namespace NBus::NPrivate; + +void TBusClientConnectionPtrOps::Ref(TBusClientConnection* c) { + return CheckedCast<TRemoteClientConnection*>(c)->Ref(); +} + +void TBusClientConnectionPtrOps::UnRef(TBusClientConnection* c) { + return CheckedCast<TRemoteClientConnection*>(c)->UnRef(); +} diff --git a/library/cpp/messagebus/connection.h b/library/cpp/messagebus/connection.h index 9a2493162f..b1df64ddc1 100644 --- a/library/cpp/messagebus/connection.h +++ b/library/cpp/messagebus/connection.h @@ -1,22 +1,22 @@ -#pragma once - -#include "defs.h" -#include "message.h" - +#pragma once + +#include "defs.h" +#include "message.h" + #include <util/generic/ptr.h> -namespace NBus { +namespace NBus { struct TBusClientConnection { /// if you want to open connection early virtual void OpenConnection() = 0; - + /// Send message to the destination /// If addr is set then use it as destination. /// Takes ownership of addr (see ClearState method). virtual EMessageStatus SendMessage(TBusMessage* pMes, bool wait = false) = 0; - + virtual EMessageStatus SendMessageOneWay(TBusMessage* pMes, bool wait = false) = 0; - + /// Like SendMessage but cares about message template <typename T /* <: TBusMessage */> EMessageStatus SendMessageAutoPtr(const TAutoPtr<T>& mes, bool wait = false) { @@ -25,7 +25,7 @@ namespace NBus { Y_UNUSED(mes.Release()); return status; } - + /// Like SendMessageOneWay but cares about message template <typename T /* <: TBusMessage */> EMessageStatus SendMessageOneWayAutoPtr(const TAutoPtr<T>& mes, bool wait = false) { @@ -34,28 +34,28 @@ namespace NBus { Y_UNUSED(mes.Release()); return status; } - + EMessageStatus SendMessageMove(TBusMessageAutoPtr message, bool wait = false) { return SendMessageAutoPtr(message, wait); } - + EMessageStatus SendMessageOneWayMove(TBusMessageAutoPtr message, bool wait = false) { return SendMessageOneWayAutoPtr(message, wait); } - + // TODO: implement similar one-way methods - + virtual ~TBusClientConnection() { } - }; - + }; + namespace NPrivate { struct TBusClientConnectionPtrOps { static void Ref(TBusClientConnection*); static void UnRef(TBusClientConnection*); }; } - + using TBusClientConnectionPtr = TIntrusivePtr<TBusClientConnection, NPrivate::TBusClientConnectionPtrOps>; - -} + +} diff --git a/library/cpp/messagebus/coreconn.cpp b/library/cpp/messagebus/coreconn.cpp index be229a187a..d9411bb5db 100644 --- a/library/cpp/messagebus/coreconn.cpp +++ b/library/cpp/messagebus/coreconn.cpp @@ -1,6 +1,6 @@ #include "coreconn.h" -#include "remote_connection.h" +#include "remote_connection.h" #include <util/datetime/base.h> #include <util/generic/yexception.h> diff --git a/library/cpp/messagebus/coreconn.h b/library/cpp/messagebus/coreconn.h index a910f6f6d7..fca228d82e 100644 --- a/library/cpp/messagebus/coreconn.h +++ b/library/cpp/messagebus/coreconn.h @@ -24,9 +24,9 @@ #include <util/system/thread.h> #include <util/thread/lfqueue.h> -#include <deque> +#include <deque> #include <utility> - + #ifdef NO_ERROR #undef NO_ERROR #endif diff --git a/library/cpp/messagebus/coreconn_ut.cpp b/library/cpp/messagebus/coreconn_ut.cpp index 710a82b75a..beb6850f26 100644 --- a/library/cpp/messagebus/coreconn_ut.cpp +++ b/library/cpp/messagebus/coreconn_ut.cpp @@ -1,25 +1,25 @@ #include <library/cpp/testing/unittest/registar.h> -#include "coreconn.h" - -#include <util/generic/yexception.h> - +#include "coreconn.h" + +#include <util/generic/yexception.h> + Y_UNIT_TEST_SUITE(TMakeIpVersionTest) { - using namespace NBus; - + using namespace NBus; + Y_UNIT_TEST(IpV4Allowed) { - UNIT_ASSERT_EQUAL(MakeIpVersion(true, false), EIP_VERSION_4); - } - + UNIT_ASSERT_EQUAL(MakeIpVersion(true, false), EIP_VERSION_4); + } + Y_UNIT_TEST(IpV6Allowed) { - UNIT_ASSERT_EQUAL(MakeIpVersion(false, true), EIP_VERSION_6); - } - + UNIT_ASSERT_EQUAL(MakeIpVersion(false, true), EIP_VERSION_6); + } + Y_UNIT_TEST(AllAllowed) { - UNIT_ASSERT_EQUAL(MakeIpVersion(true, true), EIP_VERSION_ANY); - } - + UNIT_ASSERT_EQUAL(MakeIpVersion(true, true), EIP_VERSION_ANY); + } + Y_UNIT_TEST(NothingAllowed) { - UNIT_ASSERT_EXCEPTION(MakeIpVersion(false, false), yexception); - } -} + UNIT_ASSERT_EXCEPTION(MakeIpVersion(false, false), yexception); + } +} diff --git a/library/cpp/messagebus/debug_receiver/debug_receiver.cpp b/library/cpp/messagebus/debug_receiver/debug_receiver.cpp index dfd3d0f1c9..23b02d1003 100644 --- a/library/cpp/messagebus/debug_receiver/debug_receiver.cpp +++ b/library/cpp/messagebus/debug_receiver/debug_receiver.cpp @@ -1,42 +1,42 @@ #include "debug_receiver_handler.h" #include "debug_receiver_proto.h" - + #include <library/cpp/messagebus/ybus.h> #include <library/cpp/getopt/last_getopt.h> #include <library/cpp/lwtrace/all.h> - -using namespace NBus; - -int main(int argc, char** argv) { - NLWTrace::StartLwtraceFromEnv(); - - TBusQueueConfig queueConfig; - TBusServerSessionConfig sessionConfig; - - NLastGetopt::TOpts opts; - - queueConfig.ConfigureLastGetopt(opts); - sessionConfig.ConfigureLastGetopt(opts); - - opts.AddLongOption("port").Required().RequiredArgument("PORT").StoreResult(&sessionConfig.ListenPort); - - opts.SetFreeArgsMax(0); - - NLastGetopt::TOptsParseResult r(&opts, argc, argv); - - TBusMessageQueuePtr q(CreateMessageQueue(queueConfig)); - - TDebugReceiverProtocol proto; - TDebugReceiverHandler handler; - - TBusServerSessionPtr serverSession = TBusServerSession::Create(&proto, &handler, sessionConfig, q); - // TODO: race is here - handler.ServerSession = serverSession.Get(); - - for (;;) { - Sleep(TDuration::Hours(17)); - } - - return 0; -} + +using namespace NBus; + +int main(int argc, char** argv) { + NLWTrace::StartLwtraceFromEnv(); + + TBusQueueConfig queueConfig; + TBusServerSessionConfig sessionConfig; + + NLastGetopt::TOpts opts; + + queueConfig.ConfigureLastGetopt(opts); + sessionConfig.ConfigureLastGetopt(opts); + + opts.AddLongOption("port").Required().RequiredArgument("PORT").StoreResult(&sessionConfig.ListenPort); + + opts.SetFreeArgsMax(0); + + NLastGetopt::TOptsParseResult r(&opts, argc, argv); + + TBusMessageQueuePtr q(CreateMessageQueue(queueConfig)); + + TDebugReceiverProtocol proto; + TDebugReceiverHandler handler; + + TBusServerSessionPtr serverSession = TBusServerSession::Create(&proto, &handler, sessionConfig, q); + // TODO: race is here + handler.ServerSession = serverSession.Get(); + + for (;;) { + Sleep(TDuration::Hours(17)); + } + + return 0; +} diff --git a/library/cpp/messagebus/debug_receiver/debug_receiver_handler.cpp b/library/cpp/messagebus/debug_receiver/debug_receiver_handler.cpp index 7490ae17c7..05f99e94ca 100644 --- a/library/cpp/messagebus/debug_receiver/debug_receiver_handler.cpp +++ b/library/cpp/messagebus/debug_receiver/debug_receiver_handler.cpp @@ -1,20 +1,20 @@ #include "debug_receiver_handler.h" - -#include "debug_receiver_proto.h" - + +#include "debug_receiver_proto.h" + #include <util/generic/cast.h> #include <util/string/printf.h> - + void TDebugReceiverHandler::OnError(TAutoPtr<NBus::TBusMessage>, NBus::EMessageStatus status) { - Cerr << "error " << status << "\n"; -} - + Cerr << "error " << status << "\n"; +} + void TDebugReceiverHandler::OnMessage(NBus::TOnMessageContext& message) { - TDebugReceiverMessage* typedMessage = VerifyDynamicCast<TDebugReceiverMessage*>(message.GetMessage()); - Cerr << "type=" << typedMessage->GetHeader()->Type + TDebugReceiverMessage* typedMessage = VerifyDynamicCast<TDebugReceiverMessage*>(message.GetMessage()); + Cerr << "type=" << typedMessage->GetHeader()->Type << " size=" << typedMessage->GetHeader()->Size << " flags=" << Sprintf("0x%04x", (int)typedMessage->GetHeader()->FlagsInternal) << "\n"; - - message.ForgetRequest(); -} + + message.ForgetRequest(); +} diff --git a/library/cpp/messagebus/debug_receiver/debug_receiver_handler.h b/library/cpp/messagebus/debug_receiver/debug_receiver_handler.h index 5a280fb537..0aed6b9984 100644 --- a/library/cpp/messagebus/debug_receiver/debug_receiver_handler.h +++ b/library/cpp/messagebus/debug_receiver/debug_receiver_handler.h @@ -1,10 +1,10 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/ybus.h> - + struct TDebugReceiverHandler: public NBus::IBusServerHandler { - NBus::TBusServerSession* ServerSession; - + NBus::TBusServerSession* ServerSession; + void OnError(TAutoPtr<NBus::TBusMessage> pMessage, NBus::EMessageStatus status) override; void OnMessage(NBus::TOnMessageContext& message) override; -}; +}; diff --git a/library/cpp/messagebus/debug_receiver/debug_receiver_proto.cpp b/library/cpp/messagebus/debug_receiver/debug_receiver_proto.cpp index 50990dae03..0c74f9ecc3 100644 --- a/library/cpp/messagebus/debug_receiver/debug_receiver_proto.cpp +++ b/library/cpp/messagebus/debug_receiver/debug_receiver_proto.cpp @@ -1,20 +1,20 @@ -#include "debug_receiver_proto.h" - -using namespace NBus; - -TDebugReceiverProtocol::TDebugReceiverProtocol() - : TBusProtocol("debug receiver", 0) -{ -} - +#include "debug_receiver_proto.h" + +using namespace NBus; + +TDebugReceiverProtocol::TDebugReceiverProtocol() + : TBusProtocol("debug receiver", 0) +{ +} + void TDebugReceiverProtocol::Serialize(const NBus::TBusMessage*, TBuffer&) { Y_FAIL("it is receiver only"); -} - +} + TAutoPtr<NBus::TBusMessage> TDebugReceiverProtocol::Deserialize(ui16, TArrayRef<const char> payload) { - THolder<TDebugReceiverMessage> r(new TDebugReceiverMessage(ECreateUninitialized())); - - r->Payload.Append(payload.data(), payload.size()); - - return r.Release(); -} + THolder<TDebugReceiverMessage> r(new TDebugReceiverMessage(ECreateUninitialized())); + + r->Payload.Append(payload.data(), payload.size()); + + return r.Release(); +} diff --git a/library/cpp/messagebus/debug_receiver/debug_receiver_proto.h b/library/cpp/messagebus/debug_receiver/debug_receiver_proto.h index 90c01444fb..d34710dcf7 100644 --- a/library/cpp/messagebus/debug_receiver/debug_receiver_proto.h +++ b/library/cpp/messagebus/debug_receiver/debug_receiver_proto.h @@ -1,27 +1,27 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/ybus.h> - + struct TDebugReceiverMessage: public NBus::TBusMessage { - /// constructor to create messages on sending end + /// constructor to create messages on sending end TDebugReceiverMessage(ui16 type) : NBus::TBusMessage(type) { } - - /// constructor with serialzed data to examine the header + + /// constructor with serialzed data to examine the header TDebugReceiverMessage(NBus::ECreateUninitialized) : NBus::TBusMessage(NBus::ECreateUninitialized()) { } - - TBuffer Payload; -}; - + + TBuffer Payload; +}; + struct TDebugReceiverProtocol: public NBus::TBusProtocol { - TDebugReceiverProtocol(); - + TDebugReceiverProtocol(); + void Serialize(const NBus::TBusMessage* mess, TBuffer& data) override; - + TAutoPtr<NBus::TBusMessage> Deserialize(ui16 messageType, TArrayRef<const char> payload) override; -}; +}; diff --git a/library/cpp/messagebus/debug_receiver/ya.make b/library/cpp/messagebus/debug_receiver/ya.make index dd498e41cb..f1b14d35bb 100644 --- a/library/cpp/messagebus/debug_receiver/ya.make +++ b/library/cpp/messagebus/debug_receiver/ya.make @@ -1,17 +1,17 @@ -PROGRAM(messagebus_debug_receiver) - +PROGRAM(messagebus_debug_receiver) + OWNER(g:messagebus) - -SRCS( - debug_receiver.cpp - debug_receiver_proto.cpp - debug_receiver_handler.cpp -) - -PEERDIR( + +SRCS( + debug_receiver.cpp + debug_receiver_proto.cpp + debug_receiver_handler.cpp +) + +PEERDIR( library/cpp/getopt library/cpp/lwtrace library/cpp/messagebus -) - -END() +) + +END() diff --git a/library/cpp/messagebus/defs.h b/library/cpp/messagebus/defs.h index 9d2e000dd6..cb553acc45 100644 --- a/library/cpp/messagebus/defs.h +++ b/library/cpp/messagebus/defs.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include <library/cpp/messagebus/config/defs.h> - + diff --git a/library/cpp/messagebus/dummy_debugger.h b/library/cpp/messagebus/dummy_debugger.h index b614ee94a6..89a4e18716 100644 --- a/library/cpp/messagebus/dummy_debugger.h +++ b/library/cpp/messagebus/dummy_debugger.h @@ -1,9 +1,9 @@ -#pragma once - -#include <util/datetime/base.h> -#include <util/stream/output.h> - +#pragma once + +#include <util/datetime/base.h> +#include <util/stream/output.h> + #define MB_TRACE() \ do { \ - Cerr << TInstant::Now() << " " << __FILE__ << ":" << __LINE__ << " " << __FUNCTION__ << Endl; \ - } while (false) + Cerr << TInstant::Now() << " " << __FILE__ << ":" << __LINE__ << " " << __FUNCTION__ << Endl; \ + } while (false) diff --git a/library/cpp/messagebus/duration_histogram.cpp b/library/cpp/messagebus/duration_histogram.cpp index 5217314776..32a0001d41 100644 --- a/library/cpp/messagebus/duration_histogram.cpp +++ b/library/cpp/messagebus/duration_histogram.cpp @@ -1,74 +1,74 @@ #include "duration_histogram.h" #include <util/generic/singleton.h> -#include <util/stream/str.h> - -namespace { - ui64 SecondsRound(TDuration d) { - if (d.MilliSeconds() % 1000 >= 500) { - return d.Seconds() + 1; - } else { - return d.Seconds(); - } - } - - ui64 MilliSecondsRound(TDuration d) { - if (d.MicroSeconds() % 1000 >= 500) { - return d.MilliSeconds() + 1; - } else { - return d.MilliSeconds(); - } - } - - ui64 MinutesRound(TDuration d) { - if (d.Seconds() % 60 >= 30) { - return d.Minutes() + 1; - } else { - return d.Minutes(); - } - } - -} - -namespace { - struct TMarks { +#include <util/stream/str.h> + +namespace { + ui64 SecondsRound(TDuration d) { + if (d.MilliSeconds() % 1000 >= 500) { + return d.Seconds() + 1; + } else { + return d.Seconds(); + } + } + + ui64 MilliSecondsRound(TDuration d) { + if (d.MicroSeconds() % 1000 >= 500) { + return d.MilliSeconds() + 1; + } else { + return d.MilliSeconds(); + } + } + + ui64 MinutesRound(TDuration d) { + if (d.Seconds() % 60 >= 30) { + return d.Minutes() + 1; + } else { + return d.Minutes(); + } + } + +} + +namespace { + struct TMarks { std::array<TDuration, TDurationHistogram::Buckets> Marks; - - TMarks() { - Marks[0] = TDuration::Zero(); - for (unsigned i = 1; i < TDurationHistogram::Buckets; ++i) { - if (i >= TDurationHistogram::SecondBoundary) { - Marks[i] = TDuration::Seconds(1) * (1 << (i - TDurationHistogram::SecondBoundary)); - } else { - Marks[i] = TDuration::Seconds(1) / (1 << (TDurationHistogram::SecondBoundary - i)); - } - } - } - }; -} - + + TMarks() { + Marks[0] = TDuration::Zero(); + for (unsigned i = 1; i < TDurationHistogram::Buckets; ++i) { + if (i >= TDurationHistogram::SecondBoundary) { + Marks[i] = TDuration::Seconds(1) * (1 << (i - TDurationHistogram::SecondBoundary)); + } else { + Marks[i] = TDuration::Seconds(1) / (1 << (TDurationHistogram::SecondBoundary - i)); + } + } + } + }; +} + TString TDurationHistogram::LabelBefore(unsigned i) { Y_VERIFY(i < Buckets); - - TDuration d = Singleton<TMarks>()->Marks[i]; - - TStringStream ss; - if (d == TDuration::Zero()) { - ss << "0"; - } else if (d < TDuration::Seconds(1)) { - ss << MilliSecondsRound(d) << "ms"; - } else if (d < TDuration::Minutes(1)) { - ss << SecondsRound(d) << "s"; - } else { - ss << MinutesRound(d) << "m"; - } - return ss.Str(); -} - + + TDuration d = Singleton<TMarks>()->Marks[i]; + + TStringStream ss; + if (d == TDuration::Zero()) { + ss << "0"; + } else if (d < TDuration::Seconds(1)) { + ss << MilliSecondsRound(d) << "ms"; + } else if (d < TDuration::Minutes(1)) { + ss << SecondsRound(d) << "s"; + } else { + ss << MinutesRound(d) << "m"; + } + return ss.Str(); +} + TString TDurationHistogram::PrintToString() const { - TStringStream ss; + TStringStream ss; for (auto time : Times) { ss << time << "\n"; - } - return ss.Str(); -} + } + return ss.Str(); +} diff --git a/library/cpp/messagebus/duration_histogram.h b/library/cpp/messagebus/duration_histogram.h index bda8c85704..ed060b0101 100644 --- a/library/cpp/messagebus/duration_histogram.h +++ b/library/cpp/messagebus/duration_histogram.h @@ -1,45 +1,45 @@ -#pragma once - -#include <util/datetime/base.h> +#pragma once + +#include <util/datetime/base.h> #include <util/generic/bitops.h> #include <util/generic/string.h> - + #include <array> - -struct TDurationHistogram { - static const unsigned Buckets = 20; + +struct TDurationHistogram { + static const unsigned Buckets = 20; std::array<ui64, Buckets> Times; - - static const unsigned SecondBoundary = 11; - - TDurationHistogram() { + + static const unsigned SecondBoundary = 11; + + TDurationHistogram() { Times.fill(0); - } - - static unsigned BucketFor(TDuration d) { - ui64 units = d.MicroSeconds() * (1 << SecondBoundary) / 1000000; - if (units == 0) { - return 0; - } - unsigned bucket = GetValueBitCount(units) - 1; - if (bucket >= Buckets) { - bucket = Buckets - 1; - } - return bucket; - } - - void AddTime(TDuration d) { - Times[BucketFor(d)] += 1; - } - - TDurationHistogram& operator+=(const TDurationHistogram& that) { - for (unsigned i = 0; i < Times.size(); ++i) { - Times[i] += that.Times[i]; - } - return *this; - } - + } + + static unsigned BucketFor(TDuration d) { + ui64 units = d.MicroSeconds() * (1 << SecondBoundary) / 1000000; + if (units == 0) { + return 0; + } + unsigned bucket = GetValueBitCount(units) - 1; + if (bucket >= Buckets) { + bucket = Buckets - 1; + } + return bucket; + } + + void AddTime(TDuration d) { + Times[BucketFor(d)] += 1; + } + + TDurationHistogram& operator+=(const TDurationHistogram& that) { + for (unsigned i = 0; i < Times.size(); ++i) { + Times[i] += that.Times[i]; + } + return *this; + } + static TString LabelBefore(unsigned i); - + TString PrintToString() const; -}; +}; diff --git a/library/cpp/messagebus/duration_histogram_ut.cpp b/library/cpp/messagebus/duration_histogram_ut.cpp index 5e2a194b6d..01bcc095e9 100644 --- a/library/cpp/messagebus/duration_histogram_ut.cpp +++ b/library/cpp/messagebus/duration_histogram_ut.cpp @@ -1,38 +1,38 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "duration_histogram.h" - + +#include "duration_histogram.h" + Y_UNIT_TEST_SUITE(TDurationHistogramTest) { Y_UNIT_TEST(BucketFor) { UNIT_ASSERT_VALUES_EQUAL(0u, TDurationHistogram::BucketFor(TDuration::MicroSeconds(0))); UNIT_ASSERT_VALUES_EQUAL(0u, TDurationHistogram::BucketFor(TDuration::MicroSeconds(1))); UNIT_ASSERT_VALUES_EQUAL(0u, TDurationHistogram::BucketFor(TDuration::MicroSeconds(900))); - UNIT_ASSERT_VALUES_EQUAL(1u, TDurationHistogram::BucketFor(TDuration::MicroSeconds(1500))); - UNIT_ASSERT_VALUES_EQUAL(2u, TDurationHistogram::BucketFor(TDuration::MicroSeconds(2500))); - - unsigned sb = TDurationHistogram::SecondBoundary; - + UNIT_ASSERT_VALUES_EQUAL(1u, TDurationHistogram::BucketFor(TDuration::MicroSeconds(1500))); + UNIT_ASSERT_VALUES_EQUAL(2u, TDurationHistogram::BucketFor(TDuration::MicroSeconds(2500))); + + unsigned sb = TDurationHistogram::SecondBoundary; + UNIT_ASSERT_VALUES_EQUAL(sb - 1, TDurationHistogram::BucketFor(TDuration::MilliSeconds(999))); - UNIT_ASSERT_VALUES_EQUAL(sb, TDurationHistogram::BucketFor(TDuration::MilliSeconds(1000))); - UNIT_ASSERT_VALUES_EQUAL(sb, TDurationHistogram::BucketFor(TDuration::MilliSeconds(1001))); - - UNIT_ASSERT_VALUES_EQUAL(TDurationHistogram::Buckets - 1, TDurationHistogram::BucketFor(TDuration::Hours(1))); - } - + UNIT_ASSERT_VALUES_EQUAL(sb, TDurationHistogram::BucketFor(TDuration::MilliSeconds(1000))); + UNIT_ASSERT_VALUES_EQUAL(sb, TDurationHistogram::BucketFor(TDuration::MilliSeconds(1001))); + + UNIT_ASSERT_VALUES_EQUAL(TDurationHistogram::Buckets - 1, TDurationHistogram::BucketFor(TDuration::Hours(1))); + } + Y_UNIT_TEST(Simple) { - TDurationHistogram h1; - h1.AddTime(TDuration::MicroSeconds(1)); - UNIT_ASSERT_VALUES_EQUAL(1u, h1.Times.front()); - - TDurationHistogram h2; - h1.AddTime(TDuration::Hours(1)); - UNIT_ASSERT_VALUES_EQUAL(1u, h1.Times.back()); - } - + TDurationHistogram h1; + h1.AddTime(TDuration::MicroSeconds(1)); + UNIT_ASSERT_VALUES_EQUAL(1u, h1.Times.front()); + + TDurationHistogram h2; + h1.AddTime(TDuration::Hours(1)); + UNIT_ASSERT_VALUES_EQUAL(1u, h1.Times.back()); + } + Y_UNIT_TEST(LabelFor) { - for (unsigned i = 0; i < TDurationHistogram::Buckets; ++i) { - TDurationHistogram::LabelBefore(i); - //Cerr << TDurationHistogram::LabelBefore(i) << "\n"; - } - } -} + for (unsigned i = 0; i < TDurationHistogram::Buckets; ++i) { + TDurationHistogram::LabelBefore(i); + //Cerr << TDurationHistogram::LabelBefore(i) << "\n"; + } + } +} diff --git a/library/cpp/messagebus/event_loop.cpp b/library/cpp/messagebus/event_loop.cpp index b82bd023e5..f685135bed 100644 --- a/library/cpp/messagebus/event_loop.cpp +++ b/library/cpp/messagebus/event_loop.cpp @@ -1,8 +1,8 @@ #include "event_loop.h" - + #include "network.h" -#include "thread_extra.h" - +#include "thread_extra.h" + #include <util/generic/hash.h> #include <util/network/pair.h> #include <util/network/poller.h> @@ -10,19 +10,19 @@ #include <util/system/mutex.h> #include <util/system/thread.h> #include <util/system/yassert.h> -#include <util/thread/lfqueue.h> +#include <util/thread/lfqueue.h> #include <errno.h> - + using namespace NEventLoop; namespace { - enum ERunningState { - EVENT_LOOP_CREATED, - EVENT_LOOP_RUNNING, - EVENT_LOOP_STOPPED, - }; - + enum ERunningState { + EVENT_LOOP_CREATED, + EVENT_LOOP_RUNNING, + EVENT_LOOP_STOPPED, + }; + enum EOperation { OP_READ = 1, OP_WRITE = 2, @@ -32,8 +32,8 @@ namespace { class TChannel::TImpl { public: - TImpl(TEventLoop::TImpl* eventLoop, TSocket socket, TEventHandlerPtr, void* cookie); - ~TImpl(); + TImpl(TEventLoop::TImpl* eventLoop, TSocket socket, TEventHandlerPtr, void* cookie); + ~TImpl(); void EnableRead(); void DisableRead(); @@ -43,48 +43,48 @@ public: void Unregister(); SOCKET GetSocket() const; - TSocket GetSocketPtr() const; + TSocket GetSocketPtr() const; + + void Update(int pollerFlags, bool enable); + void CallHandler(); - void Update(int pollerFlags, bool enable); - void CallHandler(); - TEventLoop::TImpl* EventLoop; - TSocket Socket; - TEventHandlerPtr EventHandler; - void* Cookie; - - TMutex Mutex; - - int CurrentFlags; - bool Close; + TSocket Socket; + TEventHandlerPtr EventHandler; + void* Cookie; + + TMutex Mutex; + + int CurrentFlags; + bool Close; }; class TEventLoop::TImpl { public: - TImpl(const char* name); + TImpl(const char* name); void Run(); void Wakeup(); void Stop(); - TChannelPtr Register(TSocket socket, TEventHandlerPtr eventHandler, void* cookie); + TChannelPtr Register(TSocket socket, TEventHandlerPtr eventHandler, void* cookie); void Unregister(SOCKET socket); typedef THashMap<SOCKET, TChannelPtr> TData; - void AddToPoller(SOCKET socket, void* cookie, int flags); + void AddToPoller(SOCKET socket, void* cookie, int flags); - TMutex Mutex; + TMutex Mutex; + + const char* Name; - const char* Name; - TAtomic RunningState; TAtomic StopSignal; TSystemEvent StoppedEvent; TData Data; - TLockFreeQueue<SOCKET> SocketsToRemove; - + TLockFreeQueue<SOCKET> SocketsToRemove; + TSocketPoller Poller; TSocketHolder WakeupReadSocket; TSocketHolder WakeupWriteSocket; @@ -117,17 +117,17 @@ SOCKET TChannel::GetSocket() const { return Impl->GetSocket(); } -TSocket TChannel::GetSocketPtr() const { - return Impl->GetSocketPtr(); -} - -TChannel::TChannel(TImpl* impl) - : Impl(impl) +TSocket TChannel::GetSocketPtr() const { + return Impl->GetSocketPtr(); +} + +TChannel::TChannel(TImpl* impl) + : Impl(impl) { } -TEventLoop::TEventLoop(const char* name) - : Impl(new TImpl(name)) +TEventLoop::TEventLoop(const char* name) + : Impl(new TImpl(name)) { } @@ -142,126 +142,126 @@ void TEventLoop::Stop() { Impl->Stop(); } -bool TEventLoop::IsRunning() { +bool TEventLoop::IsRunning() { return AtomicGet(Impl->RunningState) == EVENT_LOOP_RUNNING; -} - -TChannelPtr TEventLoop::Register(TSocket socket, TEventHandlerPtr eventHandler, void* cookie) { - return Impl->Register(socket, eventHandler, cookie); } -TChannel::TImpl::TImpl(TEventLoop::TImpl* eventLoop, TSocket socket, TEventHandlerPtr eventHandler, void* cookie) +TChannelPtr TEventLoop::Register(TSocket socket, TEventHandlerPtr eventHandler, void* cookie) { + return Impl->Register(socket, eventHandler, cookie); +} + +TChannel::TImpl::TImpl(TEventLoop::TImpl* eventLoop, TSocket socket, TEventHandlerPtr eventHandler, void* cookie) : EventLoop(eventLoop) , Socket(socket) - , EventHandler(eventHandler) - , Cookie(cookie) - , CurrentFlags(0) - , Close(false) + , EventHandler(eventHandler) + , Cookie(cookie) + , CurrentFlags(0) + , Close(false) { } -TChannel::TImpl::~TImpl() { +TChannel::TImpl::~TImpl() { Y_ASSERT(Close); -} - +} + void TChannel::TImpl::EnableRead() { - Update(OP_READ, true); + Update(OP_READ, true); } void TChannel::TImpl::DisableRead() { - Update(OP_READ, false); + Update(OP_READ, false); } void TChannel::TImpl::EnableWrite() { - Update(OP_WRITE, true); + Update(OP_WRITE, true); } void TChannel::TImpl::DisableWrite() { - Update(OP_WRITE, false); + Update(OP_WRITE, false); } void TChannel::TImpl::Unregister() { - TGuard<TMutex> guard(Mutex); - - if (Close) { - return; - } - - Close = true; - if (CurrentFlags != 0) { - EventLoop->Poller.Unwait(Socket); - CurrentFlags = 0; - } - EventHandler.Drop(); - - EventLoop->SocketsToRemove.Enqueue(Socket); - EventLoop->Wakeup(); -} - -void TChannel::TImpl::Update(int flags, bool enable) { - TGuard<TMutex> guard(Mutex); - - if (Close) { - return; - } - - int newFlags = enable ? (CurrentFlags | flags) : (CurrentFlags & ~flags); - - if (CurrentFlags == newFlags) { - return; - } - - if (!newFlags) { - EventLoop->Poller.Unwait(Socket); - } else { - void* cookie = reinterpret_cast<void*>(this); - EventLoop->AddToPoller(Socket, cookie, newFlags); - } - - CurrentFlags = newFlags; -} - + TGuard<TMutex> guard(Mutex); + + if (Close) { + return; + } + + Close = true; + if (CurrentFlags != 0) { + EventLoop->Poller.Unwait(Socket); + CurrentFlags = 0; + } + EventHandler.Drop(); + + EventLoop->SocketsToRemove.Enqueue(Socket); + EventLoop->Wakeup(); +} + +void TChannel::TImpl::Update(int flags, bool enable) { + TGuard<TMutex> guard(Mutex); + + if (Close) { + return; + } + + int newFlags = enable ? (CurrentFlags | flags) : (CurrentFlags & ~flags); + + if (CurrentFlags == newFlags) { + return; + } + + if (!newFlags) { + EventLoop->Poller.Unwait(Socket); + } else { + void* cookie = reinterpret_cast<void*>(this); + EventLoop->AddToPoller(Socket, cookie, newFlags); + } + + CurrentFlags = newFlags; +} + SOCKET TChannel::TImpl::GetSocket() const { return Socket; } -TSocket TChannel::TImpl::GetSocketPtr() const { - return Socket; -} - -void TChannel::TImpl::CallHandler() { - TEventHandlerPtr handler; - - { - TGuard<TMutex> guard(Mutex); - - // other thread may have re-added socket to epoll - // so even if CurrentFlags is 0, epoll may fire again - // so please use non-blocking operations - CurrentFlags = 0; - - if (Close) { - return; - } - - handler = EventHandler; - } - - if (!!handler) { - handler->HandleEvent(Socket, Cookie); - } -} - -TEventLoop::TImpl::TImpl(const char* name) - : Name(name) - , RunningState(EVENT_LOOP_CREATED) +TSocket TChannel::TImpl::GetSocketPtr() const { + return Socket; +} + +void TChannel::TImpl::CallHandler() { + TEventHandlerPtr handler; + + { + TGuard<TMutex> guard(Mutex); + + // other thread may have re-added socket to epoll + // so even if CurrentFlags is 0, epoll may fire again + // so please use non-blocking operations + CurrentFlags = 0; + + if (Close) { + return; + } + + handler = EventHandler; + } + + if (!!handler) { + handler->HandleEvent(Socket, Cookie); + } +} + +TEventLoop::TImpl::TImpl(const char* name) + : Name(name) + , RunningState(EVENT_LOOP_CREATED) , StopSignal(0) { SOCKET wakeupSockets[2]; - if (SocketPair(wakeupSockets) < 0) { + if (SocketPair(wakeupSockets) < 0) { Y_FAIL("failed to create socket pair for wakeup sockets: %s", LastSystemErrorText()); - } + } TSocketHolder wakeupReadSocket(wakeupSockets[0]); TSocketHolder wakeupWriteSocket(wakeupSockets[1]); @@ -279,91 +279,91 @@ TEventLoop::TImpl::TImpl(const char* name) void TEventLoop::TImpl::Run() { bool res = AtomicCas(&RunningState, EVENT_LOOP_RUNNING, EVENT_LOOP_CREATED); Y_VERIFY(res, "Invalid mbus event loop state"); - - if (!!Name) { + + if (!!Name) { SetCurrentThreadName(Name); - } - + } + while (AtomicGet(StopSignal) == 0) { void* cookies[1024]; const size_t count = Poller.WaitI(cookies, Y_ARRAY_SIZE(cookies)); void** end = cookies + count; for (void** c = cookies; c != end; ++c) { - TChannel::TImpl* s = reinterpret_cast<TChannel::TImpl*>(*c); + TChannel::TImpl* s = reinterpret_cast<TChannel::TImpl*>(*c); - if (*c == this) { + if (*c == this) { char buf[0x1000]; - if (NBus::NPrivate::SocketRecv(WakeupReadSocket, buf) < 0) { + if (NBus::NPrivate::SocketRecv(WakeupReadSocket, buf) < 0) { Y_FAIL("failed to recv from wakeup socket: %s", LastSystemErrorText()); - } + } continue; } - s->CallHandler(); + s->CallHandler(); } - + SOCKET socket = -1; while (SocketsToRemove.Dequeue(&socket)) { - TGuard<TMutex> guard(Mutex); + TGuard<TMutex> guard(Mutex); Y_VERIFY(Data.erase(socket) == 1, "must be removed once"); - } + } } - - { - TGuard<TMutex> guard(Mutex); + + { + TGuard<TMutex> guard(Mutex); for (auto& it : Data) { it.second->Unregister(); - } - - // release file descriptors - Data.clear(); - } - + } + + // release file descriptors + Data.clear(); + } + res = AtomicCas(&RunningState, EVENT_LOOP_STOPPED, EVENT_LOOP_RUNNING); - + Y_VERIFY(res); - StoppedEvent.Signal(); + StoppedEvent.Signal(); } void TEventLoop::TImpl::Stop() { AtomicSet(StopSignal, 1); - + if (AtomicGet(RunningState) == EVENT_LOOP_RUNNING) { Wakeup(); - + StoppedEvent.WaitI(); } } -TChannelPtr TEventLoop::TImpl::Register(TSocket socket, TEventHandlerPtr eventHandler, void* cookie) { +TChannelPtr TEventLoop::TImpl::Register(TSocket socket, TEventHandlerPtr eventHandler, void* cookie) { Y_VERIFY(socket != INVALID_SOCKET, "must be a valid socket"); - - TChannelPtr channel = new TChannel(new TChannel::TImpl(this, socket, eventHandler, cookie)); - TGuard<TMutex> guard(Mutex); + TChannelPtr channel = new TChannel(new TChannel::TImpl(this, socket, eventHandler, cookie)); + + TGuard<TMutex> guard(Mutex); Y_VERIFY(Data.insert(std::make_pair(socket, channel)).second, "must not be already inserted"); - return channel; + return channel; } void TEventLoop::TImpl::Wakeup() { if (NBus::NPrivate::SocketSend(WakeupWriteSocket, TArrayRef<const char>("", 1)) < 0) { - if (LastSystemError() != EAGAIN) { + if (LastSystemError() != EAGAIN) { Y_FAIL("failed to send to wakeup socket: %s", LastSystemErrorText()); - } + } } } void TEventLoop::TImpl::AddToPoller(SOCKET socket, void* cookie, int flags) { if (flags == OP_READ) { - Poller.WaitReadOneShot(socket, cookie); + Poller.WaitReadOneShot(socket, cookie); } else if (flags == OP_WRITE) { - Poller.WaitWriteOneShot(socket, cookie); + Poller.WaitWriteOneShot(socket, cookie); } else if (flags == OP_READ_WRITE) { - Poller.WaitReadWriteOneShot(socket, cookie); + Poller.WaitReadWriteOneShot(socket, cookie); } else { Y_FAIL("Wrong flags: %d", int(flags)); } diff --git a/library/cpp/messagebus/event_loop.h b/library/cpp/messagebus/event_loop.h index b313ba02a4..d5b0a53b0c 100644 --- a/library/cpp/messagebus/event_loop.h +++ b/library/cpp/messagebus/event_loop.h @@ -3,12 +3,12 @@ #include <util/generic/object_counter.h> #include <util/generic/ptr.h> #include <util/network/init.h> -#include <util/network/socket.h> +#include <util/network/socket.h> namespace NEventLoop { struct IEventHandler : public TAtomicRefCount<IEventHandler> { - virtual void HandleEvent(SOCKET socket, void* cookie) = 0; + virtual void HandleEvent(SOCKET socket, void* cookie) = 0; virtual ~IEventHandler() { } }; @@ -17,8 +17,8 @@ namespace NEventLoop { class TEventLoop; - // TODO: make TChannel itself a pointer - // to avoid confusion with Drop and Unregister + // TODO: make TChannel itself a pointer + // to avoid confusion with Drop and Unregister class TChannel : public TAtomicRefCount<TChannel> { public: @@ -32,15 +32,15 @@ namespace NEventLoop { void Unregister(); SOCKET GetSocket() const; - TSocket GetSocketPtr() const; + TSocket GetSocketPtr() const; private: class TImpl; friend class TEventLoop; - TObjectCounter<TChannel> ObjectCounter; - - TChannel(TImpl*); + TObjectCounter<TChannel> ObjectCounter; + + TChannel(TImpl*); private: THolder<TImpl> Impl; @@ -55,7 +55,7 @@ namespace NEventLoop { void Run(); void Stop(); - bool IsRunning(); + bool IsRunning(); TChannelPtr Register(TSocket socket, TEventHandlerPtr, void* cookie = nullptr); @@ -63,8 +63,8 @@ namespace NEventLoop { class TImpl; friend class TChannel; - TObjectCounter<TEventLoop> ObjectCounter; - + TObjectCounter<TEventLoop> ObjectCounter; + private: THolder<TImpl> Impl; }; diff --git a/library/cpp/messagebus/extra_ref.h b/library/cpp/messagebus/extra_ref.h index d20b9b6aa1..2927123266 100644 --- a/library/cpp/messagebus/extra_ref.h +++ b/library/cpp/messagebus/extra_ref.h @@ -1,36 +1,36 @@ -#pragma once - -#include <util/system/yassert.h> - -class TExtraRef { - TAtomic Holds; - -public: +#pragma once + +#include <util/system/yassert.h> + +class TExtraRef { + TAtomic Holds; + +public: TExtraRef() : Holds(false) { } - ~TExtraRef() { + ~TExtraRef() { Y_VERIFY(!Holds); - } - - template <typename TThis> - void Retain(TThis* thiz) { - if (AtomicGet(Holds)) { - return; - } - if (AtomicCas(&Holds, 1, 0)) { - thiz->Ref(); - } - } - - template <typename TThis> - void Release(TThis* thiz) { - if (!AtomicGet(Holds)) { - return; - } - if (AtomicCas(&Holds, 0, 1)) { - thiz->UnRef(); - } - } -}; + } + + template <typename TThis> + void Retain(TThis* thiz) { + if (AtomicGet(Holds)) { + return; + } + if (AtomicCas(&Holds, 1, 0)) { + thiz->Ref(); + } + } + + template <typename TThis> + void Release(TThis* thiz) { + if (!AtomicGet(Holds)) { + return; + } + if (AtomicCas(&Holds, 0, 1)) { + thiz->UnRef(); + } + } +}; diff --git a/library/cpp/messagebus/futex_like.cpp b/library/cpp/messagebus/futex_like.cpp index c0d5b4f4ec..7f965126db 100644 --- a/library/cpp/messagebus/futex_like.cpp +++ b/library/cpp/messagebus/futex_like.cpp @@ -1,55 +1,55 @@ -#include <util/system/platform.h> - -#ifdef _linux_ -#include <sys/syscall.h> -#include <linux/futex.h> +#include <util/system/platform.h> + +#ifdef _linux_ +#include <sys/syscall.h> +#include <linux/futex.h> #if !defined(SYS_futex) #define SYS_futex __NR_futex -#endif #endif - -#include <errno.h> - -#include <util/system/yassert.h> - -#include "futex_like.h" - -#ifdef _linux_ -namespace { +#endif + +#include <errno.h> + +#include <util/system/yassert.h> + +#include "futex_like.h" + +#ifdef _linux_ +namespace { int futex(int* uaddr, int op, int val, const struct timespec* timeout, int* uaddr2, int val3) { - return syscall(SYS_futex, uaddr, op, val, timeout, uaddr2, val3); - } -} -#endif - -void TFutexLike::Wake(size_t count) { + return syscall(SYS_futex, uaddr, op, val, timeout, uaddr2, val3); + } +} +#endif + +void TFutexLike::Wake(size_t count) { Y_ASSERT(count > 0); -#ifdef _linux_ - if (count > unsigned(Max<int>())) { - count = Max<int>(); - } +#ifdef _linux_ + if (count > unsigned(Max<int>())) { + count = Max<int>(); + } int r = futex(&Value, FUTEX_WAKE, count, nullptr, nullptr, 0); Y_VERIFY(r >= 0, "futex_wake failed: %s", strerror(errno)); -#else - TGuard<TMutex> guard(Mutex); - if (count == 1) { - CondVar.Signal(); - } else { - CondVar.BroadCast(); - } -#endif -} - -void TFutexLike::Wait(int expected) { -#ifdef _linux_ +#else + TGuard<TMutex> guard(Mutex); + if (count == 1) { + CondVar.Signal(); + } else { + CondVar.BroadCast(); + } +#endif +} + +void TFutexLike::Wait(int expected) { +#ifdef _linux_ int r = futex(&Value, FUTEX_WAIT, expected, nullptr, nullptr, 0); Y_VERIFY(r >= 0 || errno == EWOULDBLOCK, "futex_wait failed: %s", strerror(errno)); -#else - TGuard<TMutex> guard(Mutex); - if (expected == Get()) { - CondVar.WaitI(Mutex); - } -#endif -} +#else + TGuard<TMutex> guard(Mutex); + if (expected == Get()) { + CondVar.WaitI(Mutex); + } +#endif +} diff --git a/library/cpp/messagebus/futex_like.h b/library/cpp/messagebus/futex_like.h index d4ac486caf..31d60c60f1 100644 --- a/library/cpp/messagebus/futex_like.h +++ b/library/cpp/messagebus/futex_like.h @@ -1,86 +1,86 @@ -#pragma once - +#pragma once + #include <util/system/condvar.h> #include <util/system/mutex.h> -#include <util/system/platform.h> - -class TFutexLike { -private: -#ifdef _linux_ - int Value; -#else - TAtomic Value; - TMutex Mutex; - TCondVar CondVar; -#endif - -public: - TFutexLike() - : Value(0) +#include <util/system/platform.h> + +class TFutexLike { +private: +#ifdef _linux_ + int Value; +#else + TAtomic Value; + TMutex Mutex; + TCondVar CondVar; +#endif + +public: + TFutexLike() + : Value(0) { } - - int AddAndGet(int add) { -#ifdef _linux_ - //return __atomic_add_fetch(&Value, add, __ATOMIC_SEQ_CST); - return __sync_add_and_fetch(&Value, add); -#else - return AtomicAdd(Value, add); -#endif - } - - int GetAndAdd(int add) { - return AddAndGet(add) - add; - } - -// until we have modern GCC -#if 0 - int GetAndSet(int newValue) { -#ifdef _linux_ - return __atomic_exchange_n(&Value, newValue, __ATOMIC_SEQ_CST); -#else + + int AddAndGet(int add) { +#ifdef _linux_ + //return __atomic_add_fetch(&Value, add, __ATOMIC_SEQ_CST); + return __sync_add_and_fetch(&Value, add); +#else + return AtomicAdd(Value, add); +#endif + } + + int GetAndAdd(int add) { + return AddAndGet(add) - add; + } + +// until we have modern GCC +#if 0 + int GetAndSet(int newValue) { +#ifdef _linux_ + return __atomic_exchange_n(&Value, newValue, __ATOMIC_SEQ_CST); +#else return AtomicSwap(&Value, newValue); -#endif - } -#endif - - int Get() { -#ifdef _linux_ - //return __atomic_load_n(&Value, __ATOMIC_SEQ_CST); - __sync_synchronize(); - return Value; -#else - return AtomicGet(Value); -#endif - } - - void Set(int newValue) { -#ifdef _linux_ - //__atomic_store_n(&Value, newValue, __ATOMIC_SEQ_CST); - Value = newValue; - __sync_synchronize(); -#else - AtomicSet(Value, newValue); -#endif - } - - int GetAndIncrement() { - return AddAndGet(1) - 1; - } - - int IncrementAndGet() { - return AddAndGet(1); - } - - int GetAndDecrement() { - return AddAndGet(-1) + 1; - } - - int DecrementAndGet() { - return AddAndGet(-1); - } - - void Wake(size_t count = Max<size_t>()); - - void Wait(int expected); -}; +#endif + } +#endif + + int Get() { +#ifdef _linux_ + //return __atomic_load_n(&Value, __ATOMIC_SEQ_CST); + __sync_synchronize(); + return Value; +#else + return AtomicGet(Value); +#endif + } + + void Set(int newValue) { +#ifdef _linux_ + //__atomic_store_n(&Value, newValue, __ATOMIC_SEQ_CST); + Value = newValue; + __sync_synchronize(); +#else + AtomicSet(Value, newValue); +#endif + } + + int GetAndIncrement() { + return AddAndGet(1) - 1; + } + + int IncrementAndGet() { + return AddAndGet(1); + } + + int GetAndDecrement() { + return AddAndGet(-1) + 1; + } + + int DecrementAndGet() { + return AddAndGet(-1); + } + + void Wake(size_t count = Max<size_t>()); + + void Wait(int expected); +}; diff --git a/library/cpp/messagebus/handler.cpp b/library/cpp/messagebus/handler.cpp index ec12bf0b8f..333bd52934 100644 --- a/library/cpp/messagebus/handler.cpp +++ b/library/cpp/messagebus/handler.cpp @@ -1,11 +1,11 @@ -#include "handler.h" +#include "handler.h" #include "remote_server_connection.h" #include "ybus.h" - -using namespace NBus; -using namespace NBus::NPrivate; - + +using namespace NBus; +using namespace NBus::NPrivate; + void IBusErrorHandler::OnError(TAutoPtr<TBusMessage> pMessage, EMessageStatus status) { Y_UNUSED(pMessage); Y_UNUSED(status); @@ -19,17 +19,17 @@ void IBusClientHandler::OnMessageSent(TBusMessage* pMessage) { void IBusClientHandler::OnMessageSentOneWay(TAutoPtr<TBusMessage> pMessage) { Y_UNUSED(pMessage); } - + void IBusClientHandler::OnClientConnectionEvent(const TClientConnectionEvent&) { } - + void TOnMessageContext::ForgetRequest() { - Session->ForgetRequest(Ident); -} - + Session->ForgetRequest(Ident); +} + TNetAddr TOnMessageContext::GetPeerAddrNetAddr() const { - return Ident.GetNetAddr(); -} + return Ident.GetNetAddr(); +} bool TOnMessageContext::IsConnectionAlive() const { return !!Ident.Connection && Ident.Connection->IsAlive(); diff --git a/library/cpp/messagebus/handler.h b/library/cpp/messagebus/handler.h index d9df33814b..60002c68a6 100644 --- a/library/cpp/messagebus/handler.h +++ b/library/cpp/messagebus/handler.h @@ -1,44 +1,44 @@ -#pragma once - -#include "defs.h" +#pragma once + +#include "defs.h" #include "message.h" -#include "message_status.h" -#include "use_after_free_checker.h" -#include "use_count_checker.h" - +#include "message_status.h" +#include "use_after_free_checker.h" +#include "use_count_checker.h" + #include <util/generic/noncopyable.h> -namespace NBus { +namespace NBus { ///////////////////////////////////////////////////////////////// /// \brief Interface to message bus handler - + struct IBusErrorHandler { friend struct ::NBus::NPrivate::TBusSessionImpl; - + private: TUseAfterFreeChecker UseAfterFreeChecker; TUseCountChecker UseCountChecker; - + public: /// called when message or reply can't be delivered virtual void OnError(TAutoPtr<TBusMessage> pMessage, EMessageStatus status); - + virtual ~IBusErrorHandler() { } }; - + class TClientConnectionEvent { public: enum EType { CONNECTED, DISCONNECTED, }; - + private: EType Type; ui64 Id; TNetAddr Addr; - + public: TClientConnectionEvent(EType type, ui64 id, TNetAddr addr) : Type(type) @@ -56,15 +56,15 @@ namespace NBus { TNetAddr GetAddr() const { return Addr; } - }; - + }; + class TOnMessageContext : TNonCopyable { private: THolder<TBusMessage> Message; TBusIdentity Ident; // TODO: we don't need to store session, we have connection in ident TBusServerSession* Session; - + public: TOnMessageContext() : Session() @@ -76,53 +76,53 @@ namespace NBus { { Ident.Swap(ident); } - + bool IsInWork() const { return Ident.IsInWork(); } - + bool operator!() const { return !IsInWork(); } - + TBusMessage* GetMessage() { return Message.Get(); } - + TBusMessage* ReleaseMessage() { return Message.Release(); } - + TBusServerSession* GetSession() { return Session; } - + template <typename U /* <: TBusMessage */> EMessageStatus SendReplyAutoPtr(TAutoPtr<U>& rep); - + EMessageStatus SendReplyMove(TBusMessageAutoPtr response); - + void AckMessage(TBusIdentity& ident); - + void ForgetRequest(); - + void Swap(TOnMessageContext& that) { DoSwap(Message, that.Message); Ident.Swap(that.Ident); DoSwap(Session, that.Session); } - + TNetAddr GetPeerAddrNetAddr() const; bool IsConnectionAlive() const; }; - + struct IBusServerHandler: public IBusErrorHandler { virtual void OnMessage(TOnMessageContext& onMessage) = 0; /// called when reply has been sent from destination virtual void OnSent(TAutoPtr<TBusMessage> pMessage); }; - + struct IBusClientHandler: public IBusErrorHandler { /// called on source when reply arrives from destination virtual void OnReply(TAutoPtr<TBusMessage> pMessage, TAutoPtr<TBusMessage> pReply) = 0; @@ -131,5 +131,5 @@ namespace NBus { virtual void OnMessageSentOneWay(TAutoPtr<TBusMessage> pMessage); virtual void OnClientConnectionEvent(const TClientConnectionEvent&); }; - + } diff --git a/library/cpp/messagebus/handler_impl.h b/library/cpp/messagebus/handler_impl.h index f260767b47..6593f04cc3 100644 --- a/library/cpp/messagebus/handler_impl.h +++ b/library/cpp/messagebus/handler_impl.h @@ -1,23 +1,23 @@ -#pragma once - +#pragma once + #include "handler.h" #include "local_flags.h" -#include "session.h" - -namespace NBus { +#include "session.h" + +namespace NBus { template <typename U /* <: TBusMessage */> EMessageStatus TOnMessageContext::SendReplyAutoPtr(TAutoPtr<U>& response) { return Session->SendReplyAutoPtr(Ident, response); } - + inline EMessageStatus TOnMessageContext::SendReplyMove(TBusMessageAutoPtr response) { return SendReplyAutoPtr(response); } - + inline void TOnMessageContext::AckMessage(TBusIdentity& ident) { Y_VERIFY(Ident.LocalFlags == NPrivate::MESSAGE_IN_WORK); Y_VERIFY(ident.LocalFlags == 0); Ident.Swap(ident); } - -} + +} diff --git a/library/cpp/messagebus/hash.h b/library/cpp/messagebus/hash.h index bc3ad0df62..cc1b136a86 100644 --- a/library/cpp/messagebus/hash.h +++ b/library/cpp/messagebus/hash.h @@ -1,19 +1,19 @@ -#pragma once - -#include <util/str_stl.h> -#include <util/digest/numeric.h> - +#pragma once + +#include <util/str_stl.h> +#include <util/digest/numeric.h> + namespace NBus { namespace NPrivate { template <typename T> size_t Hash(const T& val) { return THash<T>()(val); } - + template <typename T, typename U> size_t HashValues(const T& a, const U& b) { return CombineHashes(Hash(a), Hash(b)); } - - } + + } } diff --git a/library/cpp/messagebus/key_value_printer.cpp b/library/cpp/messagebus/key_value_printer.cpp index 93851eff3a..c8592145c7 100644 --- a/library/cpp/messagebus/key_value_printer.cpp +++ b/library/cpp/messagebus/key_value_printer.cpp @@ -1,46 +1,46 @@ #include "key_value_printer.h" -#include <util/stream/format.h> - +#include <util/stream/format.h> + TKeyValuePrinter::TKeyValuePrinter(const TString& sep) - : Sep(sep) + : Sep(sep) { } - + TKeyValuePrinter::~TKeyValuePrinter() { } - + void TKeyValuePrinter::AddRowImpl(const TString& key, const TString& value, bool alignLeft) { - Keys.push_back(key); - Values.push_back(value); - AlignLefts.push_back(alignLeft); -} - + Keys.push_back(key); + Values.push_back(value); + AlignLefts.push_back(alignLeft); +} + TString TKeyValuePrinter::PrintToString() const { - if (Keys.empty()) { + if (Keys.empty()) { return TString(); - } - - size_t keyWidth = 0; - size_t valueWidth = 0; - - for (size_t i = 0; i < Keys.size(); ++i) { - keyWidth = Max(keyWidth, Keys.at(i).size()); - valueWidth = Max(valueWidth, Values.at(i).size()); - } - - TStringStream ss; - - for (size_t i = 0; i < Keys.size(); ++i) { - ss << RightPad(Keys.at(i), keyWidth); - ss << Sep; - if (AlignLefts.at(i)) { - ss << Values.at(i); - } else { - ss << LeftPad(Values.at(i), valueWidth); - } - ss << Endl; - } - - return ss.Str(); -} + } + + size_t keyWidth = 0; + size_t valueWidth = 0; + + for (size_t i = 0; i < Keys.size(); ++i) { + keyWidth = Max(keyWidth, Keys.at(i).size()); + valueWidth = Max(valueWidth, Values.at(i).size()); + } + + TStringStream ss; + + for (size_t i = 0; i < Keys.size(); ++i) { + ss << RightPad(Keys.at(i), keyWidth); + ss << Sep; + if (AlignLefts.at(i)) { + ss << Values.at(i); + } else { + ss << LeftPad(Values.at(i), valueWidth); + } + ss << Endl; + } + + return ss.Str(); +} diff --git a/library/cpp/messagebus/key_value_printer.h b/library/cpp/messagebus/key_value_printer.h index 34c6ec36c1..bca1fde50e 100644 --- a/library/cpp/messagebus/key_value_printer.h +++ b/library/cpp/messagebus/key_value_printer.h @@ -1,28 +1,28 @@ -#pragma once - +#pragma once + #include <util/generic/string.h> -#include <util/generic/typetraits.h> +#include <util/generic/typetraits.h> #include <util/generic/vector.h> #include <util/string/cast.h> - -class TKeyValuePrinter { -private: + +class TKeyValuePrinter { +private: TString Sep; TVector<TString> Keys; TVector<TString> Values; TVector<bool> AlignLefts; -public: +public: TKeyValuePrinter(const TString& sep = TString(": ")); - ~TKeyValuePrinter(); - - template <typename TKey, typename TValue> + ~TKeyValuePrinter(); + + template <typename TKey, typename TValue> void AddRow(const TKey& key, const TValue& value, bool leftAlign = !std::is_integral<TValue>::value) { - return AddRowImpl(ToString(key), ToString(value), leftAlign); - } - + return AddRowImpl(ToString(key), ToString(value), leftAlign); + } + TString PrintToString() const; - -private: + +private: void AddRowImpl(const TString& key, const TString& value, bool leftAlign); -}; +}; diff --git a/library/cpp/messagebus/latch.h b/library/cpp/messagebus/latch.h index d40aef2719..373f4c0e13 100644 --- a/library/cpp/messagebus/latch.h +++ b/library/cpp/messagebus/latch.h @@ -1,53 +1,53 @@ -#pragma once - +#pragma once + #include <util/system/condvar.h> -#include <util/system/mutex.h> - -class TLatch { -private: - // 0 for unlocked, 1 for locked - TAtomic Locked; - TMutex Mutex; - TCondVar CondVar; - -public: +#include <util/system/mutex.h> + +class TLatch { +private: + // 0 for unlocked, 1 for locked + TAtomic Locked; + TMutex Mutex; + TCondVar CondVar; + +public: TLatch() : Locked(0) { } - - void Wait() { - // optimistic path - if (AtomicGet(Locked) == 0) { - return; - } - - TGuard<TMutex> guard(Mutex); + + void Wait() { + // optimistic path + if (AtomicGet(Locked) == 0) { + return; + } + + TGuard<TMutex> guard(Mutex); while (AtomicGet(Locked) == 1) { - CondVar.WaitI(Mutex); - } - } - - bool TryWait() { - return AtomicGet(Locked) == 0; - } - - void Unlock() { - // optimistic path - if (AtomicGet(Locked) == 0) { - return; - } - - TGuard<TMutex> guard(Mutex); + CondVar.WaitI(Mutex); + } + } + + bool TryWait() { + return AtomicGet(Locked) == 0; + } + + void Unlock() { + // optimistic path + if (AtomicGet(Locked) == 0) { + return; + } + + TGuard<TMutex> guard(Mutex); AtomicSet(Locked, 0); - CondVar.BroadCast(); - } - - void Lock() { - AtomicSet(Locked, 1); - } - - bool IsLocked() { - return AtomicGet(Locked); - } -}; + CondVar.BroadCast(); + } + + void Lock() { + AtomicSet(Locked, 1); + } + + bool IsLocked() { + return AtomicGet(Locked); + } +}; diff --git a/library/cpp/messagebus/latch_ut.cpp b/library/cpp/messagebus/latch_ut.cpp index c1735b3339..bfab04f527 100644 --- a/library/cpp/messagebus/latch_ut.cpp +++ b/library/cpp/messagebus/latch_ut.cpp @@ -1,20 +1,20 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "latch.h" - + +#include "latch.h" + Y_UNIT_TEST_SUITE(TLatch) { Y_UNIT_TEST(Simple) { - TLatch latch; - UNIT_ASSERT(latch.TryWait()); - latch.Lock(); - UNIT_ASSERT(!latch.TryWait()); - latch.Lock(); - latch.Lock(); - UNIT_ASSERT(!latch.TryWait()); - latch.Unlock(); - UNIT_ASSERT(latch.TryWait()); - latch.Unlock(); - latch.Unlock(); - UNIT_ASSERT(latch.TryWait()); - } -} + TLatch latch; + UNIT_ASSERT(latch.TryWait()); + latch.Lock(); + UNIT_ASSERT(!latch.TryWait()); + latch.Lock(); + latch.Lock(); + UNIT_ASSERT(!latch.TryWait()); + latch.Unlock(); + UNIT_ASSERT(latch.TryWait()); + latch.Unlock(); + latch.Unlock(); + UNIT_ASSERT(latch.TryWait()); + } +} diff --git a/library/cpp/messagebus/left_right_buffer.h b/library/cpp/messagebus/left_right_buffer.h index c76aa10db6..f937cefad0 100644 --- a/library/cpp/messagebus/left_right_buffer.h +++ b/library/cpp/messagebus/left_right_buffer.h @@ -1,78 +1,78 @@ -#pragma once - +#pragma once + #include <util/generic/buffer.h> #include <util/generic/noncopyable.h> -#include <util/system/yassert.h> - +#include <util/system/yassert.h> + namespace NBus { namespace NPrivate { class TLeftRightBuffer : TNonCopyable { private: TBuffer Buffer; size_t Left; - + void CheckInvariant() { Y_ASSERT(Left <= Buffer.Size()); } - + public: TLeftRightBuffer() : Left(0) { } - + TBuffer& GetBuffer() { return Buffer; } - + size_t Capacity() { return Buffer.Capacity(); } - + void Clear() { Buffer.Clear(); Left = 0; } - + void Reset() { Buffer.Reset(); Left = 0; } - + void Compact() { Buffer.ChopHead(Left); Left = 0; } - + char* LeftPos() { return Buffer.Data() + Left; } - + size_t LeftSize() { return Left; } - + void LeftProceed(size_t count) { Y_ASSERT(count <= Size()); Left += count; } - + size_t Size() { return Buffer.Size() - Left; } - + bool Empty() { return Size() == 0; } - + char* RightPos() { return Buffer.Data() + Buffer.Size(); } - + size_t Avail() { return Buffer.Avail(); } }; - - } + + } } diff --git a/library/cpp/messagebus/lfqueue_batch.h b/library/cpp/messagebus/lfqueue_batch.h index f3db73a3dd..8128d3154d 100644 --- a/library/cpp/messagebus/lfqueue_batch.h +++ b/library/cpp/messagebus/lfqueue_batch.h @@ -1,36 +1,36 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/actor/temp_tls_vector.h> -#include <util/generic/vector.h> -#include <util/thread/lfstack.h> - +#include <util/generic/vector.h> +#include <util/thread/lfstack.h> + template <typename T, template <typename, class> class TVectorType = TVector> -class TLockFreeQueueBatch { -private: +class TLockFreeQueueBatch { +private: TLockFreeStack<TVectorType<T, std::allocator<T>>*> Stack; -public: - bool IsEmpty() { - return Stack.IsEmpty(); - } - +public: + bool IsEmpty() { + return Stack.IsEmpty(); + } + void EnqueueAll(TAutoPtr<TVectorType<T, std::allocator<T>>> vec) { - Stack.Enqueue(vec.Release()); - } - + Stack.Enqueue(vec.Release()); + } + void DequeueAllSingleConsumer(TVectorType<T, std::allocator<T>>* r) { TTempTlsVector<TVectorType<T, std::allocator<T>>*> vs; - Stack.DequeueAllSingleConsumer(vs.GetVector()); - + Stack.DequeueAllSingleConsumer(vs.GetVector()); + for (typename TVector<TVectorType<T, std::allocator<T>>*>::reverse_iterator i = vs.GetVector()->rbegin(); i != vs.GetVector()->rend(); ++i) { - if (i == vs.GetVector()->rend()) { - r->swap(**i); - } else { - r->insert(r->end(), (*i)->begin(), (*i)->end()); - } - delete *i; - } - } -}; + if (i == vs.GetVector()->rend()) { + r->swap(**i); + } else { + r->insert(r->end(), (*i)->begin(), (*i)->end()); + } + delete *i; + } + } +}; diff --git a/library/cpp/messagebus/lfqueue_batch_ut.cpp b/library/cpp/messagebus/lfqueue_batch_ut.cpp index 101f4cd932..f80434c0d4 100644 --- a/library/cpp/messagebus/lfqueue_batch_ut.cpp +++ b/library/cpp/messagebus/lfqueue_batch_ut.cpp @@ -1,56 +1,56 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "lfqueue_batch.h" - + +#include "lfqueue_batch.h" + Y_UNIT_TEST_SUITE(TLockFreeQueueBatch) { Y_UNIT_TEST(Order1) { - TLockFreeQueueBatch<unsigned> q; - { + TLockFreeQueueBatch<unsigned> q; + { TAutoPtr<TVector<unsigned>> v(new TVector<unsigned>); - v->push_back(0); - v->push_back(1); - q.EnqueueAll(v); - } - + v->push_back(0); + v->push_back(1); + q.EnqueueAll(v); + } + TVector<unsigned> r; - q.DequeueAllSingleConsumer(&r); - - UNIT_ASSERT_VALUES_EQUAL(2u, r.size()); - for (unsigned i = 0; i < 2; ++i) { - UNIT_ASSERT_VALUES_EQUAL(i, r[i]); - } - - r.clear(); - q.DequeueAllSingleConsumer(&r); - UNIT_ASSERT_VALUES_EQUAL(0u, r.size()); - } - + q.DequeueAllSingleConsumer(&r); + + UNIT_ASSERT_VALUES_EQUAL(2u, r.size()); + for (unsigned i = 0; i < 2; ++i) { + UNIT_ASSERT_VALUES_EQUAL(i, r[i]); + } + + r.clear(); + q.DequeueAllSingleConsumer(&r); + UNIT_ASSERT_VALUES_EQUAL(0u, r.size()); + } + Y_UNIT_TEST(Order2) { - TLockFreeQueueBatch<unsigned> q; - { + TLockFreeQueueBatch<unsigned> q; + { TAutoPtr<TVector<unsigned>> v(new TVector<unsigned>); - v->push_back(0); - v->push_back(1); - q.EnqueueAll(v); - } - { + v->push_back(0); + v->push_back(1); + q.EnqueueAll(v); + } + { TAutoPtr<TVector<unsigned>> v(new TVector<unsigned>); - v->push_back(2); - v->push_back(3); - v->push_back(4); - q.EnqueueAll(v); - } - + v->push_back(2); + v->push_back(3); + v->push_back(4); + q.EnqueueAll(v); + } + TVector<unsigned> r; - q.DequeueAllSingleConsumer(&r); - - UNIT_ASSERT_VALUES_EQUAL(5u, r.size()); - for (unsigned i = 0; i < 5; ++i) { - UNIT_ASSERT_VALUES_EQUAL(i, r[i]); - } - - r.clear(); - q.DequeueAllSingleConsumer(&r); - UNIT_ASSERT_VALUES_EQUAL(0u, r.size()); - } -} + q.DequeueAllSingleConsumer(&r); + + UNIT_ASSERT_VALUES_EQUAL(5u, r.size()); + for (unsigned i = 0; i < 5; ++i) { + UNIT_ASSERT_VALUES_EQUAL(i, r[i]); + } + + r.clear(); + q.DequeueAllSingleConsumer(&r); + UNIT_ASSERT_VALUES_EQUAL(0u, r.size()); + } +} diff --git a/library/cpp/messagebus/local_flags.cpp b/library/cpp/messagebus/local_flags.cpp index aac65590ed..877e533f76 100644 --- a/library/cpp/messagebus/local_flags.cpp +++ b/library/cpp/messagebus/local_flags.cpp @@ -1,19 +1,19 @@ #include "local_flags.h" #include <util/stream/str.h> -#include <util/string/printf.h> - -using namespace NBus; -using namespace NBus::NPrivate; - +#include <util/string/printf.h> + +using namespace NBus; +using namespace NBus::NPrivate; + TString NBus::NPrivate::LocalFlagSetToString(ui32 flags0) { - if (flags0 == 0) { - return "0"; - } - - ui32 flags = flags0; - - TStringStream ss; + if (flags0 == 0) { + return "0"; + } + + ui32 flags = flags0; + + TStringStream ss; #define P(name, value, ...) \ do \ if (flags & value) { \ @@ -23,10 +23,10 @@ TString NBus::NPrivate::LocalFlagSetToString(ui32 flags0) { ss << #name; \ flags &= ~name; \ } \ - while (false); - MESSAGE_LOCAL_FLAGS_MAP(P) - if (flags != 0) { - return Sprintf("0x%x", unsigned(flags0)); - } - return ss.Str(); -} + while (false); + MESSAGE_LOCAL_FLAGS_MAP(P) + if (flags != 0) { + return Sprintf("0x%x", unsigned(flags0)); + } + return ss.Str(); +} diff --git a/library/cpp/messagebus/local_flags.h b/library/cpp/messagebus/local_flags.h index fe1f157bdf..f589283188 100644 --- a/library/cpp/messagebus/local_flags.h +++ b/library/cpp/messagebus/local_flags.h @@ -1,10 +1,10 @@ -#pragma once - +#pragma once + #include <library/cpp/deprecated/enum_codegen/enum_codegen.h> #include <util/generic/string.h> -#include <util/stream/output.h> - +#include <util/stream/output.h> + namespace NBus { namespace NPrivate { #define MESSAGE_LOCAL_FLAGS_MAP(XX) \ @@ -14,13 +14,13 @@ namespace NBus { XX(MESSAGE_REPLY_IS_BEGING_SENT, 0x0008) \ XX(MESSAGE_ONE_WAY_INTERNAL, 0x0010) \ /**/ - + enum EMessageLocalFlags { MESSAGE_LOCAL_FLAGS_MAP(ENUM_VALUE_GEN) }; - + ENUM_TO_STRING(EMessageLocalFlags, MESSAGE_LOCAL_FLAGS_MAP) - + TString LocalFlagSetToString(ui32); } } diff --git a/library/cpp/messagebus/local_flags_ut.cpp b/library/cpp/messagebus/local_flags_ut.cpp index 5fdb483db6..189d73eb0f 100644 --- a/library/cpp/messagebus/local_flags_ut.cpp +++ b/library/cpp/messagebus/local_flags_ut.cpp @@ -1,18 +1,18 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "local_flags.h" - -using namespace NBus; -using namespace NBus::NPrivate; - + +#include "local_flags.h" + +using namespace NBus; +using namespace NBus::NPrivate; + Y_UNIT_TEST_SUITE(EMessageLocalFlags) { Y_UNIT_TEST(TestLocalFlagSetToString) { - UNIT_ASSERT_VALUES_EQUAL("0", LocalFlagSetToString(0)); - UNIT_ASSERT_VALUES_EQUAL("MESSAGE_REPLY_INTERNAL", + UNIT_ASSERT_VALUES_EQUAL("0", LocalFlagSetToString(0)); + UNIT_ASSERT_VALUES_EQUAL("MESSAGE_REPLY_INTERNAL", LocalFlagSetToString(MESSAGE_REPLY_INTERNAL)); - UNIT_ASSERT_VALUES_EQUAL("MESSAGE_IN_WORK|MESSAGE_IN_FLIGHT_ON_CLIENT", + UNIT_ASSERT_VALUES_EQUAL("MESSAGE_IN_WORK|MESSAGE_IN_FLIGHT_ON_CLIENT", LocalFlagSetToString(MESSAGE_IN_WORK | MESSAGE_IN_FLIGHT_ON_CLIENT)); - UNIT_ASSERT_VALUES_EQUAL("0xff3456", + UNIT_ASSERT_VALUES_EQUAL("0xff3456", LocalFlagSetToString(0xff3456)); - } -} + } +} diff --git a/library/cpp/messagebus/local_tasks.h b/library/cpp/messagebus/local_tasks.h index 4a07bf95f5..d8e801a457 100644 --- a/library/cpp/messagebus/local_tasks.h +++ b/library/cpp/messagebus/local_tasks.h @@ -1,23 +1,23 @@ -#pragma once - +#pragma once + #include <util/system/atomic.h> -class TLocalTasks { -private: +class TLocalTasks { +private: TAtomic GotTasks; - -public: - TLocalTasks() + +public: + TLocalTasks() : GotTasks(0) { } - - void AddTask() { + + void AddTask() { AtomicSet(GotTasks, 1); - } - - bool FetchTask() { + } + + bool FetchTask() { bool gotTasks = AtomicCas(&GotTasks, 0, 1); - return gotTasks; - } -}; + return gotTasks; + } +}; diff --git a/library/cpp/messagebus/locator.cpp b/library/cpp/messagebus/locator.cpp index 31cdf25805..e38a35c426 100644 --- a/library/cpp/messagebus/locator.cpp +++ b/library/cpp/messagebus/locator.cpp @@ -2,7 +2,7 @@ /// \file /// \brief Implementation of locator service -#include "locator.h" +#include "locator.h" #include "ybus.h" @@ -121,7 +121,7 @@ namespace NBus { , End(end) , Addr(addr) { - } + } bool TBusLocator::IsLocal(const TNetAddr& addr) { for (const auto& myInterface : MyInterfaces) { @@ -151,7 +151,7 @@ namespace NBus { int TBusLocator::RegisterBreak(TServiceId serviceId, const TBusKey start, const TNetAddr& addr) { TItems::const_iterator it = Items.lower_bound(TItem(serviceId, 0, start, addr)); TItems::const_iterator service_it = - Items.lower_bound(TItem(serviceId, 0, 0, TNetAddr())); + Items.lower_bound(TItem(serviceId, 0, 0, TNetAddr())); THolder<TItem> left; THolder<TItem> right; @@ -220,11 +220,11 @@ namespace NBus { } keyItem = item.Start - 1; } while (it != Items.begin()); - + if (first != Items.end() && first->Start != 0) { TItem item(serviceId, YBUS_KEYMIN, first->Start - 1, first->Addr); Items.insert(item); - } + } NormalizeBreaks(serviceId); return deleted; @@ -245,7 +245,7 @@ namespace NBus { TItem& beg = const_cast<TItem&>(*first); beg.Addr = last->Addr; - } + } } int TBusLocator::LocateAll(TBusService service, TBusKey key, TVector<TNetAddr>& addrs) { @@ -307,7 +307,7 @@ namespace NBus { } port = GetAddrPort(item.Addr); } - } + } return port; } @@ -326,7 +326,7 @@ namespace NBus { if (IsLocal(item.Addr)) { addrs.push_back(item.Addr); } - } + } if (addrs.size() == 0) { return -1; diff --git a/library/cpp/messagebus/locator.h b/library/cpp/messagebus/locator.h index b90a7aceb4..f8556a3fce 100644 --- a/library/cpp/messagebus/locator.h +++ b/library/cpp/messagebus/locator.h @@ -1,18 +1,18 @@ -#pragma once - +#pragma once + #include "defs.h" -#include <util/generic/hash.h> +#include <util/generic/hash.h> #include <util/generic/map.h> #include <util/generic/set.h> #include <util/generic/string.h> #include <util/network/interface.h> #include <util/system/mutex.h> - -namespace NBus { + +namespace NBus { /////////////////////////////////////////////// /// \brief Client interface to locator service - + /// This interface abstracts clustering/location service that /// allows clients find servers (address, port) using "name" and "key". /// The instance lives in TBusMessageQueue-object, but can be shared by different queues. @@ -22,72 +22,72 @@ namespace NBus { typedef TSet<TString> TServiceIdSet; TServiceIdSet ServiceIdSet; TServiceId GetServiceId(const char* name); - + typedef TMap<TNetAddr, TString> THostAddrMap; THostAddrMap HostAddrMap; - + TNetworkInterfaceList MyInterfaces; - + struct TItem { TServiceId ServiceId; TBusKey Start; TBusKey End; TNetAddr Addr; - + bool operator<(const TItem& y) const; - + bool operator==(const TItem& y) const; - + TItem(TServiceId serviceId, TBusKey start, TBusKey end, const TNetAddr& addr); }; typedef TMultiSet<TItem> TItems; TItems Items; TMutex Lock; - + int RegisterBreak(TServiceId serviceId, const TBusKey start, const TNetAddr& addr); int UnregisterBreak(TServiceId serviceId, const TNetAddr& addr); - + void NormalizeBreaks(TServiceId serviceId); - + private: int Register(TBusService service, TBusKey start, TBusKey end, const TNetAddr& addr); - + public: /// creates instance that obtains location table from locator server (not implemented) TBusLocator(); - + /// returns true if this address is on the same node for YBUS_KEYLOCAL bool IsLocal(const TNetAddr& addr); - + /// returns first address for service and key int Locate(TBusService service, TBusKey key, TNetAddr* addr); - + /// returns all addresses mathing service and key int LocateAll(TBusService service, TBusKey key, TVector<TNetAddr>& addrs); - + /// returns actual host name for service and key int LocateHost(TBusService service, TBusKey key, TString* host, int* port, bool* isLocal = nullptr); - + /// returns all key ranges for the given service int LocateKeys(TBusService service, TBusKeyVec& keys, bool onlyLocal = false); - + /// returns port on the local node for the service int GetLocalPort(TBusService service); - + /// returns addresses of the local node for the service int GetLocalAddresses(TBusService service, TVector<TNetAddr>& addrs); - + /// register service instance int Register(TBusService service, TBusKey start, TBusKey end, const TNetworkAddress& addr, EIpVersion requireVersion = EIP_VERSION_4, EIpVersion preferVersion = EIP_VERSION_ANY); /// @throws yexception int Register(TBusService service, const char* host, int port, TBusKey start = YBUS_KEYMIN, TBusKey end = YBUS_KEYMAX, EIpVersion requireVersion = EIP_VERSION_4, EIpVersion preferVersion = EIP_VERSION_ANY); - + /// unregister service instance int Unregister(TBusService service, TBusKey start, TBusKey end); - + int RegisterBreak(TBusService service, const TVector<TBusKey>& starts, const TNetAddr& addr); int UnregisterBreak(TBusService service, const TNetAddr& addr); }; - + } diff --git a/library/cpp/messagebus/mb_lwtrace.cpp b/library/cpp/messagebus/mb_lwtrace.cpp index 1a1cc3997e..c54cd5ab71 100644 --- a/library/cpp/messagebus/mb_lwtrace.cpp +++ b/library/cpp/messagebus/mb_lwtrace.cpp @@ -1,12 +1,12 @@ #include "mb_lwtrace.h" - + #include <library/cpp/lwtrace/all.h> - + #include <util/generic/singleton.h> - -LWTRACE_DEFINE_PROVIDER(LWTRACE_MESSAGEBUS_PROVIDER) - -void NBus::InitBusLwtrace() { - // Function is nop, and needed only to make sure TBusLwtraceInit loaded. - // It won't be necessary when pg@ implements GLOBAL in arc. -} + +LWTRACE_DEFINE_PROVIDER(LWTRACE_MESSAGEBUS_PROVIDER) + +void NBus::InitBusLwtrace() { + // Function is nop, and needed only to make sure TBusLwtraceInit loaded. + // It won't be necessary when pg@ implements GLOBAL in arc. +} diff --git a/library/cpp/messagebus/mb_lwtrace.h b/library/cpp/messagebus/mb_lwtrace.h index 032e1989ea..e62728b265 100644 --- a/library/cpp/messagebus/mb_lwtrace.h +++ b/library/cpp/messagebus/mb_lwtrace.h @@ -1,7 +1,7 @@ -#pragma once - +#pragma once + #include <library/cpp/lwtrace/all.h> - + #include <util/generic/string.h> #define LWTRACE_MESSAGEBUS_PROVIDER(PROBE, EVENT, GROUPS, TYPES, NAMES) \ @@ -10,10 +10,10 @@ PROBE(Accepted, GROUPS("MessagebusRare"), TYPES(TString), NAMES("address")) \ PROBE(Disconnected, GROUPS("MessagebusRare"), TYPES(TString), NAMES("address")) \ PROBE(Read, GROUPS(), TYPES(ui32), NAMES("size")) \ - /**/ - -LWTRACE_DECLARE_PROVIDER(LWTRACE_MESSAGEBUS_PROVIDER) - -namespace NBus { - void InitBusLwtrace(); -} + /**/ + +LWTRACE_DECLARE_PROVIDER(LWTRACE_MESSAGEBUS_PROVIDER) + +namespace NBus { + void InitBusLwtrace(); +} diff --git a/library/cpp/messagebus/memory.h b/library/cpp/messagebus/memory.h index e7bfc1827d..b2c0544491 100644 --- a/library/cpp/messagebus/memory.h +++ b/library/cpp/messagebus/memory.h @@ -1,42 +1,42 @@ -#pragma once - -#ifndef CACHE_LINE_SIZE -#define CACHE_LINE_SIZE 64 -#endif - -#define CONCAT(a, b) a##b -#define LABEL(a) CONCAT(UniqueName_, a) -#define UNIQUE_NAME LABEL(__LINE__) - -#define CACHE_LINE_PADDING char UNIQUE_NAME[CACHE_LINE_SIZE]; - -static inline void* MallocAligned(size_t size, size_t alignment) { +#pragma once + +#ifndef CACHE_LINE_SIZE +#define CACHE_LINE_SIZE 64 +#endif + +#define CONCAT(a, b) a##b +#define LABEL(a) CONCAT(UniqueName_, a) +#define UNIQUE_NAME LABEL(__LINE__) + +#define CACHE_LINE_PADDING char UNIQUE_NAME[CACHE_LINE_SIZE]; + +static inline void* MallocAligned(size_t size, size_t alignment) { void** ptr = (void**)malloc(size + alignment + sizeof(size_t*)); - if (!ptr) { + if (!ptr) { return nullptr; - } - - size_t mask = ~(alignment - 1); - intptr_t roundedDown = intptr_t(ptr) & mask; + } + + size_t mask = ~(alignment - 1); + intptr_t roundedDown = intptr_t(ptr) & mask; void** alignedPtr = (void**)(roundedDown + alignment); - alignedPtr[-1] = ptr; - return alignedPtr; -} - -static inline void FreeAligned(void* ptr) { - if (!ptr) { - return; - } - + alignedPtr[-1] = ptr; + return alignedPtr; +} + +static inline void FreeAligned(void* ptr) { + if (!ptr) { + return; + } + void** typedPtr = (void**)ptr; void* originalPtr = typedPtr[-1]; - free(originalPtr); -} - -static inline void* MallocCacheAligned(size_t size) { - return MallocAligned(size, CACHE_LINE_SIZE); -} - -static inline void FreeCacheAligned(void* ptr) { - return FreeAligned(ptr); -} + free(originalPtr); +} + +static inline void* MallocCacheAligned(size_t size) { + return MallocAligned(size, CACHE_LINE_SIZE); +} + +static inline void FreeCacheAligned(void* ptr) { + return FreeAligned(ptr); +} diff --git a/library/cpp/messagebus/memory_ut.cpp b/library/cpp/messagebus/memory_ut.cpp index 036eb43b4d..00654f28a1 100644 --- a/library/cpp/messagebus/memory_ut.cpp +++ b/library/cpp/messagebus/memory_ut.cpp @@ -1,13 +1,13 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "memory.h" - + +#include "memory.h" + Y_UNIT_TEST_SUITE(MallocAligned) { Y_UNIT_TEST(Test) { - for (size_t size = 0; size < 1000; ++size) { - void* ptr = MallocAligned(size, 128); - UNIT_ASSERT(uintptr_t(ptr) % 128 == 0); - FreeAligned(ptr); - } - } -} + for (size_t size = 0; size < 1000; ++size) { + void* ptr = MallocAligned(size, 128); + UNIT_ASSERT(uintptr_t(ptr) % 128 == 0); + FreeAligned(ptr); + } + } +} diff --git a/library/cpp/messagebus/message.cpp b/library/cpp/messagebus/message.cpp index eca319326e..bfa7ed8e9b 100644 --- a/library/cpp/messagebus/message.cpp +++ b/library/cpp/messagebus/message.cpp @@ -1,14 +1,14 @@ #include "remote_server_connection.h" #include "ybus.h" - + #include <util/random/random.h> #include <util/string/printf.h> #include <util/system/atomic.h> #include <string.h> -using namespace NBus; - +using namespace NBus; + namespace NBus { using namespace NBus::NPrivate; @@ -19,40 +19,40 @@ namespace NBus { , LocalFlags(0) { } - + TBusIdentity::~TBusIdentity() { - // TODO: print local flags -#ifndef NDEBUG + // TODO: print local flags +#ifndef NDEBUG Y_VERIFY(LocalFlags == 0, "local flags must be zero at this point; message type is %s", MessageType.value_or("unknown").c_str()); -#else +#else Y_VERIFY(LocalFlags == 0, "local flags must be zero at this point"); -#endif +#endif } - + TNetAddr TBusIdentity::GetNetAddr() const { if (!!Connection) { return Connection->GetAddr(); } else { Y_FAIL(); } - } - + } + void TBusIdentity::Pack(char* dest) { memcpy(dest, this, sizeof(TBusIdentity)); LocalFlags = 0; - + // prevent decref new (&Connection) TIntrusivePtr<TRemoteServerConnection>; } - + void TBusIdentity::Unpack(const char* src) { Y_VERIFY(LocalFlags == 0); Y_VERIFY(!Connection); - + memcpy(this, src, sizeof(TBusIdentity)); } - + void TBusHeader::GenerateId() { for (;;) { Id = RandomNumber<TBusKey>(); @@ -61,7 +61,7 @@ namespace NBus { return; } } - + TBusMessage::TBusMessage(ui16 type, int approxsize) //: TCtr("BusMessage") : TRefCounted<TBusMessage, TAtomicCounter, TDelete>(1) @@ -72,7 +72,7 @@ namespace NBus { Y_UNUSED(approxsize); GetHeader()->Type = type; DoReset(); - } + } TBusMessage::TBusMessage(ECreateUninitialized) //: TCtr("BusMessage") @@ -87,12 +87,12 @@ namespace NBus { } TBusMessage::~TBusMessage() { -#ifndef NDEBUG +#ifndef NDEBUG Y_VERIFY(GetHeader()->Id != YBUS_KEYINVALID, "must not be invalid key, message type: %d, ", int(Type)); GetHeader()->Id = YBUS_KEYINVALID; Data = (void*)17; CheckClean(); -#endif +#endif } void TBusMessage::DoReset() { @@ -102,20 +102,20 @@ namespace NBus { GetHeader()->GenerateId(); GetHeader()->SetVersionInternal(); } - + void TBusMessage::Reset() { CheckClean(); DoReset(); } - + void TBusMessage::CheckClean() const { if (Y_UNLIKELY(LocalFlags != 0)) { TString describe = Describe(); TString localFlags = LocalFlagSetToString(LocalFlags); Y_FAIL("message local flags must be zero, got: %s, message: %s", localFlags.data(), describe.data()); } - } - + } + /////////////////////////////////////////////////////// /// \brief Unpacks header from network order @@ -181,18 +181,18 @@ namespace NBus { ss << " conn=" << Connection->GetAddr(); } ss - << " flags=" << Flags - << " local-flags=" << LocalFlags -#ifndef NDEBUG + << " flags=" << Flags + << " local-flags=" << LocalFlags +#ifndef NDEBUG << " msg-type= " << MessageType.value_or("unknown").c_str() -#endif - ; +#endif + ; return ss.Str(); } - -} - -template <> + +} + +template <> void Out<TBusIdentity>(IOutputStream& os, TTypeTraits<TBusIdentity>::TFuncParam ident) { - os << ident.ToString(); -} + os << ident.ToString(); +} diff --git a/library/cpp/messagebus/message.h b/library/cpp/messagebus/message.h index 6fce2b1fac..005ca10c65 100644 --- a/library/cpp/messagebus/message.h +++ b/library/cpp/messagebus/message.h @@ -1,5 +1,5 @@ -#pragma once - +#pragma once + #include "base.h" #include "local_flags.h" #include "message_status.h" @@ -8,16 +8,16 @@ #include <util/generic/array_ref.h> #include <util/generic/noncopyable.h> -#include <util/generic/ptr.h> +#include <util/generic/ptr.h> #include <util/generic/string.h> #include <util/system/defaults.h> #include <util/system/type_name.h> -#include <util/system/yassert.h> - +#include <util/system/yassert.h> + #include <optional> #include <typeinfo> -namespace NBus { +namespace NBus { /////////////////////////////////////////////////////////////////// /// \brief Structure to preserve identity from message to reply struct TBusIdentity : TNonCopyable { @@ -25,33 +25,33 @@ namespace NBus { friend class NPrivate::TRemoteServerSession; friend struct NPrivate::TClientRequestImpl; friend class TOnMessageContext; - + // TODO: make private TBusKey MessageId; - + private: ui32 Size; TIntrusivePtr<NPrivate::TRemoteServerConnection> Connection; ui16 Flags; ui32 LocalFlags; TInstant RecvTime; - -#ifndef NDEBUG + +#ifndef NDEBUG std::optional<TString> MessageType; -#endif - +#endif + private: // TODO: drop TNetAddr GetNetAddr() const; - + public: void Pack(char* dest); void Unpack(const char* src); - + bool IsInWork() const { return LocalFlags & NPrivate::MESSAGE_IN_WORK; } - + // for internal use only void BeginWork() { SetInWork(true); @@ -64,7 +64,7 @@ namespace NBus { TBusIdentity(); ~TBusIdentity(); - + void Swap(TBusIdentity& that) { DoSwap(MessageId, that.MessageId); DoSwap(Size, that.Size); @@ -72,13 +72,13 @@ namespace NBus { DoSwap(Flags, that.Flags); DoSwap(LocalFlags, that.LocalFlags); DoSwap(RecvTime, that.RecvTime); -#ifndef NDEBUG +#ifndef NDEBUG DoSwap(MessageType, that.MessageType); -#endif +#endif } - + TString ToString() const; - + private: void SetInWork(bool inWork) { if (LocalFlags == 0 && inWork) { @@ -89,20 +89,20 @@ namespace NBus { Y_FAIL("impossible combination of flag and parameter: %s %d", inWork ? "true" : "false", unsigned(LocalFlags)); } - } - + } + void SetMessageType(const std::type_info& messageTypeInfo) { -#ifndef NDEBUG +#ifndef NDEBUG Y_VERIFY(!MessageType, "state check"); MessageType = TypeName(messageTypeInfo); -#else +#else Y_UNUSED(messageTypeInfo); -#endif +#endif } }; - + static const size_t BUS_IDENTITY_PACKED_SIZE = sizeof(TBusIdentity); - + /////////////////////////////////////////////////////////////// /// \brief Message flags in TBusHeader.Flags enum EMessageFlags { @@ -110,59 +110,59 @@ namespace NBus { MESSAGE_COMPRESS_RESPONSE = 0x4000, ///< message prefers compressed response MESSAGE_VERSION_INTERNAL = 0x00F0, ///< these bits are used as version }; - -////////////////////////////////////////////////////////// -/// \brief Message header present in all message send and received - -/// This header is send into the wire. -/// \todo fix for low/high end, 32/64bit some day -#pragma pack(1) + +////////////////////////////////////////////////////////// +/// \brief Message header present in all message send and received + +/// This header is send into the wire. +/// \todo fix for low/high end, 32/64bit some day +#pragma pack(1) struct TBusHeader { friend class TBusMessage; - + TBusKey Id = 0; ///< unique message ID ui32 Size = 0; ///< total size of the message TBusInstant SendTime = 0; ///< time the message was sent ui16 FlagsInternal = 0; ///< TRACE is one of the flags ui16 Type = 0; ///< to be used by TBusProtocol - + int GetVersionInternal() { return (FlagsInternal & MESSAGE_VERSION_INTERNAL) >> 4; } void SetVersionInternal(unsigned ver = YBUS_VERSION) { FlagsInternal |= (ver << 4); } - + public: TBusHeader() { } TBusHeader(TArrayRef<const char> data) { ReadHeader(data); } - + private: /// function for serialization/deserialization of the header /// returns number of bytes written/read int ReadHeader(TArrayRef<const char> data); - + void GenerateId(); }; -#pragma pack() - +#pragma pack() + #define TBUSMAX_MESSAGE 26 * 1024 * 1024 + sizeof(NBus::TBusHeader) ///< is't it enough? #define TBUSMIN_MESSAGE sizeof(NBus::TBusHeader) ///< can't be less then header - + inline bool IsVersionNegotiation(const NBus::TBusHeader& header) { return header.Id == 0 && header.Size == sizeof(TBusHeader); } ////////////////////////////////////////////////////////// /// \brief Base class for all messages passed in the system - + enum ECreateUninitialized { MESSAGE_CREATE_UNINITIALIZED, }; - + class TBusMessage : protected TBusHeader, public TRefCounted<TBusMessage, TAtomicCounter, TDelete>, @@ -175,35 +175,35 @@ namespace NBus { friend class ::NBus::NPrivate::TRemoteClientConnection; friend class ::NBus::NPrivate::TRemoteServerConnection; friend struct ::NBus::NPrivate::TBusMessagePtrAndHeader; - + private: ui32 LocalFlags; - + /// connection identity for reply set by PushMessage() NPrivate::TBusSocketAddr ReplyTo; // server-side response only, hack ui32 RequestSize; - + TInstant RecvTime; - + public: /// constructor to create messages on sending end TBusMessage(ui16 type, int approxsize = sizeof(TBusHeader)); - + /// constructor with serialzed data to examine the header TBusMessage(ECreateUninitialized); - + // slow, for diagnostics only virtual TString Describe() const; - + // must be called if this message object needs to be reused void Reset(); - + void CheckClean() const; - + void SetCompressed(bool); void SetCompressedResponse(bool); - + private: bool IsCompressed() const { return FlagsInternal & MESSAGE_COMPRESS_INTERNAL; @@ -211,11 +211,11 @@ namespace NBus { bool IsCompressedResponse() const { return FlagsInternal & MESSAGE_COMPRESS_RESPONSE; } - + public: /// can have private data to destroy virtual ~TBusMessage(); - + /// returns header of the message TBusHeader* GetHeader() { return this; @@ -223,50 +223,50 @@ namespace NBus { const TBusHeader* GetHeader() const { return this; } - + /// helper to return type for protocol object to unpack object static ui16 GetType(TArrayRef<const char> data) { return TBusHeader(data).Type; } - + /// returns payload data static TArrayRef<const char> GetPayload(TArrayRef<const char> data) { return data.Slice(sizeof(TBusHeader)); } - + private: void DoReset(); - + /// serialize message identity to be used to construct reply message void GetIdentity(TBusIdentity& ident) const; - + /// set message identity from serialized form void SetIdentity(const TBusIdentity& ident); - + public: TNetAddr GetReplyTo() const { return ReplyTo.ToNetAddr(); } - + /// store of application specific data, never serialized into wire void* Data; }; - + class TBusMessageAutoPtr: public TAutoPtr<TBusMessage> { public: TBusMessageAutoPtr() { } - + TBusMessageAutoPtr(TBusMessage* message) : TAutoPtr<TBusMessage>(message) { } - + template <typename T1> TBusMessageAutoPtr(const TAutoPtr<T1>& that) : TAutoPtr<TBusMessage>(that.Release()) { } }; - + } diff --git a/library/cpp/messagebus/message_counter.cpp b/library/cpp/messagebus/message_counter.cpp index 93092a65a6..04d9343f6a 100644 --- a/library/cpp/messagebus/message_counter.cpp +++ b/library/cpp/messagebus/message_counter.cpp @@ -1,46 +1,46 @@ #include "message_counter.h" -#include <util/stream/str.h> - -using namespace NBus; -using namespace NBus::NPrivate; - -TMessageCounter::TMessageCounter() - : BytesData(0) - , BytesNetwork(0) - , Count(0) - , CountCompressed(0) - , CountCompressionRequests(0) +#include <util/stream/str.h> + +using namespace NBus; +using namespace NBus::NPrivate; + +TMessageCounter::TMessageCounter() + : BytesData(0) + , BytesNetwork(0) + , Count(0) + , CountCompressed(0) + , CountCompressionRequests(0) { } - -TMessageCounter& TMessageCounter::operator+=(const TMessageCounter& that) { - BytesData += that.BytesData; - BytesNetwork += that.BytesNetwork; - Count += that.Count; - CountCompressed += that.CountCompressed; - CountCompressionRequests += that.CountCompressionRequests; - return *this; -} - + +TMessageCounter& TMessageCounter::operator+=(const TMessageCounter& that) { + BytesData += that.BytesData; + BytesNetwork += that.BytesNetwork; + Count += that.Count; + CountCompressed += that.CountCompressed; + CountCompressionRequests += that.CountCompressionRequests; + return *this; +} + TString TMessageCounter::ToString(bool reader) const { - if (reader) { + if (reader) { Y_ASSERT(CountCompressionRequests == 0); - } - - TStringStream readValue; - readValue << Count; - if (CountCompressionRequests != 0 || CountCompressed != 0) { - readValue << " (" << CountCompressed << " compr"; - if (!reader) { - readValue << ", " << CountCompressionRequests << " compr reqs"; - } - readValue << ")"; - } - readValue << ", "; - readValue << BytesData << "b"; - if (BytesNetwork != BytesData) { - readValue << " (" << BytesNetwork << "b network)"; - } - return readValue.Str(); -} + } + + TStringStream readValue; + readValue << Count; + if (CountCompressionRequests != 0 || CountCompressed != 0) { + readValue << " (" << CountCompressed << " compr"; + if (!reader) { + readValue << ", " << CountCompressionRequests << " compr reqs"; + } + readValue << ")"; + } + readValue << ", "; + readValue << BytesData << "b"; + if (BytesNetwork != BytesData) { + readValue << " (" << BytesNetwork << "b network)"; + } + return readValue.Str(); +} diff --git a/library/cpp/messagebus/message_counter.h b/library/cpp/messagebus/message_counter.h index c0c72df5f3..e4be1180b0 100644 --- a/library/cpp/messagebus/message_counter.h +++ b/library/cpp/messagebus/message_counter.h @@ -1,5 +1,5 @@ -#pragma once - +#pragma once + #include <util/generic/string.h> #include <cstddef> @@ -12,7 +12,7 @@ namespace NBus { size_t Count; size_t CountCompressed; size_t CountCompressionRequests; // reader only - + void AddMessage(size_t bytesData, size_t bytesCompressed, bool Compressed, bool compressionRequested) { BytesData += bytesData; BytesNetwork += bytesCompressed; @@ -24,13 +24,13 @@ namespace NBus { CountCompressionRequests += 1; } } - + TMessageCounter& operator+=(const TMessageCounter& that); - + TString ToString(bool reader) const; - + TMessageCounter(); }; - } + } } diff --git a/library/cpp/messagebus/message_ptr_and_header.h b/library/cpp/messagebus/message_ptr_and_header.h index a28ec7b08b..9b4e2fd270 100644 --- a/library/cpp/messagebus/message_ptr_and_header.h +++ b/library/cpp/messagebus/message_ptr_and_header.h @@ -1,36 +1,36 @@ -#pragma once - +#pragma once + #include "message.h" -#include "nondestroying_holder.h" - +#include "nondestroying_holder.h" + #include <util/generic/noncopyable.h> #include <util/generic/utility.h> - + namespace NBus { namespace NPrivate { struct TBusMessagePtrAndHeader : TNonCopyable { TNonDestroyingHolder<TBusMessage> MessagePtr; TBusHeader Header; ui32 LocalFlags; - + TBusMessagePtrAndHeader() : LocalFlags() { } - + explicit TBusMessagePtrAndHeader(TBusMessage* messagePtr) : MessagePtr(messagePtr) , Header(*MessagePtr->GetHeader()) , LocalFlags(MessagePtr->LocalFlags) { } - + void Swap(TBusMessagePtrAndHeader& that) { DoSwap(MessagePtr, that.MessagePtr); DoSwap(Header, that.Header); DoSwap(LocalFlags, that.LocalFlags); } }; - + } } diff --git a/library/cpp/messagebus/message_status.cpp b/library/cpp/messagebus/message_status.cpp index c895e6a9df..41ad62b73f 100644 --- a/library/cpp/messagebus/message_status.cpp +++ b/library/cpp/messagebus/message_status.cpp @@ -1,13 +1,13 @@ -#include "message_status.h" - -using namespace NBus; - -const char* NBus::MessageStatusDescription(EMessageStatus messageStatus) { +#include "message_status.h" + +using namespace NBus; + +const char* NBus::MessageStatusDescription(EMessageStatus messageStatus) { #define MESSAGE_STATUS_DESCRIPTION_GEN(name, description, ...) \ if (messageStatus == name) \ return description; - - MESSAGE_STATUS_MAP(MESSAGE_STATUS_DESCRIPTION_GEN) - - return "Unknown"; -} + + MESSAGE_STATUS_MAP(MESSAGE_STATUS_DESCRIPTION_GEN) + + return "Unknown"; +} diff --git a/library/cpp/messagebus/message_status.h b/library/cpp/messagebus/message_status.h index d7611da4dc..e1878960b3 100644 --- a/library/cpp/messagebus/message_status.h +++ b/library/cpp/messagebus/message_status.h @@ -1,14 +1,14 @@ -#pragma once - +#pragma once + #include "codegen.h" #include "defs.h" #include <library/cpp/deprecated/enum_codegen/enum_codegen.h> - -namespace NBus { -//////////////////////////////////////////////////////////////// -/// \brief Status of message communication - + +namespace NBus { +//////////////////////////////////////////////////////////////// +/// \brief Status of message communication + #define MESSAGE_STATUS_MAP(XX) \ XX(MESSAGE_OK, "OK") \ XX(MESSAGE_CONNECT_FAILED, "Connect failed") \ @@ -26,20 +26,20 @@ namespace NBus { XX(MESSAGE_SERVICE_TOOMANY, "Locator failed to resolve address") \ XX(MESSAGE_SHUTDOWN, "Failure because of either session or connection shutdown") \ XX(MESSAGE_DONT_ASK, "Internal error code used by modules") - + enum EMessageStatus { MESSAGE_STATUS_MAP(ENUM_VALUE_GEN_NO_VALUE) MESSAGE_STATUS_COUNT }; - + ENUM_TO_STRING(EMessageStatus, MESSAGE_STATUS_MAP) - + const char* MessageStatusDescription(EMessageStatus); - + static inline const char* GetMessageStatus(EMessageStatus status) { return ToCString(status); } - + // For lwtrace struct TMessageStatusField { typedef int TStoreType; @@ -53,5 +53,5 @@ namespace NBus { return value; } }; - -} // ns + +} // ns diff --git a/library/cpp/messagebus/message_status_counter.cpp b/library/cpp/messagebus/message_status_counter.cpp index 13d4cfbdab..891c8f5bb2 100644 --- a/library/cpp/messagebus/message_status_counter.cpp +++ b/library/cpp/messagebus/message_status_counter.cpp @@ -1,60 +1,60 @@ #include "message_status_counter.h" -#include "key_value_printer.h" -#include "text_utils.h" - +#include "key_value_printer.h" +#include "text_utils.h" + #include <library/cpp/messagebus/monitoring/mon_proto.pb.h> - + #include <util/stream/str.h> - -using namespace NBus; -using namespace NBus::NPrivate; - + +using namespace NBus; +using namespace NBus::NPrivate; + TMessageStatusCounter::TMessageStatusCounter() { - Zero(Counts); -} - -TMessageStatusCounter& TMessageStatusCounter::operator+=(const TMessageStatusCounter& that) { - for (size_t i = 0; i < MESSAGE_STATUS_COUNT; ++i) { - Counts[i] += that.Counts[i]; - } - return *this; -} - + Zero(Counts); +} + +TMessageStatusCounter& TMessageStatusCounter::operator+=(const TMessageStatusCounter& that) { + for (size_t i = 0; i < MESSAGE_STATUS_COUNT; ++i) { + Counts[i] += that.Counts[i]; + } + return *this; +} + TString TMessageStatusCounter::PrintToString() const { - TStringStream ss; - TKeyValuePrinter p; - bool hasNonZeros = false; - bool hasZeros = false; - for (size_t i = 0; i < MESSAGE_STATUS_COUNT; ++i) { - if (i == MESSAGE_OK) { + TStringStream ss; + TKeyValuePrinter p; + bool hasNonZeros = false; + bool hasZeros = false; + for (size_t i = 0; i < MESSAGE_STATUS_COUNT; ++i) { + if (i == MESSAGE_OK) { Y_VERIFY(Counts[i] == 0); - continue; - } - if (Counts[i] != 0) { - p.AddRow(EMessageStatus(i), Counts[i]); - const char* description = MessageStatusDescription(EMessageStatus(i)); - // TODO: add third column + continue; + } + if (Counts[i] != 0) { + p.AddRow(EMessageStatus(i), Counts[i]); + const char* description = MessageStatusDescription(EMessageStatus(i)); + // TODO: add third column Y_UNUSED(description); - - hasNonZeros = true; - } else { - hasZeros = true; - } - } - if (!hasNonZeros) { - ss << "message status counts are zeros\n"; - } else { - if (hasZeros) { - ss << "message status counts are zeros, except:\n"; - } else { - ss << "message status counts:\n"; - } - ss << IndentText(p.PrintToString()); - } - return ss.Str(); -} - + + hasNonZeros = true; + } else { + hasZeros = true; + } + } + if (!hasNonZeros) { + ss << "message status counts are zeros\n"; + } else { + if (hasZeros) { + ss << "message status counts are zeros, except:\n"; + } else { + ss << "message status counts:\n"; + } + ss << IndentText(p.PrintToString()); + } + return ss.Str(); +} + void TMessageStatusCounter::FillErrorsProtobuf(TConnectionStatusMonRecord* status) const { status->clear_errorcountbystatus(); for (size_t i = 0; i < MESSAGE_STATUS_COUNT; ++i) { diff --git a/library/cpp/messagebus/message_status_counter.h b/library/cpp/messagebus/message_status_counter.h index 18a1afd1b7..e8ba2fdd31 100644 --- a/library/cpp/messagebus/message_status_counter.h +++ b/library/cpp/messagebus/message_status_counter.h @@ -1,13 +1,13 @@ -#pragma once - +#pragma once + #include "message_status.h" #include <library/cpp/messagebus/monitoring/mon_proto.pb.h> #include <util/generic/string.h> - + #include <array> - + namespace NBus { namespace NPrivate { struct TMessageStatusCounter { @@ -16,14 +16,14 @@ namespace NBus { } std::array<unsigned, MESSAGE_STATUS_COUNT> Counts; - + unsigned& operator[](EMessageStatus index) { return Counts[index]; } const unsigned& operator[](EMessageStatus index) const { return Counts[index]; } - + TMessageStatusCounter(); TMessageStatusCounter& operator+=(const TMessageStatusCounter&); @@ -31,6 +31,6 @@ namespace NBus { TString PrintToString() const; void FillErrorsProtobuf(TConnectionStatusMonRecord*) const; }; - + } } diff --git a/library/cpp/messagebus/messqueue.cpp b/library/cpp/messagebus/messqueue.cpp index f77e54b548..3474d62705 100644 --- a/library/cpp/messagebus/messqueue.cpp +++ b/library/cpp/messagebus/messqueue.cpp @@ -1,58 +1,58 @@ #include "key_value_printer.h" #include "mb_lwtrace.h" -#include "remote_client_session.h" -#include "remote_server_session.h" +#include "remote_client_session.h" +#include "remote_server_session.h" #include "ybus.h" #include <util/generic/singleton.h> -using namespace NBus; -using namespace NBus::NPrivate; -using namespace NActor; +using namespace NBus; +using namespace NBus::NPrivate; +using namespace NActor; -TBusMessageQueuePtr NBus::CreateMessageQueue(const TBusQueueConfig& config, TExecutorPtr executor, TBusLocator* locator, const char* name) { - return new TBusMessageQueue(config, executor, locator, name); -} - -TBusMessageQueuePtr NBus::CreateMessageQueue(const TBusQueueConfig& config, TBusLocator* locator, const char* name) { - TExecutor::TConfig executorConfig; - executorConfig.WorkerCount = config.NumWorkers; - executorConfig.Name = name; - TExecutorPtr executor = new TExecutor(executorConfig); - return CreateMessageQueue(config, executor, locator, name); +TBusMessageQueuePtr NBus::CreateMessageQueue(const TBusQueueConfig& config, TExecutorPtr executor, TBusLocator* locator, const char* name) { + return new TBusMessageQueue(config, executor, locator, name); } -TBusMessageQueuePtr NBus::CreateMessageQueue(const TBusQueueConfig& config, const char* name) { - return CreateMessageQueue(config, new TBusLocator, name); +TBusMessageQueuePtr NBus::CreateMessageQueue(const TBusQueueConfig& config, TBusLocator* locator, const char* name) { + TExecutor::TConfig executorConfig; + executorConfig.WorkerCount = config.NumWorkers; + executorConfig.Name = name; + TExecutorPtr executor = new TExecutor(executorConfig); + return CreateMessageQueue(config, executor, locator, name); } -TBusMessageQueuePtr NBus::CreateMessageQueue(TExecutorPtr executor, const char* name) { - return CreateMessageQueue(TBusQueueConfig(), executor, new TBusLocator, name); -} - -TBusMessageQueuePtr NBus::CreateMessageQueue(const char* name) { +TBusMessageQueuePtr NBus::CreateMessageQueue(const TBusQueueConfig& config, const char* name) { + return CreateMessageQueue(config, new TBusLocator, name); +} + +TBusMessageQueuePtr NBus::CreateMessageQueue(TExecutorPtr executor, const char* name) { + return CreateMessageQueue(TBusQueueConfig(), executor, new TBusLocator, name); +} + +TBusMessageQueuePtr NBus::CreateMessageQueue(const char* name) { TBusQueueConfig config; - return CreateMessageQueue(config, name); + return CreateMessageQueue(config, name); } -namespace { +namespace { TBusQueueConfig QueueConfigFillDefaults(const TBusQueueConfig& orig, const TString& name) { - TBusQueueConfig patched = orig; - if (!patched.Name) { - patched.Name = name; - } - return patched; - } -} - -TBusMessageQueue::TBusMessageQueue(const TBusQueueConfig& config, TExecutorPtr executor, TBusLocator* locator, const char* name) - : Config(QueueConfigFillDefaults(config, name)) - , Locator(locator) - , WorkQueue(executor) - , Running(1) + TBusQueueConfig patched = orig; + if (!patched.Name) { + patched.Name = name; + } + return patched; + } +} + +TBusMessageQueue::TBusMessageQueue(const TBusQueueConfig& config, TExecutorPtr executor, TBusLocator* locator, const char* name) + : Config(QueueConfigFillDefaults(config, name)) + , Locator(locator) + , WorkQueue(executor) + , Running(1) { - InitBusLwtrace(); - InitNetworkSubSystem(); + InitBusLwtrace(); + InitNetworkSubSystem(); } TBusMessageQueue::~TBusMessageQueue() { @@ -60,73 +60,73 @@ TBusMessageQueue::~TBusMessageQueue() { } void TBusMessageQueue::Stop() { - if (!AtomicCas(&Running, 0, 1)) { - ShutdownComplete.WaitI(); - return; - } - - Scheduler.Stop(); - - DestroyAllSessions(); - - WorkQueue->Stop(); - - ShutdownComplete.Signal(); -} - -bool TBusMessageQueue::IsRunning() { - return AtomicGet(Running); -} - + if (!AtomicCas(&Running, 0, 1)) { + ShutdownComplete.WaitI(); + return; + } + + Scheduler.Stop(); + + DestroyAllSessions(); + + WorkQueue->Stop(); + + ShutdownComplete.Signal(); +} + +bool TBusMessageQueue::IsRunning() { + return AtomicGet(Running); +} + TBusMessageQueueStatus TBusMessageQueue::GetStatusRecordInternal() const { - TBusMessageQueueStatus r; - r.ExecutorStatus = WorkQueue->GetStatusRecordInternal(); - r.Config = Config; - return r; -} - + TBusMessageQueueStatus r; + r.ExecutorStatus = WorkQueue->GetStatusRecordInternal(); + r.Config = Config; + return r; +} + TString TBusMessageQueue::GetStatusSelf() const { - return GetStatusRecordInternal().PrintToString(); -} - + return GetStatusRecordInternal().PrintToString(); +} + TString TBusMessageQueue::GetStatusSingleLine() const { - return WorkQueue->GetStatusSingleLine(); -} - + return WorkQueue->GetStatusSingleLine(); +} + TString TBusMessageQueue::GetStatus(ui16 flags) const { - TStringStream ss; - - ss << GetStatusSelf(); - + TStringStream ss; + + ss << GetStatusSelf(); + TList<TIntrusivePtr<TBusSessionImpl>> sessions; - { - TGuard<TMutex> scope(Lock); - sessions = Sessions; - } - + { + TGuard<TMutex> scope(Lock); + sessions = Sessions; + } + for (TList<TIntrusivePtr<TBusSessionImpl>>::const_iterator session = sessions.begin(); session != sessions.end(); ++session) { - ss << Endl; - ss << (*session)->GetStatus(flags); - } - - ss << Endl; - ss << "object counts (not necessarily owned by this message queue):" << Endl; - TKeyValuePrinter p; - p.AddRow("TRemoteClientConnection", TObjectCounter<TRemoteClientConnection>::ObjectCount(), false); - p.AddRow("TRemoteServerConnection", TObjectCounter<TRemoteServerConnection>::ObjectCount(), false); - p.AddRow("TRemoteClientSession", TObjectCounter<TRemoteClientSession>::ObjectCount(), false); - p.AddRow("TRemoteServerSession", TObjectCounter<TRemoteServerSession>::ObjectCount(), false); - p.AddRow("NEventLoop::TEventLoop", TObjectCounter<NEventLoop::TEventLoop>::ObjectCount(), false); - p.AddRow("NEventLoop::TChannel", TObjectCounter<NEventLoop::TChannel>::ObjectCount(), false); - ss << p.PrintToString(); - - return ss.Str(); -} - + ss << Endl; + ss << (*session)->GetStatus(flags); + } + + ss << Endl; + ss << "object counts (not necessarily owned by this message queue):" << Endl; + TKeyValuePrinter p; + p.AddRow("TRemoteClientConnection", TObjectCounter<TRemoteClientConnection>::ObjectCount(), false); + p.AddRow("TRemoteServerConnection", TObjectCounter<TRemoteServerConnection>::ObjectCount(), false); + p.AddRow("TRemoteClientSession", TObjectCounter<TRemoteClientSession>::ObjectCount(), false); + p.AddRow("TRemoteServerSession", TObjectCounter<TRemoteServerSession>::ObjectCount(), false); + p.AddRow("NEventLoop::TEventLoop", TObjectCounter<NEventLoop::TEventLoop>::ObjectCount(), false); + p.AddRow("NEventLoop::TChannel", TObjectCounter<NEventLoop::TChannel>::ObjectCount(), false); + ss << p.PrintToString(); + + return ss.Str(); +} + TBusClientSessionPtr TBusMessageQueue::CreateSource(TBusProtocol* proto, IBusClientHandler* handler, const TBusClientSessionConfig& config, const TString& name) { - TRemoteClientSessionPtr session(new TRemoteClientSession(this, proto, handler, config, name)); - Add(session.Get()); + TRemoteClientSessionPtr session(new TRemoteClientSession(this, proto, handler, config, name)); + Add(session.Get()); return session.Get(); } @@ -161,27 +161,27 @@ TBusServerSessionPtr TBusMessageQueue::CreateDestination(TBusProtocol* proto, IB } } -void TBusMessageQueue::Add(TIntrusivePtr<TBusSessionImpl> session) { +void TBusMessageQueue::Add(TIntrusivePtr<TBusSessionImpl> session) { TGuard<TMutex> scope(Lock); Sessions.push_back(session); } -void TBusMessageQueue::Remove(TBusSession* session) { - TGuard<TMutex> scope(Lock); +void TBusMessageQueue::Remove(TBusSession* session) { + TGuard<TMutex> scope(Lock); TList<TIntrusivePtr<TBusSessionImpl>>::iterator it = std::find(Sessions.begin(), Sessions.end(), session); Y_VERIFY(it != Sessions.end(), "do not destroy session twice"); - Sessions.erase(it); -} - + Sessions.erase(it); +} + void TBusMessageQueue::Destroy(TBusSession* session) { - session->Shutdown(); -} - -void TBusMessageQueue::DestroyAllSessions() { + session->Shutdown(); +} + +void TBusMessageQueue::DestroyAllSessions() { TList<TIntrusivePtr<TBusSessionImpl>> sessions; { TGuard<TMutex> scope(Lock); - sessions = Sessions; + sessions = Sessions; } for (auto& session : sessions) { @@ -194,5 +194,5 @@ void TBusMessageQueue::Schedule(IScheduleItemAutoPtr i) { } TString TBusMessageQueue::GetNameInternal() const { - return Config.Name; -} + return Config.Name; +} diff --git a/library/cpp/messagebus/misc/atomic_box.h b/library/cpp/messagebus/misc/atomic_box.h index a7e83b70ab..401621f933 100644 --- a/library/cpp/messagebus/misc/atomic_box.h +++ b/library/cpp/messagebus/misc/atomic_box.h @@ -1,34 +1,34 @@ -#pragma once - +#pragma once + #include <util/system/atomic.h> -// TAtomic with human interface -template <typename T> -class TAtomicBox { -private: - union { - TAtomic Value; - // when T is enum, it is convenient to inspect its content in gdb - T ValueForDebugger; - }; - +// TAtomic with human interface +template <typename T> +class TAtomicBox { +private: + union { + TAtomic Value; + // when T is enum, it is convenient to inspect its content in gdb + T ValueForDebugger; + }; + static_assert(sizeof(T) <= sizeof(TAtomic), "expect sizeof(T) <= sizeof(TAtomic)"); -public: +public: TAtomicBox(T value = T()) : Value(value) { } - - void Set(T value) { + + void Set(T value) { AtomicSet(Value, (TAtomic)value); - } - - T Get() const { + } + + T Get() const { return (T)AtomicGet(Value); - } - - bool CompareAndSet(T expected, T set) { + } + + bool CompareAndSet(T expected, T set) { return AtomicCas(&Value, (TAtomicBase)set, (TAtomicBase)expected); - } -}; + } +}; diff --git a/library/cpp/messagebus/misc/test_sync.h b/library/cpp/messagebus/misc/test_sync.h index 8e5aa212aa..be3f4f20b8 100644 --- a/library/cpp/messagebus/misc/test_sync.h +++ b/library/cpp/messagebus/misc/test_sync.h @@ -1,75 +1,75 @@ -#pragma once - +#pragma once + #include <util/system/condvar.h> -#include <util/system/mutex.h> - -class TTestSync { -private: - unsigned Current; - - TMutex Mutex; - TCondVar CondVar; - -public: - TTestSync() - : Current(0) +#include <util/system/mutex.h> + +class TTestSync { +private: + unsigned Current; + + TMutex Mutex; + TCondVar CondVar; + +public: + TTestSync() + : Current(0) { } - - void Inc() { - TGuard<TMutex> guard(Mutex); - - DoInc(); - CondVar.BroadCast(); - } - - unsigned Get() { - TGuard<TMutex> guard(Mutex); - - return Current; - } - - void WaitFor(unsigned n) { - TGuard<TMutex> guard(Mutex); - + + void Inc() { + TGuard<TMutex> guard(Mutex); + + DoInc(); + CondVar.BroadCast(); + } + + unsigned Get() { + TGuard<TMutex> guard(Mutex); + + return Current; + } + + void WaitFor(unsigned n) { + TGuard<TMutex> guard(Mutex); + Y_VERIFY(Current <= n, "too late, waiting for %d, already %d", n, Current); - - while (n > Current) { - CondVar.WaitI(Mutex); - } - } - - void WaitForAndIncrement(unsigned n) { - TGuard<TMutex> guard(Mutex); - + + while (n > Current) { + CondVar.WaitI(Mutex); + } + } + + void WaitForAndIncrement(unsigned n) { + TGuard<TMutex> guard(Mutex); + Y_VERIFY(Current <= n, "too late, waiting for %d, already %d", n, Current); - - while (n > Current) { - CondVar.WaitI(Mutex); - } - - DoInc(); - CondVar.BroadCast(); - } - - void CheckAndIncrement(unsigned n) { - TGuard<TMutex> guard(Mutex); - + + while (n > Current) { + CondVar.WaitI(Mutex); + } + + DoInc(); + CondVar.BroadCast(); + } + + void CheckAndIncrement(unsigned n) { + TGuard<TMutex> guard(Mutex); + Y_VERIFY(Current == n, "must be %d, currently %d", n, Current); - - DoInc(); - CondVar.BroadCast(); - } - - void Check(unsigned n) { - TGuard<TMutex> guard(Mutex); - + + DoInc(); + CondVar.BroadCast(); + } + + void Check(unsigned n) { + TGuard<TMutex> guard(Mutex); + Y_VERIFY(Current == n, "must be %d, currently %d", n, Current); - } - -private: - void DoInc() { - unsigned r = ++Current; + } + +private: + void DoInc() { + unsigned r = ++Current; Y_UNUSED(r); - } -}; + } +}; diff --git a/library/cpp/messagebus/misc/weak_ptr.h b/library/cpp/messagebus/misc/weak_ptr.h index 46b6496d86..70fdeb0e2a 100644 --- a/library/cpp/messagebus/misc/weak_ptr.h +++ b/library/cpp/messagebus/misc/weak_ptr.h @@ -1,99 +1,99 @@ -#pragma once - -#include <util/generic/ptr.h> -#include <util/system/mutex.h> - -template <typename T> -struct TWeakPtr; - -template <typename TSelf> -struct TWeakRefCounted { +#pragma once + +#include <util/generic/ptr.h> +#include <util/system/mutex.h> + +template <typename T> +struct TWeakPtr; + +template <typename TSelf> +struct TWeakRefCounted { template <typename> friend struct TWeakPtr; -private: +private: struct TRef: public TAtomicRefCount<TRef> { - TMutex Mutex; - TSelf* Outer; - + TMutex Mutex; + TSelf* Outer; + TRef(TSelf* outer) : Outer(outer) { } - - void Release() { - TGuard<TMutex> g(Mutex); + + void Release() { + TGuard<TMutex> g(Mutex); Y_ASSERT(!!Outer); Outer = nullptr; - } - - TIntrusivePtr<TSelf> Get() { - TGuard<TMutex> g(Mutex); + } + + TIntrusivePtr<TSelf> Get() { + TGuard<TMutex> g(Mutex); Y_ASSERT(!Outer || Outer->RefCount() > 0); - return Outer; - } - }; - - TAtomicCounter Counter; - TIntrusivePtr<TRef> RefPtr; - -public: - TWeakRefCounted() - : RefPtr(new TRef(static_cast<TSelf*>(this))) + return Outer; + } + }; + + TAtomicCounter Counter; + TIntrusivePtr<TRef> RefPtr; + +public: + TWeakRefCounted() + : RefPtr(new TRef(static_cast<TSelf*>(this))) { } - - void Ref() { - Counter.Inc(); - } - - void UnRef() { - if (Counter.Dec() == 0) { - RefPtr->Release(); - - // drop is to prevent dtor from reading it - RefPtr.Drop(); - - delete static_cast<TSelf*>(this); - } - } - - void DecRef() { - Counter.Dec(); - } - - unsigned RefCount() const { - return Counter.Val(); - } -}; - -template <typename T> -struct TWeakPtr { -private: - typedef TIntrusivePtr<typename T::TRef> TRefPtr; - TRefPtr RefPtr; - -public: + + void Ref() { + Counter.Inc(); + } + + void UnRef() { + if (Counter.Dec() == 0) { + RefPtr->Release(); + + // drop is to prevent dtor from reading it + RefPtr.Drop(); + + delete static_cast<TSelf*>(this); + } + } + + void DecRef() { + Counter.Dec(); + } + + unsigned RefCount() const { + return Counter.Val(); + } +}; + +template <typename T> +struct TWeakPtr { +private: + typedef TIntrusivePtr<typename T::TRef> TRefPtr; + TRefPtr RefPtr; + +public: TWeakPtr() { } - - TWeakPtr(T* t) { - if (!!t) { - RefPtr = t->RefPtr; - } - } - - TWeakPtr(TIntrusivePtr<T> t) { - if (!!t) { - RefPtr = t->RefPtr; - } - } - - TIntrusivePtr<T> Get() { - if (!RefPtr) { + + TWeakPtr(T* t) { + if (!!t) { + RefPtr = t->RefPtr; + } + } + + TWeakPtr(TIntrusivePtr<T> t) { + if (!!t) { + RefPtr = t->RefPtr; + } + } + + TIntrusivePtr<T> Get() { + if (!RefPtr) { return nullptr; - } else { - return RefPtr->Get(); - } - } -}; + } else { + return RefPtr->Get(); + } + } +}; diff --git a/library/cpp/messagebus/misc/weak_ptr_ut.cpp b/library/cpp/messagebus/misc/weak_ptr_ut.cpp index 63d253e128..5a325278db 100644 --- a/library/cpp/messagebus/misc/weak_ptr_ut.cpp +++ b/library/cpp/messagebus/misc/weak_ptr_ut.cpp @@ -1,11 +1,11 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "weak_ptr.h" - + +#include "weak_ptr.h" + Y_UNIT_TEST_SUITE(TWeakPtrTest) { - struct TWeakPtrTester: public TWeakRefCounted<TWeakPtrTester> { - int* const CounterPtr; - + struct TWeakPtrTester: public TWeakRefCounted<TWeakPtrTester> { + int* const CounterPtr; + TWeakPtrTester(int* counterPtr) : CounterPtr(counterPtr) { @@ -13,34 +13,34 @@ Y_UNIT_TEST_SUITE(TWeakPtrTest) { ~TWeakPtrTester() { ++*CounterPtr; } - }; - + }; + Y_UNIT_TEST(Simple) { - int destroyCount = 0; - - TIntrusivePtr<TWeakPtrTester> p(new TWeakPtrTester(&destroyCount)); - - UNIT_ASSERT(!!p); - UNIT_ASSERT_VALUES_EQUAL(1u, p->RefCount()); - - TWeakPtr<TWeakPtrTester> p2(p); - - UNIT_ASSERT_VALUES_EQUAL(1u, p->RefCount()); - - { - TIntrusivePtr<TWeakPtrTester> p3 = p2.Get(); - UNIT_ASSERT(!!p3); - UNIT_ASSERT_VALUES_EQUAL(2u, p->RefCount()); - } - - p.Drop(); - UNIT_ASSERT_VALUES_EQUAL(1, destroyCount); - - { - TIntrusivePtr<TWeakPtrTester> p3 = p2.Get(); - UNIT_ASSERT(!p3); - } - - UNIT_ASSERT_VALUES_EQUAL(1, destroyCount); - } -} + int destroyCount = 0; + + TIntrusivePtr<TWeakPtrTester> p(new TWeakPtrTester(&destroyCount)); + + UNIT_ASSERT(!!p); + UNIT_ASSERT_VALUES_EQUAL(1u, p->RefCount()); + + TWeakPtr<TWeakPtrTester> p2(p); + + UNIT_ASSERT_VALUES_EQUAL(1u, p->RefCount()); + + { + TIntrusivePtr<TWeakPtrTester> p3 = p2.Get(); + UNIT_ASSERT(!!p3); + UNIT_ASSERT_VALUES_EQUAL(2u, p->RefCount()); + } + + p.Drop(); + UNIT_ASSERT_VALUES_EQUAL(1, destroyCount); + + { + TIntrusivePtr<TWeakPtrTester> p3 = p2.Get(); + UNIT_ASSERT(!p3); + } + + UNIT_ASSERT_VALUES_EQUAL(1, destroyCount); + } +} diff --git a/library/cpp/messagebus/monitoring/mon_proto.proto b/library/cpp/messagebus/monitoring/mon_proto.proto index cfc1cebe26..73b6614481 100644 --- a/library/cpp/messagebus/monitoring/mon_proto.proto +++ b/library/cpp/messagebus/monitoring/mon_proto.proto @@ -1,6 +1,6 @@ import "library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto"; - -package NBus; + +package NBus; option java_package = "ru.yandex.messagebus.monitoring.proto"; @@ -28,28 +28,28 @@ message TMessageStatusRecord { optional uint32 Count = 2; } -message TConnectionStatusMonRecord { +message TConnectionStatusMonRecord { optional uint32 SendQueueSize = 1 [ (NMonProto.Metric).Type = GAUGE ]; - // client only + // client only optional uint32 AckMessagesSize = 2 [ (NMonProto.Metric).Type = GAUGE ]; optional uint32 ErrorCount = 3 [ (NMonProto.Metric).Type = RATE ]; - + optional uint64 WriteBytes = 10 [ (NMonProto.Metric).Type = RATE ]; - optional uint64 WriteBytesCompressed = 11; + optional uint64 WriteBytesCompressed = 11; optional uint64 WriteMessages = 12 [ (NMonProto.Metric).Type = RATE ]; - optional uint64 WriteSyscalls = 13; - optional uint64 WriteActs = 14; + optional uint64 WriteSyscalls = 13; + optional uint64 WriteActs = 14; optional uint64 ReadBytes = 20 [ (NMonProto.Metric).Type = RATE ]; - optional uint64 ReadBytesCompressed = 21; + optional uint64 ReadBytesCompressed = 21; optional uint64 ReadMessages = 22 [ (NMonProto.Metric).Type = RATE ]; - optional uint64 ReadSyscalls = 23; - optional uint64 ReadActs = 24; + optional uint64 ReadSyscalls = 23; + optional uint64 ReadActs = 24; repeated TMessageStatusRecord ErrorCountByStatus = 25; -} - -message TSessionStatusMonRecord { +} + +message TSessionStatusMonRecord { optional uint32 InFlight = 1 [ (NMonProto.Metric).Type = GAUGE ]; optional uint32 ConnectionCount = 2 [ (NMonProto.Metric).Type = GAUGE ]; optional uint32 ConnectCount = 3 [ (NMonProto.Metric).Type = RATE ]; -} +} diff --git a/library/cpp/messagebus/monitoring/ya.make b/library/cpp/messagebus/monitoring/ya.make index 07df343142..25782492b1 100644 --- a/library/cpp/messagebus/monitoring/ya.make +++ b/library/cpp/messagebus/monitoring/ya.make @@ -1,15 +1,15 @@ PROTO_LIBRARY() - + OWNER(g:messagebus) - -PEERDIR( + +PEERDIR( library/cpp/monlib/encode/legacy_protobuf/protos -) - -SRCS( - mon_proto.proto -) - +) + +SRCS( + mon_proto.proto +) + EXCLUDE_TAGS(GO_PROTO) -END() +END() diff --git a/library/cpp/messagebus/moved.h b/library/cpp/messagebus/moved.h index fe3fd476b4..ede8dcd244 100644 --- a/library/cpp/messagebus/moved.h +++ b/library/cpp/messagebus/moved.h @@ -1,39 +1,39 @@ -#pragma once - -#include <util/generic/utility.h> - -template <typename T> -class TMoved { -private: - mutable T Value; - -public: +#pragma once + +#include <util/generic/utility.h> + +template <typename T> +class TMoved { +private: + mutable T Value; + +public: TMoved() { } - TMoved(const TMoved<T>& that) { - DoSwap(Value, that.Value); - } - TMoved(const T& that) { - DoSwap(Value, const_cast<T&>(that)); - } - - void swap(TMoved& that) { - DoSwap(Value, that.Value); - } - - T& operator*() { - return Value; - } - - const T& operator*() const { - return Value; - } - - T* operator->() { - return &Value; - } - - const T* operator->() const { - return &Value; - } -}; + TMoved(const TMoved<T>& that) { + DoSwap(Value, that.Value); + } + TMoved(const T& that) { + DoSwap(Value, const_cast<T&>(that)); + } + + void swap(TMoved& that) { + DoSwap(Value, that.Value); + } + + T& operator*() { + return Value; + } + + const T& operator*() const { + return Value; + } + + T* operator->() { + return &Value; + } + + const T* operator->() const { + return &Value; + } +}; diff --git a/library/cpp/messagebus/moved_ut.cpp b/library/cpp/messagebus/moved_ut.cpp index bdae344db6..c1a07cce7e 100644 --- a/library/cpp/messagebus/moved_ut.cpp +++ b/library/cpp/messagebus/moved_ut.cpp @@ -1,22 +1,22 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "moved.h" - + +#include "moved.h" + Y_UNIT_TEST_SUITE(TMovedTest) { Y_UNIT_TEST(Simple) { TMoved<THolder<int>> h1(MakeHolder<int>(10)); TMoved<THolder<int>> h2 = h1; - UNIT_ASSERT(!*h1); - UNIT_ASSERT(!!*h2); - UNIT_ASSERT_VALUES_EQUAL(10, **h2); - } - + UNIT_ASSERT(!*h1); + UNIT_ASSERT(!!*h2); + UNIT_ASSERT_VALUES_EQUAL(10, **h2); + } + void Foo(TMoved<THolder<int>> h) { - UNIT_ASSERT_VALUES_EQUAL(11, **h); - } - + UNIT_ASSERT_VALUES_EQUAL(11, **h); + } + Y_UNIT_TEST(PassToFunction) { - THolder<int> h(new int(11)); - Foo(h); - } -} + THolder<int> h(new int(11)); + Foo(h); + } +} diff --git a/library/cpp/messagebus/netaddr_ut.cpp b/library/cpp/messagebus/netaddr_ut.cpp index e9b7aafc1d..e5c68bf402 100644 --- a/library/cpp/messagebus/netaddr_ut.cpp +++ b/library/cpp/messagebus/netaddr_ut.cpp @@ -1,21 +1,21 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "netaddr.h" + +#include "netaddr.h" #include "test_utils.h" - -using namespace NBus; - + +using namespace NBus; + Y_UNIT_TEST_SUITE(TNetAddr) { Y_UNIT_TEST(ResolveIpv4) { ASSUME_IP_V4_ENABLED; - UNIT_ASSERT(TNetAddr("ns1.yandex.ru", 80, EIP_VERSION_4).IsIpv4()); - } - + UNIT_ASSERT(TNetAddr("ns1.yandex.ru", 80, EIP_VERSION_4).IsIpv4()); + } + Y_UNIT_TEST(ResolveIpv6) { - UNIT_ASSERT(TNetAddr("ns1.yandex.ru", 80, EIP_VERSION_6).IsIpv6()); - } - + UNIT_ASSERT(TNetAddr("ns1.yandex.ru", 80, EIP_VERSION_6).IsIpv6()); + } + Y_UNIT_TEST(ResolveAny) { - TNetAddr("ns1.yandex.ru", 80, EIP_VERSION_ANY); - } -} + TNetAddr("ns1.yandex.ru", 80, EIP_VERSION_ANY); + } +} diff --git a/library/cpp/messagebus/network.cpp b/library/cpp/messagebus/network.cpp index 5a0ab5163d..304bedae5a 100644 --- a/library/cpp/messagebus/network.cpp +++ b/library/cpp/messagebus/network.cpp @@ -3,27 +3,27 @@ #include <util/generic/maybe.h> #include <util/generic/ptr.h> #include <util/network/init.h> -#include <util/network/socket.h> +#include <util/network/socket.h> #include <util/system/platform.h> - -using namespace NBus; -using namespace NBus::NPrivate; - -namespace { + +using namespace NBus; +using namespace NBus::NPrivate; + +namespace { TBindResult BindOnPortProto(int port, int af, bool reusePort) { Y_VERIFY(af == AF_INET || af == AF_INET6, "wrong af"); - - SOCKET fd = ::socket(af, SOCK_STREAM, 0); + + SOCKET fd = ::socket(af, SOCK_STREAM, 0); if (fd == INVALID_SOCKET) { ythrow TSystemError() << "failed to create a socket"; } - - int one = 1; + + int one = 1; int r1 = SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, one); if (r1 < 0) { ythrow TSystemError() << "failed to setsockopt SO_REUSEADDR"; } - + #ifdef SO_REUSEPORT if (reusePort) { int r = SetSockOpt(fd, SOL_SOCKET, SO_REUSEPORT, one); @@ -35,43 +35,43 @@ namespace { Y_UNUSED(reusePort); #endif - THolder<TOpaqueAddr> addr(new TOpaqueAddr); - sockaddr* sa = addr->MutableAddr(); - sa->sa_family = af; - socklen_t len; - if (af == AF_INET) { - len = sizeof(sockaddr_in); + THolder<TOpaqueAddr> addr(new TOpaqueAddr); + sockaddr* sa = addr->MutableAddr(); + sa->sa_family = af; + socklen_t len; + if (af == AF_INET) { + len = sizeof(sockaddr_in); ((sockaddr_in*)sa)->sin_port = HostToInet((ui16)port); ((sockaddr_in*)sa)->sin_addr.s_addr = INADDR_ANY; - } else { - len = sizeof(sockaddr_in6); + } else { + len = sizeof(sockaddr_in6); ((sockaddr_in6*)sa)->sin6_port = HostToInet((ui16)port); - } - - if (af == AF_INET6) { - FixIPv6ListenSocket(fd); - } - - int r2 = ::bind(fd, sa, len); - if (r2 < 0) { + } + + if (af == AF_INET6) { + FixIPv6ListenSocket(fd); + } + + int r2 = ::bind(fd, sa, len); + if (r2 < 0) { ythrow TSystemError() << "failed to bind on port " << port; - } - - int rsn = ::getsockname(fd, addr->MutableAddr(), addr->LenPtr()); + } + + int rsn = ::getsockname(fd, addr->MutableAddr(), addr->LenPtr()); if (rsn < 0) { ythrow TSystemError() << "failed to getsockname"; } - - int r3 = ::listen(fd, 50); + + int r3 = ::listen(fd, 50); if (r3 < 0) { ythrow TSystemError() << "listen failed"; } - - TBindResult r; - r.Socket.Reset(new TSocketHolder(fd)); - r.Addr = TNetAddr(addr.Release()); - return r; - } + + TBindResult r; + r.Socket.Reset(new TSocketHolder(fd)); + r.Addr = TNetAddr(addr.Release()); + return r; + } TMaybe<TBindResult> TryBindOnPortProto(int port, int af, bool reusePort) { try { @@ -91,13 +91,13 @@ namespace { r.second.emplace_back(std::move(r2)); return r; } -} - +} + std::pair<unsigned, TVector<TBindResult>> NBus::BindOnPort(int port, bool reusePort) { std::pair<unsigned, TVector<TBindResult>> r; r.second.reserve(2); - - if (port != 0) { + + if (port != 0) { return AggregateBindResults(BindOnPortProto(port, AF_INET, reusePort), BindOnPortProto(port, AF_INET6, reusePort)); } @@ -107,50 +107,50 @@ std::pair<unsigned, TVector<TBindResult>> NBus::BindOnPort(int port, bool reuseP TMaybe<TBindResult> in4 = TryBindOnPortProto(0, AF_INET, reusePort); if (!in4) { continue; - } + } TMaybe<TBindResult> in6 = TryBindOnPortProto(in4->Addr.GetPort(), AF_INET6, reusePort); if (!in6) { continue; - } + } return AggregateBindResults(std::move(*in4), std::move(*in6)); - } + } TBindResult in4 = BindOnPortProto(0, AF_INET, reusePort); TBindResult in6 = BindOnPortProto(in4.Addr.GetPort(), AF_INET6, reusePort); return AggregateBindResults(std::move(in4), std::move(in6)); -} - -void NBus::NPrivate::SetSockOptTcpCork(SOCKET s, bool value) { -#ifdef _linux_ +} + +void NBus::NPrivate::SetSockOptTcpCork(SOCKET s, bool value) { +#ifdef _linux_ CheckedSetSockOpt(s, IPPROTO_TCP, TCP_CORK, (int)value, "TCP_CORK"); #else Y_UNUSED(s); Y_UNUSED(value); -#endif -} - +#endif +} + ssize_t NBus::NPrivate::SocketSend(SOCKET s, TArrayRef<const char> data) { - int flags = 0; -#if defined(_linux_) || defined(_freebsd_) - flags |= MSG_NOSIGNAL; -#endif - ssize_t r = ::send(s, data.data(), data.size(), flags); - if (r < 0) { + int flags = 0; +#if defined(_linux_) || defined(_freebsd_) + flags |= MSG_NOSIGNAL; +#endif + ssize_t r = ::send(s, data.data(), data.size(), flags); + if (r < 0) { Y_VERIFY(LastSystemError() != EBADF, "bad fd"); - } - return r; -} - + } + return r; +} + ssize_t NBus::NPrivate::SocketRecv(SOCKET s, TArrayRef<char> buffer) { - int flags = 0; -#if defined(_linux_) || defined(_freebsd_) - flags |= MSG_NOSIGNAL; -#endif - ssize_t r = ::recv(s, buffer.data(), buffer.size(), flags); - if (r < 0) { + int flags = 0; +#if defined(_linux_) || defined(_freebsd_) + flags |= MSG_NOSIGNAL; +#endif + ssize_t r = ::recv(s, buffer.data(), buffer.size(), flags); + if (r < 0) { Y_VERIFY(LastSystemError() != EBADF, "bad fd"); - } - return r; -} + } + return r; +} diff --git a/library/cpp/messagebus/network.h b/library/cpp/messagebus/network.h index 2bb347c38b..cc4bd76ea3 100644 --- a/library/cpp/messagebus/network.h +++ b/library/cpp/messagebus/network.h @@ -1,28 +1,28 @@ -#pragma once - +#pragma once + #include "netaddr.h" - + #include <util/generic/array_ref.h> #include <util/generic/ptr.h> -#include <util/network/socket.h> - +#include <util/network/socket.h> + #include <utility> - + namespace NBus { namespace NPrivate { void SetSockOptTcpCork(SOCKET s, bool value); - + [[nodiscard]] ssize_t SocketSend(SOCKET s, TArrayRef<const char> data); - + [[nodiscard]] ssize_t SocketRecv(SOCKET s, TArrayRef<char> buffer); - + } - + struct TBindResult { TSimpleSharedPtr<TSocketHolder> Socket; TNetAddr Addr; }; - + std::pair<unsigned, TVector<TBindResult>> BindOnPort(int port, bool reusePort); } diff --git a/library/cpp/messagebus/network_ut.cpp b/library/cpp/messagebus/network_ut.cpp index 4091b8ed7f..f1798419db 100644 --- a/library/cpp/messagebus/network_ut.cpp +++ b/library/cpp/messagebus/network_ut.cpp @@ -1,65 +1,65 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "network.h" - + +#include "network.h" + #include <library/cpp/messagebus/test/helper/fixed_port.h> -using namespace NBus; -using namespace NBus::NPrivate; -using namespace NBus::NTest; - -namespace { - int GetSockPort(SOCKET socket) { - sockaddr_storage addr; - Zero(addr); - - socklen_t len = sizeof(addr); - +using namespace NBus; +using namespace NBus::NPrivate; +using namespace NBus::NTest; + +namespace { + int GetSockPort(SOCKET socket) { + sockaddr_storage addr; + Zero(addr); + + socklen_t len = sizeof(addr); + int r = ::getsockname(socket, (sockaddr*)&addr, &len); - UNIT_ASSERT(r >= 0); - - if (addr.ss_family == AF_INET) { + UNIT_ASSERT(r >= 0); + + if (addr.ss_family == AF_INET) { sockaddr_in* addr_in = (sockaddr_in*)&addr; - return InetToHost(addr_in->sin_port); - } else if (addr.ss_family == AF_INET6) { + return InetToHost(addr_in->sin_port); + } else if (addr.ss_family == AF_INET6) { sockaddr_in6* addr_in6 = (sockaddr_in6*)&addr; - return InetToHost(addr_in6->sin6_port); - } else { - UNIT_FAIL("unknown AF"); - throw 1; - } - } -} - + return InetToHost(addr_in6->sin6_port); + } else { + UNIT_FAIL("unknown AF"); + throw 1; + } + } +} + Y_UNIT_TEST_SUITE(Network) { Y_UNIT_TEST(BindOnPortConcrete) { - if (!IsFixedPortTestAllowed()) { - return; - } - + if (!IsFixedPortTestAllowed()) { + return; + } + TVector<TBindResult> r = BindOnPort(FixedPort, false).second; - UNIT_ASSERT_VALUES_EQUAL(size_t(2), r.size()); - + UNIT_ASSERT_VALUES_EQUAL(size_t(2), r.size()); + for (TVector<TBindResult>::iterator i = r.begin(); i != r.end(); ++i) { - UNIT_ASSERT_VALUES_EQUAL(i->Addr.GetPort(), GetSockPort(i->Socket->operator SOCKET())); - } - } - + UNIT_ASSERT_VALUES_EQUAL(i->Addr.GetPort(), GetSockPort(i->Socket->operator SOCKET())); + } + } + Y_UNIT_TEST(BindOnPortRandom) { TVector<TBindResult> r = BindOnPort(0, false).second; - UNIT_ASSERT_VALUES_EQUAL(size_t(2), r.size()); - + UNIT_ASSERT_VALUES_EQUAL(size_t(2), r.size()); + for (TVector<TBindResult>::iterator i = r.begin(); i != r.end(); ++i) { - UNIT_ASSERT_VALUES_EQUAL(i->Addr.GetPort(), GetSockPort(i->Socket->operator SOCKET())); - UNIT_ASSERT(i->Addr.GetPort() > 0); - } - - UNIT_ASSERT_VALUES_EQUAL(r.at(0).Addr.GetPort(), r.at(1).Addr.GetPort()); - } + UNIT_ASSERT_VALUES_EQUAL(i->Addr.GetPort(), GetSockPort(i->Socket->operator SOCKET())); + UNIT_ASSERT(i->Addr.GetPort() > 0); + } + + UNIT_ASSERT_VALUES_EQUAL(r.at(0).Addr.GetPort(), r.at(1).Addr.GetPort()); + } Y_UNIT_TEST(BindOnBusyPort) { auto r = BindOnPort(0, false); UNIT_ASSERT_EXCEPTION_CONTAINS(BindOnPort(r.first, false), TSystemError, "failed to bind on port " + ToString(r.first)); } -} +} diff --git a/library/cpp/messagebus/nondestroying_holder.h b/library/cpp/messagebus/nondestroying_holder.h index 7349ed1381..f4725d696f 100644 --- a/library/cpp/messagebus/nondestroying_holder.h +++ b/library/cpp/messagebus/nondestroying_holder.h @@ -1,39 +1,39 @@ -#pragma once - -#include <util/generic/ptr.h> - -template <typename T> -class TNonDestroyingHolder: public THolder<T> { -public: +#pragma once + +#include <util/generic/ptr.h> + +template <typename T> +class TNonDestroyingHolder: public THolder<T> { +public: TNonDestroyingHolder(T* t = nullptr) noexcept - : THolder<T>(t) - { - } - + : THolder<T>(t) + { + } + TNonDestroyingHolder(TAutoPtr<T> t) noexcept - : THolder<T>(t) - { - } - - ~TNonDestroyingHolder() { + : THolder<T>(t) + { + } + + ~TNonDestroyingHolder() { Y_VERIFY(!*this, "stored object must be explicitly released"); - } -}; - -template <class T> -class TNonDestroyingAutoPtr: public TAutoPtr<T> { -public: + } +}; + +template <class T> +class TNonDestroyingAutoPtr: public TAutoPtr<T> { +public: inline TNonDestroyingAutoPtr(T* t = 0) noexcept - : TAutoPtr<T>(t) - { - } - + : TAutoPtr<T>(t) + { + } + inline TNonDestroyingAutoPtr(const TAutoPtr<T>& t) noexcept - : TAutoPtr<T>(t.Release()) - { - } - + : TAutoPtr<T>(t.Release()) + { + } + inline ~TNonDestroyingAutoPtr() { Y_VERIFY(!*this, "stored object must be explicitly released"); - } -}; + } +}; diff --git a/library/cpp/messagebus/nondestroying_holder_ut.cpp b/library/cpp/messagebus/nondestroying_holder_ut.cpp index 890dbc7b11..208042a2ba 100644 --- a/library/cpp/messagebus/nondestroying_holder_ut.cpp +++ b/library/cpp/messagebus/nondestroying_holder_ut.cpp @@ -1,12 +1,12 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "nondestroying_holder.h" - + +#include "nondestroying_holder.h" + Y_UNIT_TEST_SUITE(TNonDestroyingHolder) { Y_UNIT_TEST(ToAutoPtr) { - TNonDestroyingHolder<int> h(new int(11)); - TAutoPtr<int> i(h); - UNIT_ASSERT_VALUES_EQUAL(11, *i); - UNIT_ASSERT(!h); - } -} + TNonDestroyingHolder<int> h(new int(11)); + TAutoPtr<int> i(h); + UNIT_ASSERT_VALUES_EQUAL(11, *i); + UNIT_ASSERT(!h); + } +} diff --git a/library/cpp/messagebus/oldmodule/module.cpp b/library/cpp/messagebus/oldmodule/module.cpp index ccebcfb7cc..24bd778799 100644 --- a/library/cpp/messagebus/oldmodule/module.cpp +++ b/library/cpp/messagebus/oldmodule/module.cpp @@ -1,4 +1,4 @@ -#include "module.h" +#include "module.h" #include <library/cpp/messagebus/scheduler_actor.h> #include <library/cpp/messagebus/thread_extra.h> @@ -9,19 +9,19 @@ #include <util/generic/singleton.h> #include <util/string/printf.h> -#include <util/system/event.h> +#include <util/system/event.h> + +using namespace NActor; +using namespace NBus; +using namespace NBus::NPrivate; -using namespace NActor; -using namespace NBus; -using namespace NBus::NPrivate; - namespace { Y_POD_STATIC_THREAD(TBusJob*) ThreadCurrentJob; struct TThreadCurrentJobGuard { TBusJob* Prev; - + TThreadCurrentJobGuard(TBusJob* job) : Prev(ThreadCurrentJob) { @@ -32,7 +32,7 @@ namespace { ThreadCurrentJob = Prev; } }; - + void ClearState(NBus::TJobState* state) { /// skip sendbacks handlers if (state->Message != state->Reply) { @@ -46,11 +46,11 @@ namespace { state->Reply = nullptr; } } - } - + } + void ClearJobStateVector(NBus::TJobStateVec* vec) { Y_ASSERT(vec); - + for (auto& call : *vec) { ClearState(&call); } @@ -71,12 +71,12 @@ namespace NBus { : Module(module) { } - + void OnReply(TAutoPtr<TBusMessage> req, TAutoPtr<TBusMessage> reply) override; void OnMessageSentOneWay(TAutoPtr<TBusMessage> pMessage) override; void OnError(TAutoPtr<TBusMessage> msg, EMessageStatus status) override; void OnClientConnectionEvent(const TClientConnectionEvent& event) override; - + TBusModuleImpl* const Module; }; @@ -94,13 +94,13 @@ namespace NBus { struct TBusModuleImpl: public TBusModuleInternal { TBusModule* const Module; - + TBusMessageQueue* Queue; - + TScheduler Scheduler; - + const char* const Name; - + typedef TList<TJobRunner*> TBusJobList; /// jobs currently in-flight on this module TBusJobList Jobs; @@ -108,13 +108,13 @@ namespace NBus { TMutex Lock; TCondVar ShutdownCondVar; TAtomic JobCount; - + enum EState { CREATED, RUNNING, STOPPED, }; - + TAtomic State; TBusModuleConfig ModuleConfig; TBusServerSessionPtr ExternalSession; @@ -122,12 +122,12 @@ namespace NBus { THolder<IBusClientHandler> ModuleClientHandler; THolder<IBusServerHandler> ModuleServerHandler; TVector<TSimpleSharedPtr<TBusStarter>> Starters; - + // Sessions must be destroyed before // ModuleClientHandler / ModuleServerHandler TVector<TBusClientSessionPtr> ClientSessions; TVector<TBusServerSessionPtr> ServerSessions; - + TBusModuleImpl(TBusModule* module, const char* name) : Module(module) , Queue() @@ -139,12 +139,12 @@ namespace NBus { , ModuleServerHandler(new TModuleServerHandler(this)) { } - + ~TBusModuleImpl() override { // Shutdown cannot be called from destructor, // because module has virtual methods. Y_VERIFY(State != RUNNING, "if running, must explicitly call Shutdown() before destructor"); - + Scheduler.Stop(); while (!Jobs.empty()) { @@ -152,56 +152,56 @@ namespace NBus { } Y_VERIFY(JobCount == 0, "state check"); } - + void OnMessageReceived(TAutoPtr<TBusMessage> msg, TOnMessageContext&); - + void AddJob(TJobRunner* jobRunner); - + void DestroyJob(TJobRunner* job); - + /// terminate job on this message void CancelJob(TBusJob* job, EMessageStatus status); /// prints statuses of jobs TString GetStatus(unsigned flags); - + size_t Size() const { return AtomicGet(JobCount); } - + void Shutdown(); - + TVector<TBusClientSessionPtr> GetClientSessionsInternal() override { return ClientSessions; } - + TVector<TBusServerSessionPtr> GetServerSessionsInternal() override { return ServerSessions; } - + TBusMessageQueue* GetQueue() override { return Queue; } - + TString GetNameInternal() override { return Name; } - + TString GetStatusSingleLine() override { TStringStream ss; ss << "jobs: " << Size(); return ss.Str(); } - + void OnClientConnectionEvent(const TClientConnectionEvent& event) { Module->OnClientConnectionEvent(event); } }; - + struct TJobResponseMessage { TBusMessage* Request; TBusMessage* Response; EMessageStatus Status; - + TJobResponseMessage(TBusMessage* request, TBusMessage* response, EMessageStatus status) : Request(request) , Response(response) @@ -215,9 +215,9 @@ namespace NBus { public NActor::TQueueInActor<TJobRunner, TJobResponseMessage>, public TScheduleActor<TJobRunner> { THolder<TBusJob> Job; - + TList<TJobRunner*>::iterator JobStorageIterator; - + TJobRunner(TAutoPtr<TBusJob> job) : NActor::TActor<TJobRunner>(job->ModuleImpl->Queue->GetExecutor()) , TScheduleActor<TJobRunner>(&job->ModuleImpl->Scheduler) @@ -226,15 +226,15 @@ namespace NBus { { Job->Runner = this; } - + ~TJobRunner() override { Y_ASSERT(JobStorageIterator == TList<TJobRunner*>::iterator()); } - + void ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, const TJobResponseMessage& message) { Job->CallReplyHandler(message.Status, message.Request, message.Response); } - + void Destroy() { if (!!Job->OnMessageContext) { if (!Job->ReplySent) { @@ -242,24 +242,24 @@ namespace NBus { } } Job->ModuleImpl->DestroyJob(this); - } - + } + void Act(NActor::TDefaultTag) { if (JobStorageIterator == TList<TJobRunner*>::iterator()) { return; } - + if (Job->SleepUntil != 0) { if (AtomicGet(Job->ModuleImpl->State) == TBusModuleImpl::STOPPED) { Destroy(); return; } } - + TThreadCurrentJobGuard g(Job.Get()); - + NActor::TQueueInActor<TJobRunner, TJobResponseMessage>::DequeueAll(); - + if (Alarm.FetchTask()) { if (Job->AnyPendingToSend()) { Y_ASSERT(Job->SleepUntil == 0); @@ -272,50 +272,50 @@ namespace NBus { Y_ASSERT(Job->SleepUntil != 0); Job->SleepUntil = 0; } - } - + } + for (;;) { if (Job->Pending.empty() && !!Job->Handler && Job->Status == MESSAGE_OK) { TWhatThreadDoesPushPop pp("do call job handler (do not confuse with reply handler)"); - + Job->Handler = Job->Handler(Job->Module, Job.Get(), Job->Message); } - + if (Job->SleepUntil != 0) { ScheduleAt(TInstant::MilliSeconds(Job->SleepUntil)); return; } - + Job->SendPending(); - + if (Job->AnyPendingToSend()) { ScheduleAt(TInstant::Now() + TDuration::Seconds(1)); return; } - + if (!Job->Pending.empty()) { // waiting replies return; } - + if (Job->IsDone()) { Destroy(); return; } } - } + } }; - + } - + static inline TJobRunner* GetJob(TBusMessage* message) { return (TJobRunner*)message->Data; - } - + } + static inline void SetJob(TBusMessage* message, TJobRunner* job) { message->Data = job; } - + TBusJob::TBusJob(TBusModule* module, TBusMessage* message) : Status(MESSAGE_OK) , Runner() @@ -346,7 +346,7 @@ namespace NBus { ///////////////////////////////////////////////////////// /// \brief Send messages in pending list - + /// If at least one message is gone return true /// If message has not been send, move it to Finished with appropriate error code bool TBusJob::SendPending() { @@ -358,7 +358,7 @@ namespace NBus { size_t it = 0; while (it != Pending.size()) { TJobState& call = Pending[it]; - + if (call.Status == MESSAGE_DONT_ASK) { EMessageStatus getAddressStatus = MESSAGE_OK; TNetAddr addr; @@ -371,22 +371,22 @@ namespace NBus { if (getAddressStatus == MESSAGE_OK) { // hold extra reference for each request in flight Runner->Ref(); - + if (call.OneWay) { call.Status = call.Session->SendMessageOneWay(call.Message, &addr); } else { call.Status = call.Session->SendMessage(call.Message, &addr); } - + if (call.Status != MESSAGE_OK) { Runner->UnRef(); } - - } else { + + } else { call.Status = getAddressStatus; - } + } } - + if (call.Status == MESSAGE_OK) { ++it; // keep pending list until we get reply } else if (call.Status == MESSAGE_BUSY) { @@ -397,11 +397,11 @@ namespace NBus { DoCallReplyHandler(call); call.Status = MESSAGE_DONT_ASK; call.Message->Reset(); // generate new Id - } else { + } else { Finished.push_back(call); DoCallReplyHandler(call); Pending.erase(Pending.begin() + it); - } + } } return Pending.size() > 0; } @@ -419,12 +419,12 @@ namespace NBus { bool TBusJob::IsDone() { bool r = (SleepUntil == 0 && Pending.size() == 0 && (Handler == nullptr || Status != MESSAGE_OK)); return r; - } - + } + void TBusJob::CallJobHandlerOnly() { TThreadCurrentJobGuard threadCurrentJobGuard(this); TWhatThreadDoesPushPop pp("do call job handler (do not confuse with reply handler)"); - + Handler = Handler(ModuleImpl->Module, this, Message); } @@ -438,31 +438,31 @@ namespace NBus { if (Status != MESSAGE_OK) { break; } - + /// there are messages to send and wait for reply SendPending(); - + if (!Pending.empty()) { break; } - + /// asked to sleep if (SleepUntil) { break; } } - + Y_VERIFY(!(Pending.size() == 0 && Handler == nullptr && Status == MESSAGE_OK && !ReplySent), "Handler returned NULL without Cancel() or SendReply() for message=%016" PRIx64 " type=%d", Message->GetHeader()->Id, Message->GetHeader()->Type); - + return IsDone(); } - + void TBusJob::DoCallReplyHandler(TJobState& call) { if (call.Handler) { TWhatThreadDoesPushPop pp("do call reply handler (do not confuse with job handler)"); - + TThreadCurrentJobGuard threadCurrentJobGuard(this); (Module->*(call.Handler))(this, call.Status, call.Message, call.Reply); } @@ -477,7 +477,7 @@ namespace NBus { break; } } - + /// if not found, report error if (i == Pending.size()) { Y_FAIL("must not happen"); @@ -496,7 +496,7 @@ namespace NBus { DoCallReplyHandler(call); return 0; } - + /// call the handler if provided DoCallReplyHandler(call); @@ -515,50 +515,50 @@ namespace NBus { SetJob(mess.Get(), Runner); Pending.push_back(TJobState(rhandler, MESSAGE_DONT_ASK, mess.Release(), session, nullptr, maxRetries, nullptr, false)); } - + void TBusJob::Send(TBusMessageAutoPtr mess, TBusClientSession* session, TReplyHandler rhandler, size_t maxRetries, const TNetAddr& addr) { CheckThreadCurrentJob(); SetJob(mess.Get(), Runner); Pending.push_back(TJobState(rhandler, MESSAGE_DONT_ASK, mess.Release(), session, nullptr, maxRetries, &addr, false)); } - + void TBusJob::SendOneWayTo(TBusMessageAutoPtr req, TBusClientSession* session, const TNetAddr& addr) { CheckThreadCurrentJob(); SetJob(req.Get(), Runner); Pending.push_back(TJobState(nullptr, MESSAGE_DONT_ASK, req.Release(), session, nullptr, 0, &addr, true)); } - + void TBusJob::SendOneWayWithLocator(TBusMessageAutoPtr req, TBusClientSession* session) { CheckThreadCurrentJob(); - + SetJob(req.Get(), Runner); Pending.push_back(TJobState(nullptr, MESSAGE_DONT_ASK, req.Release(), session, nullptr, 0, nullptr, true)); } - + /////////////////////////////////////////////////////////////// /// send reply to the starter message void TBusJob::SendReply(TBusMessageAutoPtr reply) { CheckThreadCurrentJob(); - + Y_VERIFY(!ReplySent, "cannot call SendReply twice"); ReplySent = true; if (!OnMessageContext) return; - + EMessageStatus ok = OnMessageContext.SendReplyMove(reply); if (ok != MESSAGE_OK) { // TODO: count errors } } - + /// set the flag to terminate job at the earliest convenience void TBusJob::Cancel(EMessageStatus status) { CheckThreadCurrentJob(); - + Status = status; - } + } void TBusJob::ClearState(TJobState& call) { TJobStateVec::iterator it; @@ -580,10 +580,10 @@ namespace NBus { void TBusJob::Sleep(int milliSeconds) { CheckThreadCurrentJob(); - + Y_VERIFY(Pending.empty(), "sleep is not allowed when there are pending job"); Y_VERIFY(SleepUntil == 0, "must not override sleep"); - + SleepUntil = Now() + milliSeconds; } @@ -642,12 +642,12 @@ namespace NBus { : StarterMaxInFlight(1000) { } - + TBusModuleConfig::TSecret::TSecret() : SchedulePeriod(TDuration::Seconds(1)) { } - + TBusModule::TBusModule(const char* name) : Impl(new TBusModuleImpl(this, name)) { @@ -659,16 +659,16 @@ namespace NBus { const char* TBusModule::GetName() const { return Impl->Name; } - + void TBusModule::SetConfig(const TBusModuleConfig& config) { Impl->ModuleConfig = config; } - + bool TBusModule::StartInput() { Y_VERIFY(Impl->State == TBusModuleImpl::CREATED, "state check"); Y_VERIFY(!!Impl->Queue, "state check"); Impl->State = TBusModuleImpl::RUNNING; - + Y_ASSERT(!Impl->ExternalSession); TBusServerSessionPtr extSession = CreateExtSession(*Impl->Queue); if (extSession != nullptr) { @@ -676,14 +676,14 @@ namespace NBus { } return true; - } + } bool TBusModule::Shutdown() { Impl->Shutdown(); return true; } - + TBusJob* TBusModule::CreateJobInstance(TBusMessage* message) { TBusJob* job = new TBusJob(this, message); return job; @@ -706,11 +706,11 @@ TBusSession* TMyModule::CreateExtSession(TBusMessageQueue& queue) { int TBusModule::GetModuleSessionInFlight() const { return Impl->Size(); } - + TIntrusivePtr<TBusModuleInternal> TBusModule::GetInternal() { return Impl.Get(); } - + TBusServerSessionPtr TBusModule::CreateDefaultDestination( TBusMessageQueue& queue, TBusProtocol* proto, const TBusServerSessionConfig& config, const TString& name) { TBusServerSessionConfig patchedConfig = config; @@ -725,7 +725,7 @@ TBusSession* TMyModule::CreateExtSession(TBusMessageQueue& queue) { TBusServerSession::Create(proto, Impl->ModuleServerHandler.Get(), patchedConfig, &queue); Impl->ServerSessions.push_back(session); return session; - } + } TBusClientSessionPtr TBusModule::CreateDefaultSource( TBusMessageQueue& queue, TBusProtocol* proto, const TBusClientSessionConfig& config, const TString& name) { @@ -741,140 +741,140 @@ TBusSession* TMyModule::CreateExtSession(TBusMessageQueue& queue) { TBusClientSession::Create(proto, Impl->ModuleClientHandler.Get(), patchedConfig, &queue); Impl->ClientSessions.push_back(session); return session; - } - + } + TBusStarter* TBusModule::CreateDefaultStarter(TBusMessageQueue&, const TBusSessionConfig& config) { TBusStarter* session = new TBusStarter(this, config); Impl->Starters.push_back(session); return session; - } + } void TBusModule::OnClientConnectionEvent(const TClientConnectionEvent& event) { Y_UNUSED(event); - } - + } + TString TBusModule::GetStatus(unsigned flags) { TString strReturn = Sprintf("%s\n", Impl->Name); strReturn += Impl->GetStatus(flags); return strReturn; } - + } void TBusModuleImpl::AddJob(TJobRunner* jobRunner) { - TWhatThreadDoesAcquireGuard<TMutex> G(Lock, "modules: acquiring lock for AddJob"); - Jobs.push_back(jobRunner); - jobRunner->JobStorageIterator = Jobs.end(); - --jobRunner->JobStorageIterator; -} - + TWhatThreadDoesAcquireGuard<TMutex> G(Lock, "modules: acquiring lock for AddJob"); + Jobs.push_back(jobRunner); + jobRunner->JobStorageIterator = Jobs.end(); + --jobRunner->JobStorageIterator; +} + void TBusModuleImpl::DestroyJob(TJobRunner* job) { Y_ASSERT(job->JobStorageIterator != TList<TJobRunner*>::iterator()); - - { - TWhatThreadDoesAcquireGuard<TMutex> G(Lock, "modules: acquiring lock for DestroyJob"); - int jobCount = AtomicDecrement(JobCount); + + { + TWhatThreadDoesAcquireGuard<TMutex> G(Lock, "modules: acquiring lock for DestroyJob"); + int jobCount = AtomicDecrement(JobCount); Y_VERIFY(jobCount >= 0, "decremented too much"); - Jobs.erase(job->JobStorageIterator); - + Jobs.erase(job->JobStorageIterator); + if (AtomicGet(State) == STOPPED) { - if (jobCount == 0) { - ShutdownCondVar.BroadCast(); - } + if (jobCount == 0) { + ShutdownCondVar.BroadCast(); + } } } - + job->JobStorageIterator = TList<TJobRunner*>::iterator(); } -void TBusModuleImpl::OnMessageReceived(TAutoPtr<TBusMessage> msg0, TOnMessageContext& context) { - TBusMessage* msg = !!msg0 ? msg0.Get() : context.GetMessage(); +void TBusModuleImpl::OnMessageReceived(TAutoPtr<TBusMessage> msg0, TOnMessageContext& context) { + TBusMessage* msg = !!msg0 ? msg0.Get() : context.GetMessage(); Y_VERIFY(!!msg); - - THolder<TJobRunner> jobRunner(new TJobRunner(Module->CreateJobInstance(msg))); - jobRunner->Job->MessageHolder.Reset(msg0.Release()); - jobRunner->Job->OnMessageContext.Swap(context); - SetJob(jobRunner->Job->Message, jobRunner.Get()); - - AtomicIncrement(JobCount); - - AddJob(jobRunner.Get()); - - jobRunner.Release()->Schedule(); -} - -void TBusModuleImpl::Shutdown() { + + THolder<TJobRunner> jobRunner(new TJobRunner(Module->CreateJobInstance(msg))); + jobRunner->Job->MessageHolder.Reset(msg0.Release()); + jobRunner->Job->OnMessageContext.Swap(context); + SetJob(jobRunner->Job->Message, jobRunner.Get()); + + AtomicIncrement(JobCount); + + AddJob(jobRunner.Get()); + + jobRunner.Release()->Schedule(); +} + +void TBusModuleImpl::Shutdown() { if (AtomicGet(State) != TBusModuleImpl::RUNNING) { AtomicSet(State, TBusModuleImpl::STOPPED); - return; - } + return; + } AtomicSet(State, TBusModuleImpl::STOPPED); - + for (auto& clientSession : ClientSessions) { clientSession->Shutdown(); - } + } for (auto& serverSession : ServerSessions) { serverSession->Shutdown(); - } - - for (size_t starter = 0; starter < Starters.size(); ++starter) { - Starters[starter]->Shutdown(); - } - - { - TWhatThreadDoesAcquireGuard<TMutex> guard(Lock, "modules: acquiring lock for Shutdown"); + } + + for (size_t starter = 0; starter < Starters.size(); ++starter) { + Starters[starter]->Shutdown(); + } + + { + TWhatThreadDoesAcquireGuard<TMutex> guard(Lock, "modules: acquiring lock for Shutdown"); for (auto& Job : Jobs) { Job->Schedule(); - } - - while (!Jobs.empty()) { - ShutdownCondVar.WaitI(Lock); - } - } + } + + while (!Jobs.empty()) { + ShutdownCondVar.WaitI(Lock); + } + } } -EMessageStatus TBusModule::StartJob(TAutoPtr<TBusMessage> message) { +EMessageStatus TBusModule::StartJob(TAutoPtr<TBusMessage> message) { Y_VERIFY(Impl->State == TBusModuleImpl::RUNNING); Y_VERIFY(!!Impl->Queue); - + if ((unsigned)AtomicGet(Impl->JobCount) >= Impl->ModuleConfig.StarterMaxInFlight) { - return MESSAGE_BUSY; - } - - TOnMessageContext dummy; - Impl->OnMessageReceived(message.Release(), dummy); - - return MESSAGE_OK; -} - -void TModuleServerHandler::OnMessage(TOnMessageContext& msg) { + return MESSAGE_BUSY; + } + + TOnMessageContext dummy; + Impl->OnMessageReceived(message.Release(), dummy); + + return MESSAGE_OK; +} + +void TModuleServerHandler::OnMessage(TOnMessageContext& msg) { Module->OnMessageReceived(nullptr, msg); -} - -void TModuleClientHandler::OnReply(TAutoPtr<TBusMessage> req, TAutoPtr<TBusMessage> resp) { - TJobRunner* job = GetJob(req.Get()); +} + +void TModuleClientHandler::OnReply(TAutoPtr<TBusMessage> req, TAutoPtr<TBusMessage> resp) { + TJobRunner* job = GetJob(req.Get()); Y_ASSERT(job); Y_ASSERT(job->Job->Message != req.Get()); - job->EnqueueAndSchedule(TJobResponseMessage(req.Release(), resp.Release(), MESSAGE_OK)); - job->UnRef(); + job->EnqueueAndSchedule(TJobResponseMessage(req.Release(), resp.Release(), MESSAGE_OK)); + job->UnRef(); } -void TModuleClientHandler::OnMessageSentOneWay(TAutoPtr<TBusMessage> req) { - TJobRunner* job = GetJob(req.Get()); +void TModuleClientHandler::OnMessageSentOneWay(TAutoPtr<TBusMessage> req) { + TJobRunner* job = GetJob(req.Get()); Y_ASSERT(job); Y_ASSERT(job->Job->Message != req.Get()); job->EnqueueAndSchedule(TJobResponseMessage(req.Release(), nullptr, MESSAGE_OK)); - job->UnRef(); + job->UnRef(); } - -void TModuleClientHandler::OnError(TAutoPtr<TBusMessage> msg, EMessageStatus status) { - TJobRunner* job = GetJob(msg.Get()); - if (job) { + +void TModuleClientHandler::OnError(TAutoPtr<TBusMessage> msg, EMessageStatus status) { + TJobRunner* job = GetJob(msg.Get()); + if (job) { Y_ASSERT(job->Job->Message != msg.Get()); job->EnqueueAndSchedule(TJobResponseMessage(msg.Release(), nullptr, status)); - job->UnRef(); - } -} + job->UnRef(); + } +} void TModuleClientHandler::OnClientConnectionEvent(const TClientConnectionEvent& event) { Module->OnClientConnectionEvent(event); diff --git a/library/cpp/messagebus/oldmodule/module.h b/library/cpp/messagebus/oldmodule/module.h index ead001480c..8d1c4a5d52 100644 --- a/library/cpp/messagebus/oldmodule/module.h +++ b/library/cpp/messagebus/oldmodule/module.h @@ -40,7 +40,7 @@ /// error (not MESSAGE_OK) #include "startsession.h" - + #include <library/cpp/messagebus/ybus.h> #include <util/generic/noncopyable.h> @@ -62,7 +62,7 @@ namespace NBus { protected: typedef TJobHandler (TBusModule::*TBusHandlerPtr)(TBusJob* job, TBusMessage* mess); TBusHandlerPtr MyPtr; - + public: template <class B> TJobHandler(TJobHandler (B::*fptr)(TBusJob* job, TBusMessage* mess)) { @@ -107,7 +107,7 @@ namespace NBus { TNetAddr Addr; bool UseAddr; bool OneWay; - + private: TJobState(TReplyHandler handler, EMessageStatus status, @@ -126,7 +126,7 @@ namespace NBus { Addr = *addr; } UseAddr = !!addr; - } + } public: TString GetStatus(unsigned flags); @@ -140,10 +140,10 @@ namespace NBus { /// Maintains internal state of document in computation class TBusJob { TObjectCounter<TBusJob> ObjectCounter; - + private: void CheckThreadCurrentJob(); - + public: /// given a module and starter message TBusJob(TBusModule* module, TBusMessage* message); @@ -154,9 +154,9 @@ namespace NBus { TBusMessage* GetMessage() const { return Message; } - + TNetAddr GetPeerAddrNetAddr() const; - + /// send message to any other session or application /// If addr is set then use it as destination. void Send(TBusMessageAutoPtr mess, TBusClientSession* session, TReplyHandler rhandler, size_t maxRetries, const TNetAddr& addr); @@ -164,7 +164,7 @@ namespace NBus { void SendOneWayTo(TBusMessageAutoPtr req, TBusClientSession* session, const TNetAddr& addr); void SendOneWayWithLocator(TBusMessageAutoPtr req, TBusClientSession* session); - + /// send reply to the starter message virtual void SendReply(TBusMessageAutoPtr reply); @@ -186,7 +186,7 @@ namespace NBus { Y_ASSERT(stateVec); *stateVec = Pending; } - + /// helper function to find state of previously sent messages template <class MessageType> TJobState* GetState(int* startFrom = nullptr) { @@ -275,18 +275,18 @@ namespace NBus { void Sleep(int milliSeconds); void CallJobHandlerOnly(); - + private: bool CallJobHandler(); void DoCallReplyHandler(TJobState&); /// send out all Pending jobs, failed sends will be migrated to Finished bool SendPending(); bool AnyPendingToSend(); - + public: /// helper to call from OnReply() and OnError() int CallReplyHandler(EMessageStatus status, TBusMessage* mess, TBusMessage* reply); - + public: TJobHandler Handler; ///< job handler to be executed within next CallJobHandler() EMessageStatus Status; ///< set != MESSAGE_OK if job should terminate asap @@ -315,48 +315,48 @@ namespace NBus { //////////////////////////////////////////////////////////////////// /// \brief Classes to implement basic module functionality - + class IJobFactory { protected: virtual ~IJobFactory() { } - + public: /// job factory method, override to create custom jobs virtual TBusJob* CreateJobInstance(TBusMessage* message) = 0; - }; - + }; + struct TBusModuleConfig { unsigned StarterMaxInFlight; - + struct TSecret { TDuration SchedulePeriod; - + TSecret(); }; TSecret Secret; - + TBusModuleConfig(); }; - + namespace NPrivate { struct TBusModuleInternal: public TAtomicRefCount<TBusModuleInternal> { virtual TVector<TBusClientSessionPtr> GetClientSessionsInternal() = 0; virtual TVector<TBusServerSessionPtr> GetServerSessionsInternal() = 0; virtual TBusMessageQueue* GetQueue() = 0; - + virtual TString GetNameInternal() = 0; - + virtual TString GetStatusSingleLine() = 0; - + virtual ~TBusModuleInternal() { } }; } - + class TBusModule: public IJobFactory, TNonCopyable { friend class TBusJob; - + TObjectCounter<TBusModule> ObjectCounter; TIntrusivePtr<NPrivate::TBusModuleImpl> Impl; @@ -365,7 +365,7 @@ namespace NBus { /// Each module should have a name which is used as protocol service TBusModule(const char* name); ~TBusModule() override; - + const char* GetName() const; void SetConfig(const TBusModuleConfig& config); @@ -377,17 +377,17 @@ namespace NBus { virtual bool StartInput(); /// called when application is about to exit virtual bool Shutdown(); - + // this default implementation just creates TBusJob object TBusJob* CreateJobInstance(TBusMessage* message) override; EMessageStatus StartJob(TAutoPtr<TBusMessage> message); - + /// creates private sessions, calls CreateExtSession(), should be called before StartInput() bool CreatePrivateSessions(TBusMessageQueue* queue); - + virtual void OnClientConnectionEvent(const TClientConnectionEvent& event); - + public: /// entry point into module, first function to call virtual TJobHandler Start(TBusJob* job, TBusMessage* mess) = 0; diff --git a/library/cpp/messagebus/oldmodule/startsession.h b/library/cpp/messagebus/oldmodule/startsession.h index 864f82b316..5e26e7e1e5 100644 --- a/library/cpp/messagebus/oldmodule/startsession.h +++ b/library/cpp/messagebus/oldmodule/startsession.h @@ -15,7 +15,7 @@ namespace NBus { bool Exiting; TCondVar ExitSignal; TMutex ExitLock; - + static void* _starter(void* data); void Starter(); diff --git a/library/cpp/messagebus/oldmodule/ya.make b/library/cpp/messagebus/oldmodule/ya.make index 03ff8a46ac..ca5eae74f0 100644 --- a/library/cpp/messagebus/oldmodule/ya.make +++ b/library/cpp/messagebus/oldmodule/ya.make @@ -1,15 +1,15 @@ -LIBRARY() - +LIBRARY() + OWNER(g:messagebus) - -PEERDIR( + +PEERDIR( library/cpp/messagebus library/cpp/messagebus/actor -) - -SRCS( - module.cpp - startsession.cpp -) - -END() +) + +SRCS( + module.cpp + startsession.cpp +) + +END() diff --git a/library/cpp/messagebus/protobuf/ya.make b/library/cpp/messagebus/protobuf/ya.make index 35649705fe..64ff240b51 100644 --- a/library/cpp/messagebus/protobuf/ya.make +++ b/library/cpp/messagebus/protobuf/ya.make @@ -1,15 +1,15 @@ -LIBRARY(messagebus_protobuf) - +LIBRARY(messagebus_protobuf) + OWNER(g:messagebus) - -SRCS( - ybusbuf.cpp -) - -PEERDIR( + +SRCS( + ybusbuf.cpp +) + +PEERDIR( contrib/libs/protobuf library/cpp/messagebus library/cpp/messagebus/actor -) - -END() +) + +END() diff --git a/library/cpp/messagebus/protobuf/ybusbuf.cpp b/library/cpp/messagebus/protobuf/ybusbuf.cpp index e6fe79e2bd..63415b3737 100644 --- a/library/cpp/messagebus/protobuf/ybusbuf.cpp +++ b/library/cpp/messagebus/protobuf/ybusbuf.cpp @@ -1,88 +1,88 @@ #include "ybusbuf.h" - + #include <library/cpp/messagebus/actor/what_thread_does.h> #include <google/protobuf/io/coded_stream.h> - -using namespace NBus; - -TBusBufferProtocol::TBusBufferProtocol(TBusService name, int port) - : TBusProtocol(name, port) -{ -} - -TBusBufferProtocol::~TBusBufferProtocol() { + +using namespace NBus; + +TBusBufferProtocol::TBusBufferProtocol(TBusService name, int port) + : TBusProtocol(name, port) +{ +} + +TBusBufferProtocol::~TBusBufferProtocol() { for (auto& type : Types) { delete type; - } -} - -TBusBufferBase* TBusBufferProtocol::FindType(int type) { - for (unsigned i = 0; i < Types.size(); i++) { - if (Types[i]->GetHeader()->Type == type) { - return Types[i]; - } - } + } +} + +TBusBufferBase* TBusBufferProtocol::FindType(int type) { + for (unsigned i = 0; i < Types.size(); i++) { + if (Types[i]->GetHeader()->Type == type) { + return Types[i]; + } + } return nullptr; -} - -bool TBusBufferProtocol::IsRegisteredType(unsigned type) { - return TypeMask[type >> 5] & (1 << (type & ((1 << 5) - 1))); -} - -void TBusBufferProtocol::RegisterType(TAutoPtr<TBusBufferBase> mess) { - ui32 type = mess->GetHeader()->Type; - TypeMask[type >> 5] |= 1 << (type & ((1 << 5) - 1)); - - Types.push_back(mess.Release()); -} - +} + +bool TBusBufferProtocol::IsRegisteredType(unsigned type) { + return TypeMask[type >> 5] & (1 << (type & ((1 << 5) - 1))); +} + +void TBusBufferProtocol::RegisterType(TAutoPtr<TBusBufferBase> mess) { + ui32 type = mess->GetHeader()->Type; + TypeMask[type >> 5] |= 1 << (type & ((1 << 5) - 1)); + + Types.push_back(mess.Release()); +} + TArrayRef<TBusBufferBase* const> TBusBufferProtocol::GetTypes() const { - return Types; -} - + return Types; +} + void TBusBufferProtocol::Serialize(const TBusMessage* mess, TBuffer& data) { - TWhatThreadDoesPushPop pp("serialize protobuf message"); - + TWhatThreadDoesPushPop pp("serialize protobuf message"); + const TBusHeader* header = mess->GetHeader(); - - if (!IsRegisteredType(header->Type)) { + + if (!IsRegisteredType(header->Type)) { Y_FAIL("unknown message type: %d", int(header->Type)); - return; - } - - // cast the base from real message - const TBusBufferBase* bmess = CheckedCast<const TBusBufferBase*>(mess); - - unsigned size = bmess->GetRecord()->ByteSize(); - data.Reserve(data.Size() + size); - + return; + } + + // cast the base from real message + const TBusBufferBase* bmess = CheckedCast<const TBusBufferBase*>(mess); + + unsigned size = bmess->GetRecord()->ByteSize(); + data.Reserve(data.Size() + size); + char* after = (char*)bmess->GetRecord()->SerializeWithCachedSizesToArray((ui8*)data.Pos()); Y_VERIFY(after - data.Pos() == size); - - data.Advance(size); -} - + + data.Advance(size); +} + TAutoPtr<TBusMessage> TBusBufferProtocol::Deserialize(ui16 messageType, TArrayRef<const char> payload) { - TWhatThreadDoesPushPop pp("deserialize protobuf message"); - + TWhatThreadDoesPushPop pp("deserialize protobuf message"); + TBusBufferBase* messageTemplate = FindType(messageType); if (messageTemplate == nullptr) { return nullptr; //Y_FAIL("unknown message type: %d", unsigned(messageType)); - } - - // clone the base - TAutoPtr<TBusBufferBase> bmess = messageTemplate->New(); - + } + + // clone the base + TAutoPtr<TBusBufferBase> bmess = messageTemplate->New(); + // Need to override protobuf message size limit // NOTE: the payload size has already been checked against session MaxMessageSize google::protobuf::io::CodedInputStream input(reinterpret_cast<const ui8*>(payload.data()), payload.size()); input.SetTotalBytesLimit(payload.size()); bool ok = bmess->GetRecord()->ParseFromCodedStream(&input) && input.ConsumedEntireMessage(); - if (!ok) { + if (!ok) { return nullptr; - } - return bmess.Release(); -} + } + return bmess.Release(); +} diff --git a/library/cpp/messagebus/protobuf/ybusbuf.h b/library/cpp/messagebus/protobuf/ybusbuf.h index bdba972aa3..57b4267ea5 100644 --- a/library/cpp/messagebus/protobuf/ybusbuf.h +++ b/library/cpp/messagebus/protobuf/ybusbuf.h @@ -10,7 +10,7 @@ #include <util/stream/mem.h> #include <array> - + namespace NBus { using TBusBufferRecord = ::google::protobuf::Message; @@ -29,25 +29,25 @@ namespace NBus { : TBusMessage(MESSAGE_CREATE_UNINITIALIZED) { } - + ui16 GetType() const { return GetHeader()->Type; } - + virtual TBusBufferRecord* GetRecord() const = 0; virtual TBusBufferBase* New() = 0; }; - + /////////////////////////////////////////////////////////////////// /// \brief Template for all messages that have protobuf description - + /// @param TBufferRecord is record described in .proto file with namespace /// @param MessageFile is offset for .proto file message ids /// \attention If you want one protocol NBus::TBusBufferProtocol to handle /// messageges described in different .proto files, make sure that they have /// unique values for MessageFile - + template <class TBufferRecord, int MType> class TBusBufferMessage: public TBusBufferBase { public: @@ -93,7 +93,7 @@ namespace NBus { class TBusBufferMessagePtrBase { public: typedef typename TBufferMessage::RecordType RecordType; - + private: TSelf* GetSelf() { return static_cast<TSelf*>(this); @@ -132,7 +132,7 @@ namespace NBus { class TBusBufferMessagePtr: public TBusBufferMessagePtrBase<TBusBufferMessagePtr<TBufferMessage>, TBufferMessage> { protected: TBufferMessage* Holder; - + public: TBusBufferMessagePtr(TBufferMessage* mess) : Holder(mess) @@ -147,14 +147,14 @@ namespace NBus { const TBufferMessage* Get() const { return Holder; } - + operator TBufferMessage*() { return Holder; } operator const TBufferMessage*() const { return Holder; } - + operator TAutoPtr<TBusMessage>() { TAutoPtr<TBusMessage> r(Holder); Holder = 0; @@ -166,12 +166,12 @@ namespace NBus { return r; } }; - + template <class TBufferMessage> class TBusBufferMessageAutoPtr: public TBusBufferMessagePtrBase<TBusBufferMessageAutoPtr<TBufferMessage>, TBufferMessage> { public: TAutoPtr<TBufferMessage> AutoPtr; - + public: TBusBufferMessageAutoPtr() { } @@ -186,11 +186,11 @@ namespace NBus { const TBufferMessage* Get() const { return AutoPtr.Get(); } - + TBufferMessage* Release() const { return AutoPtr.Release(); } - + operator TAutoPtr<TBusMessage>() { return AutoPtr.Release(); } @@ -201,22 +201,22 @@ namespace NBus { ///////////////////////////////////////////// /// \brief Generic protocol object for messages descibed with protobuf - + /// \attention If you mix messages in the same protocol from more than /// .proto file make sure that they have different MessageFile parameter /// in the NBus::TBusBufferMessage template - + class TBusBufferProtocol: public TBusProtocol { private: TVector<TBusBufferBase*> Types; std::array<ui32, ((1 << 16) >> 5)> TypeMask; - + TBusBufferBase* FindType(int type); bool IsRegisteredType(unsigned type); - + public: TBusBufferProtocol(TBusService name, int port); - + ~TBusBufferProtocol() override; /// register all the message that this protocol should handle diff --git a/library/cpp/messagebus/queue_config.cpp b/library/cpp/messagebus/queue_config.cpp index 5d430970fe..78fb52ee49 100644 --- a/library/cpp/messagebus/queue_config.cpp +++ b/library/cpp/messagebus/queue_config.cpp @@ -1,22 +1,22 @@ -#include "queue_config.h" - -using namespace NBus; - -TBusQueueConfig::TBusQueueConfig() { - // workers and listeners configuratioin - NumWorkers = 1; -} - +#include "queue_config.h" + +using namespace NBus; + +TBusQueueConfig::TBusQueueConfig() { + // workers and listeners configuratioin + NumWorkers = 1; +} + void TBusQueueConfig::ConfigureLastGetopt( NLastGetopt::TOpts& opts, const TString& prefix) { opts.AddLongOption(prefix + "worker-count") .RequiredArgument("COUNT") .DefaultValue(ToString(NumWorkers)) .StoreResult(&NumWorkers); -} - +} + TString TBusQueueConfig::PrintToString() const { - TStringStream ss; - ss << "NumWorkers=" << NumWorkers << "\n"; - return ss.Str(); -} + TStringStream ss; + ss << "NumWorkers=" << NumWorkers << "\n"; + return ss.Str(); +} diff --git a/library/cpp/messagebus/queue_config.h b/library/cpp/messagebus/queue_config.h index 2b597c1b01..a9955f0c70 100644 --- a/library/cpp/messagebus/queue_config.h +++ b/library/cpp/messagebus/queue_config.h @@ -1,19 +1,19 @@ -#pragma once - +#pragma once + #include <library/cpp/getopt/last_getopt.h> - -namespace NBus { + +namespace NBus { ////////////////////////////////////////////////////////////////// /// \brief Configuration for message queue struct TBusQueueConfig { TString Name; int NumWorkers; ///< number of threads calling OnMessage(), OnReply() handlers - + TBusQueueConfig(); ///< initializes with default settings - + void ConfigureLastGetopt(NLastGetopt::TOpts&, const TString& prefix = "mb-"); - + TString PrintToString() const; }; - -} + +} diff --git a/library/cpp/messagebus/rain_check/core/coro.cpp b/library/cpp/messagebus/rain_check/core/coro.cpp index eda2fab402..500841dd5b 100644 --- a/library/cpp/messagebus/rain_check/core/coro.cpp +++ b/library/cpp/messagebus/rain_check/core/coro.cpp @@ -1,60 +1,60 @@ #include "coro.h" - -#include "coro_stack.h" - + +#include "coro_stack.h" + #include <util/system/tls.h> #include <util/system/yassert.h> - -using namespace NRainCheck; - + +using namespace NRainCheck; + TContClosure TCoroTaskRunner::ContClosure(TCoroTaskRunner* runner, TArrayRef<char> memRegion) { - TContClosure contClosure; - contClosure.TrampoLine = runner; - contClosure.Stack = memRegion; - return contClosure; -} - -TCoroTaskRunner::TCoroTaskRunner(IEnv* env, ISubtaskListener* parent, TAutoPtr<ICoroTask> impl) - : TTaskRunnerBase(env, parent, impl.Release()) - , Stack(GetImpl()->StackSize) - , ContMachineContext(ContClosure(this, Stack.MemRegion())) - , CoroDone(false) -{ -} - -TCoroTaskRunner::~TCoroTaskRunner() { + TContClosure contClosure; + contClosure.TrampoLine = runner; + contClosure.Stack = memRegion; + return contClosure; +} + +TCoroTaskRunner::TCoroTaskRunner(IEnv* env, ISubtaskListener* parent, TAutoPtr<ICoroTask> impl) + : TTaskRunnerBase(env, parent, impl.Release()) + , Stack(GetImpl()->StackSize) + , ContMachineContext(ContClosure(this, Stack.MemRegion())) + , CoroDone(false) +{ +} + +TCoroTaskRunner::~TCoroTaskRunner() { Y_ASSERT(CoroDone); -} - +} + Y_POD_STATIC_THREAD(TContMachineContext*) CallerContext; Y_POD_STATIC_THREAD(TCoroTaskRunner*) Task; - + bool TCoroTaskRunner::ReplyReceived() { Y_ASSERT(!CoroDone); - - TContMachineContext me; - - CallerContext = &me; - Task = this; - - me.SwitchTo(&ContMachineContext); - - Stack.VerifyNoStackOverflow(); - + + TContMachineContext me; + + CallerContext = &me; + Task = this; + + me.SwitchTo(&ContMachineContext); + + Stack.VerifyNoStackOverflow(); + Y_ASSERT(CallerContext == &me); Y_ASSERT(Task == this); - - return !CoroDone; -} - + + return !CoroDone; +} + void NRainCheck::TCoroTaskRunner::DoRun() { - GetImpl()->Run(); - CoroDone = true; - ContMachineContext.SwitchTo(CallerContext); -} - + GetImpl()->Run(); + CoroDone = true; + ContMachineContext.SwitchTo(CallerContext); +} + void NRainCheck::ICoroTask::WaitForSubtasks() { - Task->ContMachineContext.SwitchTo(CallerContext); -} + Task->ContMachineContext.SwitchTo(CallerContext); +} diff --git a/library/cpp/messagebus/rain_check/core/coro.h b/library/cpp/messagebus/rain_check/core/coro.h index bf2fca54bd..95e2a30f9b 100644 --- a/library/cpp/messagebus/rain_check/core/coro.h +++ b/library/cpp/messagebus/rain_check/core/coro.h @@ -1,58 +1,58 @@ -#pragma once - +#pragma once + #include "coro_stack.h" #include "task.h" #include <util/generic/ptr.h> -#include <util/memory/alloc.h> -#include <util/system/align.h> +#include <util/memory/alloc.h> +#include <util/system/align.h> #include <util/system/context.h> #include <util/system/valgrind.h> - -namespace NRainCheck { - class ICoroTask; - - class TCoroTaskRunner: public TTaskRunnerBase, private ITrampoLine { - friend class ICoroTask; - - private: - NPrivate::TCoroStack Stack; - TContMachineContext ContMachineContext; - bool CoroDone; - - public: - TCoroTaskRunner(IEnv* env, ISubtaskListener* parent, TAutoPtr<ICoroTask> impl); + +namespace NRainCheck { + class ICoroTask; + + class TCoroTaskRunner: public TTaskRunnerBase, private ITrampoLine { + friend class ICoroTask; + + private: + NPrivate::TCoroStack Stack; + TContMachineContext ContMachineContext; + bool CoroDone; + + public: + TCoroTaskRunner(IEnv* env, ISubtaskListener* parent, TAutoPtr<ICoroTask> impl); ~TCoroTaskRunner() override; - - private: + + private: static TContClosure ContClosure(TCoroTaskRunner* runner, TArrayRef<char> memRegion); - + bool ReplyReceived() override /* override */; - + void DoRun() override /* override */; - + ICoroTask* GetImpl() { return (ICoroTask*)GetImplBase(); } - }; - - class ICoroTask: public ITaskBase { - friend class TCoroTaskRunner; - - private: - size_t StackSize; - - public: - typedef TCoroTaskRunner TTaskRunner; - typedef ICoroTask ITask; - + }; + + class ICoroTask: public ITaskBase { + friend class TCoroTaskRunner; + + private: + size_t StackSize; + + public: + typedef TCoroTaskRunner TTaskRunner; + typedef ICoroTask ITask; + ICoroTask(size_t stackSize = 0x2000) : StackSize(stackSize) { } - - virtual void Run() = 0; - static void WaitForSubtasks(); - }; - -} + + virtual void Run() = 0; + static void WaitForSubtasks(); + }; + +} diff --git a/library/cpp/messagebus/rain_check/core/coro_stack.cpp b/library/cpp/messagebus/rain_check/core/coro_stack.cpp index 888d965a23..83b984ca6e 100644 --- a/library/cpp/messagebus/rain_check/core/coro_stack.cpp +++ b/library/cpp/messagebus/rain_check/core/coro_stack.cpp @@ -1,41 +1,41 @@ #include "coro_stack.h" - -#include <util/generic/singleton.h> -#include <util/system/valgrind.h> - + +#include <util/generic/singleton.h> +#include <util/system/valgrind.h> + #include <cstdlib> #include <stdio.h> - -using namespace NRainCheck; -using namespace NRainCheck::NPrivate; - -TCoroStack::TCoroStack(size_t size) - : SizeValue(size) -{ + +using namespace NRainCheck; +using namespace NRainCheck::NPrivate; + +TCoroStack::TCoroStack(size_t size) + : SizeValue(size) +{ Y_VERIFY(size % sizeof(ui32) == 0); Y_VERIFY(size >= 0x1000); - - DataHolder.Reset(malloc(size)); - - // register in valgrind - - *MagicNumberLocation() = MAGIC_NUMBER; - -#if defined(WITH_VALGRIND) + + DataHolder.Reset(malloc(size)); + + // register in valgrind + + *MagicNumberLocation() = MAGIC_NUMBER; + +#if defined(WITH_VALGRIND) ValgrindStackId = VALGRIND_STACK_REGISTER(Data(), (char*)Data() + Size()); -#endif -} - +#endif +} + TCoroStack::~TCoroStack() { -#if defined(WITH_VALGRIND) - VALGRIND_STACK_DEREGISTER(ValgrindStackId); -#endif - - VerifyNoStackOverflow(); -} - -void TCoroStack::FailStackOverflow() { - static const char message[] = "stack overflow\n"; - fputs(message, stderr); - abort(); -} +#if defined(WITH_VALGRIND) + VALGRIND_STACK_DEREGISTER(ValgrindStackId); +#endif + + VerifyNoStackOverflow(); +} + +void TCoroStack::FailStackOverflow() { + static const char message[] = "stack overflow\n"; + fputs(message, stderr); + abort(); +} diff --git a/library/cpp/messagebus/rain_check/core/coro_stack.h b/library/cpp/messagebus/rain_check/core/coro_stack.h index 41ac786470..2f3520e6e4 100644 --- a/library/cpp/messagebus/rain_check/core/coro_stack.h +++ b/library/cpp/messagebus/rain_check/core/coro_stack.h @@ -1,54 +1,54 @@ -#pragma once - +#pragma once + #include <util/generic/array_ref.h> #include <util/generic/ptr.h> -#include <util/system/valgrind.h> - +#include <util/system/valgrind.h> + namespace NRainCheck { namespace NPrivate { struct TCoroStack { THolder<void, TFree> DataHolder; size_t SizeValue; - -#if defined(WITH_VALGRIND) + +#if defined(WITH_VALGRIND) size_t ValgrindStackId; -#endif - +#endif + TCoroStack(size_t size); ~TCoroStack(); - + void* Data() { return DataHolder.Get(); } - + size_t Size() { return SizeValue; } - + TArrayRef<char> MemRegion() { return TArrayRef((char*)Data(), Size()); } - + ui32* MagicNumberLocation() { -#if STACK_GROW_DOWN == 1 +#if STACK_GROW_DOWN == 1 return (ui32*)Data(); -#elif STACK_GROW_DOWN == 0 +#elif STACK_GROW_DOWN == 0 return ((ui32*)(((char*)Data()) + Size())) - 1; -#else -#error "unknown" -#endif +#else +#error "unknown" +#endif } - + static void FailStackOverflow(); - + inline void VerifyNoStackOverflow() noexcept { if (Y_UNLIKELY(*MagicNumberLocation() != MAGIC_NUMBER)) { FailStackOverflow(); } - } - + } + static const ui32 MAGIC_NUMBER = 0xAB4D15FE; }; - + } } diff --git a/library/cpp/messagebus/rain_check/core/coro_ut.cpp b/library/cpp/messagebus/rain_check/core/coro_ut.cpp index 4ee688f4c1..61a33584a5 100644 --- a/library/cpp/messagebus/rain_check/core/coro_ut.cpp +++ b/library/cpp/messagebus/rain_check/core/coro_ut.cpp @@ -1,106 +1,106 @@ #include <library/cpp/testing/unittest/registar.h> - + #include "coro.h" -#include "spawn.h" - +#include "spawn.h" + #include <library/cpp/messagebus/rain_check/test/ut/test.h> - -using namespace NRainCheck; - + +using namespace NRainCheck; + Y_UNIT_TEST_SUITE(RainCheckCoro) { struct TSimpleCoroTask : ICoroTask { - TTestSync* const TestSync; - - TSimpleCoroTask(TTestEnv*, TTestSync* testSync) - : TestSync(testSync) - { - } - + TTestSync* const TestSync; + + TSimpleCoroTask(TTestEnv*, TTestSync* testSync) + : TestSync(testSync) + { + } + void Run() override { - TestSync->WaitForAndIncrement(0); - } - }; - + TestSync->WaitForAndIncrement(0); + } + }; + Y_UNIT_TEST(Simple) { - TTestSync testSync; - - TTestEnv env; - - TIntrusivePtr<TCoroTaskRunner> task = env.SpawnTask<TSimpleCoroTask>(&testSync); - testSync.WaitForAndIncrement(1); - } - + TTestSync testSync; + + TTestEnv env; + + TIntrusivePtr<TCoroTaskRunner> task = env.SpawnTask<TSimpleCoroTask>(&testSync); + testSync.WaitForAndIncrement(1); + } + struct TSleepCoroTask : ICoroTask { - TTestEnv* const Env; - TTestSync* const TestSync; - - TSleepCoroTask(TTestEnv* env, TTestSync* testSync) - : Env(env) - , TestSync(testSync) - { - } - - TSubtaskCompletion SleepCompletion; - + TTestEnv* const Env; + TTestSync* const TestSync; + + TSleepCoroTask(TTestEnv* env, TTestSync* testSync) + : Env(env) + , TestSync(testSync) + { + } + + TSubtaskCompletion SleepCompletion; + void Run() override { - Env->SleepService.Sleep(&SleepCompletion, TDuration::MilliSeconds(1)); - WaitForSubtasks(); - TestSync->WaitForAndIncrement(0); - } - }; - + Env->SleepService.Sleep(&SleepCompletion, TDuration::MilliSeconds(1)); + WaitForSubtasks(); + TestSync->WaitForAndIncrement(0); + } + }; + Y_UNIT_TEST(Sleep) { - TTestSync testSync; - - TTestEnv env; - - TIntrusivePtr<TCoroTaskRunner> task = env.SpawnTask<TSleepCoroTask>(&testSync); - - testSync.WaitForAndIncrement(1); - } - + TTestSync testSync; + + TTestEnv env; + + TIntrusivePtr<TCoroTaskRunner> task = env.SpawnTask<TSleepCoroTask>(&testSync); + + testSync.WaitForAndIncrement(1); + } + struct TSubtask : ICoroTask { - TTestEnv* const Env; - TTestSync* const TestSync; - - TSubtask(TTestEnv* env, TTestSync* testSync) - : Env(env) - , TestSync(testSync) - { - } - + TTestEnv* const Env; + TTestSync* const TestSync; + + TSubtask(TTestEnv* env, TTestSync* testSync) + : Env(env) + , TestSync(testSync) + { + } + void Run() override { - TestSync->CheckAndIncrement(1); - } - }; - + TestSync->CheckAndIncrement(1); + } + }; + struct TSpawnCoroTask : ICoroTask { - TTestEnv* const Env; - TTestSync* const TestSync; - - TSpawnCoroTask(TTestEnv* env, TTestSync* testSync) - : Env(env) - , TestSync(testSync) - { - } - - TSubtaskCompletion SubtaskCompletion; - + TTestEnv* const Env; + TTestSync* const TestSync; + + TSpawnCoroTask(TTestEnv* env, TTestSync* testSync) + : Env(env) + , TestSync(testSync) + { + } + + TSubtaskCompletion SubtaskCompletion; + void Run() override { - TestSync->CheckAndIncrement(0); - SpawnSubtask<TSubtask>(Env, &SubtaskCompletion, TestSync); - WaitForSubtasks(); - TestSync->CheckAndIncrement(2); - } - }; - + TestSync->CheckAndIncrement(0); + SpawnSubtask<TSubtask>(Env, &SubtaskCompletion, TestSync); + WaitForSubtasks(); + TestSync->CheckAndIncrement(2); + } + }; + Y_UNIT_TEST(Spawn) { - TTestSync testSync; - - TTestEnv env; - - TIntrusivePtr<TCoroTaskRunner> task = env.SpawnTask<TSpawnCoroTask>(&testSync); - - testSync.WaitForAndIncrement(3); - } -} + TTestSync testSync; + + TTestEnv env; + + TIntrusivePtr<TCoroTaskRunner> task = env.SpawnTask<TSpawnCoroTask>(&testSync); + + testSync.WaitForAndIncrement(3); + } +} diff --git a/library/cpp/messagebus/rain_check/core/env.cpp b/library/cpp/messagebus/rain_check/core/env.cpp index 150d63d9bb..fdc0000dbd 100644 --- a/library/cpp/messagebus/rain_check/core/env.cpp +++ b/library/cpp/messagebus/rain_check/core/env.cpp @@ -1,3 +1,3 @@ -#include "env.h" - -using namespace NRainCheck; +#include "env.h" + +using namespace NRainCheck; diff --git a/library/cpp/messagebus/rain_check/core/env.h b/library/cpp/messagebus/rain_check/core/env.h index 4e289dbd3d..f6dd7fceb6 100644 --- a/library/cpp/messagebus/rain_check/core/env.h +++ b/library/cpp/messagebus/rain_check/core/env.h @@ -1,47 +1,47 @@ -#pragma once - +#pragma once + #include "sleep.h" #include "spawn.h" - + #include <library/cpp/messagebus/actor/executor.h> - + #include <util/generic/ptr.h> - -namespace NRainCheck { - struct IEnv { - virtual ::NActor::TExecutor* GetExecutor() = 0; + +namespace NRainCheck { + struct IEnv { + virtual ::NActor::TExecutor* GetExecutor() = 0; virtual ~IEnv() { } - }; - - template <typename TSelf> - struct TEnvTemplate: public IEnv { - template <typename TTask, typename TParam> - TIntrusivePtr<typename TTask::TTaskRunner> SpawnTask(TParam param) { + }; + + template <typename TSelf> + struct TEnvTemplate: public IEnv { + template <typename TTask, typename TParam> + TIntrusivePtr<typename TTask::TTaskRunner> SpawnTask(TParam param) { return ::NRainCheck::SpawnTask<TTask, TSelf>((TSelf*)this, param); - } - }; - - template <typename TSelf> - struct TSimpleEnvTemplate: public TEnvTemplate<TSelf> { - ::NActor::TExecutorPtr Executor; - TSleepService SleepService; - - TSimpleEnvTemplate(unsigned threadCount = 0) - : Executor(new ::NActor::TExecutor(threadCount != 0 ? threadCount : 4)) + } + }; + + template <typename TSelf> + struct TSimpleEnvTemplate: public TEnvTemplate<TSelf> { + ::NActor::TExecutorPtr Executor; + TSleepService SleepService; + + TSimpleEnvTemplate(unsigned threadCount = 0) + : Executor(new ::NActor::TExecutor(threadCount != 0 ? threadCount : 4)) { } - + ::NActor::TExecutor* GetExecutor() override { return Executor.Get(); } - }; - - struct TSimpleEnv: public TSimpleEnvTemplate<TSimpleEnv> { + }; + + struct TSimpleEnv: public TSimpleEnvTemplate<TSimpleEnv> { TSimpleEnv(unsigned threadCount = 0) : TSimpleEnvTemplate<TSimpleEnv>(threadCount) { } - }; - -} + }; + +} diff --git a/library/cpp/messagebus/rain_check/core/fwd.h b/library/cpp/messagebus/rain_check/core/fwd.h index 2f8f1d4754..b43ff8c17c 100644 --- a/library/cpp/messagebus/rain_check/core/fwd.h +++ b/library/cpp/messagebus/rain_check/core/fwd.h @@ -1,18 +1,18 @@ -#pragma once - -namespace NRainCheck { - namespace NPrivate { - } - - class ITaskBase; - class ISimpleTask; - class ICoroTask; - - struct ISubtaskListener; - - class TTaskRunnerBase; - - class TSubtaskCompletion; - struct IEnv; - -} +#pragma once + +namespace NRainCheck { + namespace NPrivate { + } + + class ITaskBase; + class ISimpleTask; + class ICoroTask; + + struct ISubtaskListener; + + class TTaskRunnerBase; + + class TSubtaskCompletion; + struct IEnv; + +} diff --git a/library/cpp/messagebus/rain_check/core/rain_check.cpp b/library/cpp/messagebus/rain_check/core/rain_check.cpp index 63bc300554..2ea1f9e21b 100644 --- a/library/cpp/messagebus/rain_check/core/rain_check.cpp +++ b/library/cpp/messagebus/rain_check/core/rain_check.cpp @@ -1 +1 @@ -#include "rain_check.h" +#include "rain_check.h" diff --git a/library/cpp/messagebus/rain_check/core/rain_check.h b/library/cpp/messagebus/rain_check/core/rain_check.h index a97de4537e..0f289717a2 100644 --- a/library/cpp/messagebus/rain_check/core/rain_check.h +++ b/library/cpp/messagebus/rain_check/core/rain_check.h @@ -1,8 +1,8 @@ -#pragma once - -#include "coro.h" +#pragma once + +#include "coro.h" #include "env.h" -#include "simple.h" -#include "sleep.h" -#include "spawn.h" +#include "simple.h" +#include "sleep.h" +#include "spawn.h" #include "task.h" diff --git a/library/cpp/messagebus/rain_check/core/simple.cpp b/library/cpp/messagebus/rain_check/core/simple.cpp index 8dc71a84ee..70182b2f93 100644 --- a/library/cpp/messagebus/rain_check/core/simple.cpp +++ b/library/cpp/messagebus/rain_check/core/simple.cpp @@ -1,18 +1,18 @@ -#include "simple.h" - -using namespace NRainCheck; - -TSimpleTaskRunner::TSimpleTaskRunner(IEnv* env, ISubtaskListener* parentTask, TAutoPtr<ISimpleTask> impl) - : TTaskRunnerBase(env, parentTask, impl.Release()) - , ContinueFunc(&ISimpleTask::Start) -{ -} - -TSimpleTaskRunner::~TSimpleTaskRunner() { +#include "simple.h" + +using namespace NRainCheck; + +TSimpleTaskRunner::TSimpleTaskRunner(IEnv* env, ISubtaskListener* parentTask, TAutoPtr<ISimpleTask> impl) + : TTaskRunnerBase(env, parentTask, impl.Release()) + , ContinueFunc(&ISimpleTask::Start) +{ +} + +TSimpleTaskRunner::~TSimpleTaskRunner() { Y_ASSERT(!ContinueFunc); -} - +} + bool TSimpleTaskRunner::ReplyReceived() { - ContinueFunc = (GetImpl()->*(ContinueFunc.Func))(); - return !!ContinueFunc; -} + ContinueFunc = (GetImpl()->*(ContinueFunc.Func))(); + return !!ContinueFunc; +} diff --git a/library/cpp/messagebus/rain_check/core/simple.h b/library/cpp/messagebus/rain_check/core/simple.h index eeee4c8c23..20e1bf19f5 100644 --- a/library/cpp/messagebus/rain_check/core/simple.h +++ b/library/cpp/messagebus/rain_check/core/simple.h @@ -1,62 +1,62 @@ -#pragma once - -#include "task.h" - -namespace NRainCheck { - class ISimpleTask; - - // Function called on continue - class TContinueFunc { - friend class TSimpleTaskRunner; - - typedef TContinueFunc (ISimpleTask::*TFunc)(); - TFunc Func; - - public: - TContinueFunc() +#pragma once + +#include "task.h" + +namespace NRainCheck { + class ISimpleTask; + + // Function called on continue + class TContinueFunc { + friend class TSimpleTaskRunner; + + typedef TContinueFunc (ISimpleTask::*TFunc)(); + TFunc Func; + + public: + TContinueFunc() : Func(nullptr) { } - - TContinueFunc(void*) + + TContinueFunc(void*) : Func(nullptr) { } - - template <typename TTask> - TContinueFunc(TContinueFunc (TTask::*func)()) + + template <typename TTask> + TContinueFunc(TContinueFunc (TTask::*func)()) : Func((TFunc)func) - { + { static_assert((std::is_base_of<ISimpleTask, TTask>::value), "expect (std::is_base_of<ISimpleTask, TTask>::value)"); - } - - bool operator!() const { - return !Func; - } - }; - - class TSimpleTaskRunner: public TTaskRunnerBase { - public: - TSimpleTaskRunner(IEnv* env, ISubtaskListener* parentTask, TAutoPtr<ISimpleTask>); + } + + bool operator!() const { + return !Func; + } + }; + + class TSimpleTaskRunner: public TTaskRunnerBase { + public: + TSimpleTaskRunner(IEnv* env, ISubtaskListener* parentTask, TAutoPtr<ISimpleTask>); ~TSimpleTaskRunner() override; - - private: - // Function to be called on completion of all pending tasks. - TContinueFunc ContinueFunc; - + + private: + // Function to be called on completion of all pending tasks. + TContinueFunc ContinueFunc; + bool ReplyReceived() override /* override */; - + ISimpleTask* GetImpl() { return (ISimpleTask*)GetImplBase(); } - }; - - class ISimpleTask: public ITaskBase { - public: - typedef TSimpleTaskRunner TTaskRunner; - typedef ISimpleTask ITask; - - virtual TContinueFunc Start() = 0; - }; - -} + }; + + class ISimpleTask: public ITaskBase { + public: + typedef TSimpleTaskRunner TTaskRunner; + typedef ISimpleTask ITask; + + virtual TContinueFunc Start() = 0; + }; + +} diff --git a/library/cpp/messagebus/rain_check/core/simple_ut.cpp b/library/cpp/messagebus/rain_check/core/simple_ut.cpp index 97b5db2d89..d4545e05aa 100644 --- a/library/cpp/messagebus/rain_check/core/simple_ut.cpp +++ b/library/cpp/messagebus/rain_check/core/simple_ut.cpp @@ -1,59 +1,59 @@ #include <library/cpp/testing/unittest/registar.h> - + #include <library/cpp/messagebus/rain_check/test/ut/test.h> #include <library/cpp/messagebus/latch.h> - + #include <util/system/event.h> - -using namespace NRainCheck; - + +using namespace NRainCheck; + Y_UNIT_TEST_SUITE(RainCheckSimple) { - struct TTaskWithCompletionCallback: public ISimpleTask { - TTestEnv* const Env; - TTestSync* const TestSync; - - TTaskWithCompletionCallback(TTestEnv* env, TTestSync* testSync) - : Env(env) - , TestSync(testSync) + struct TTaskWithCompletionCallback: public ISimpleTask { + TTestEnv* const Env; + TTestSync* const TestSync; + + TTaskWithCompletionCallback(TTestEnv* env, TTestSync* testSync) + : Env(env) + , TestSync(testSync) { } - - TSubtaskCompletion SleepCompletion; - + + TSubtaskCompletion SleepCompletion; + TContinueFunc Start() override { - TestSync->CheckAndIncrement(0); - - Env->SleepService.Sleep(&SleepCompletion, TDuration::MilliSeconds(1)); - SleepCompletion.SetCompletionCallback(&TTaskWithCompletionCallback::SleepCompletionCallback); - - return &TTaskWithCompletionCallback::Last; - } - - void SleepCompletionCallback(TSubtaskCompletion* completion) { + TestSync->CheckAndIncrement(0); + + Env->SleepService.Sleep(&SleepCompletion, TDuration::MilliSeconds(1)); + SleepCompletion.SetCompletionCallback(&TTaskWithCompletionCallback::SleepCompletionCallback); + + return &TTaskWithCompletionCallback::Last; + } + + void SleepCompletionCallback(TSubtaskCompletion* completion) { Y_VERIFY(completion == &SleepCompletion); - TestSync->CheckAndIncrement(1); - - Env->SleepService.Sleep(&SleepCompletion, TDuration::MilliSeconds(1)); - SleepCompletion.SetCompletionCallback(&TTaskWithCompletionCallback::NextSleepCompletionCallback); - } - + TestSync->CheckAndIncrement(1); + + Env->SleepService.Sleep(&SleepCompletion, TDuration::MilliSeconds(1)); + SleepCompletion.SetCompletionCallback(&TTaskWithCompletionCallback::NextSleepCompletionCallback); + } + void NextSleepCompletionCallback(TSubtaskCompletion*) { - TestSync->CheckAndIncrement(2); - } - - TContinueFunc Last() { - TestSync->CheckAndIncrement(3); + TestSync->CheckAndIncrement(2); + } + + TContinueFunc Last() { + TestSync->CheckAndIncrement(3); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(CompletionCallback) { - TTestEnv env; - TTestSync testSync; - - env.SpawnTask<TTaskWithCompletionCallback>(&testSync); - - testSync.WaitForAndIncrement(4); - } -} + TTestEnv env; + TTestSync testSync; + + env.SpawnTask<TTaskWithCompletionCallback>(&testSync); + + testSync.WaitForAndIncrement(4); + } +} diff --git a/library/cpp/messagebus/rain_check/core/sleep.cpp b/library/cpp/messagebus/rain_check/core/sleep.cpp index 10b875bc79..f5d0b4cac9 100644 --- a/library/cpp/messagebus/rain_check/core/sleep.cpp +++ b/library/cpp/messagebus/rain_check/core/sleep.cpp @@ -1,47 +1,47 @@ #include "rain_check.h" -#include <util/system/yassert.h> - -using namespace NRainCheck; -using namespace NRainCheck::NPrivate; -using namespace NBus; -using namespace NBus::NPrivate; - -TSleepService::TSleepService(::NBus::NPrivate::TScheduler* scheduler) - : Scheduler(scheduler) -{ -} - -NRainCheck::TSleepService::TSleepService() - : SchedulerHolder(new TScheduler) - , Scheduler(SchedulerHolder.Get()) -{ -} - +#include <util/system/yassert.h> + +using namespace NRainCheck; +using namespace NRainCheck::NPrivate; +using namespace NBus; +using namespace NBus::NPrivate; + +TSleepService::TSleepService(::NBus::NPrivate::TScheduler* scheduler) + : Scheduler(scheduler) +{ +} + +NRainCheck::TSleepService::TSleepService() + : SchedulerHolder(new TScheduler) + , Scheduler(SchedulerHolder.Get()) +{ +} + NRainCheck::TSleepService::~TSleepService() { - if (!!SchedulerHolder) { - Scheduler->Stop(); - } -} - -namespace { - struct TSleepServiceScheduleItem: public IScheduleItem { - ISubtaskListener* const Parent; - - TSleepServiceScheduleItem(ISubtaskListener* parent, TInstant time) - : IScheduleItem(time) - , Parent(parent) - { - } - + if (!!SchedulerHolder) { + Scheduler->Stop(); + } +} + +namespace { + struct TSleepServiceScheduleItem: public IScheduleItem { + ISubtaskListener* const Parent; + + TSleepServiceScheduleItem(ISubtaskListener* parent, TInstant time) + : IScheduleItem(time) + , Parent(parent) + { + } + void Do() override { - Parent->SetDone(); - } - }; -} - + Parent->SetDone(); + } + }; +} + void TSleepService::Sleep(TSubtaskCompletion* r, TDuration duration) { - TTaskRunnerBase* current = TTaskRunnerBase::CurrentTask(); - r->SetRunning(current); - Scheduler->Schedule(new TSleepServiceScheduleItem(r, TInstant::Now() + duration)); -} + TTaskRunnerBase* current = TTaskRunnerBase::CurrentTask(); + r->SetRunning(current); + Scheduler->Schedule(new TSleepServiceScheduleItem(r, TInstant::Now() + duration)); +} diff --git a/library/cpp/messagebus/rain_check/core/sleep.h b/library/cpp/messagebus/rain_check/core/sleep.h index b5b343de98..1a7a1f8674 100644 --- a/library/cpp/messagebus/rain_check/core/sleep.h +++ b/library/cpp/messagebus/rain_check/core/sleep.h @@ -1,24 +1,24 @@ -#pragma once - +#pragma once + #include "fwd.h" - + #include <library/cpp/messagebus/scheduler/scheduler.h> - + #include <util/datetime/base.h> - -namespace NRainCheck { - class TSleepService { - private: - THolder< ::NBus::NPrivate::TScheduler> SchedulerHolder; - ::NBus::NPrivate::TScheduler* const Scheduler; - public: - TSleepService(::NBus::NPrivate::TScheduler*); - TSleepService(); - ~TSleepService(); - - // Wake up a task after given duration. - void Sleep(TSubtaskCompletion* r, TDuration); - }; - -} +namespace NRainCheck { + class TSleepService { + private: + THolder< ::NBus::NPrivate::TScheduler> SchedulerHolder; + ::NBus::NPrivate::TScheduler* const Scheduler; + + public: + TSleepService(::NBus::NPrivate::TScheduler*); + TSleepService(); + ~TSleepService(); + + // Wake up a task after given duration. + void Sleep(TSubtaskCompletion* r, TDuration); + }; + +} diff --git a/library/cpp/messagebus/rain_check/core/sleep_ut.cpp b/library/cpp/messagebus/rain_check/core/sleep_ut.cpp index 3c92fa2ca7..2ae85a87b1 100644 --- a/library/cpp/messagebus/rain_check/core/sleep_ut.cpp +++ b/library/cpp/messagebus/rain_check/core/sleep_ut.cpp @@ -1,46 +1,46 @@ #include <library/cpp/testing/unittest/registar.h> - + #include <library/cpp/messagebus/rain_check/test/ut/test.h> - + #include <util/system/event.h> -using namespace NRainCheck; -using namespace NActor; - +using namespace NRainCheck; +using namespace NActor; + Y_UNIT_TEST_SUITE(Sleep) { - struct TTestTask: public ISimpleTask { - TSimpleEnv* const Env; - TTestSync* const TestSync; - - TTestTask(TSimpleEnv* env, TTestSync* testSync) - : Env(env) - , TestSync(testSync) + struct TTestTask: public ISimpleTask { + TSimpleEnv* const Env; + TTestSync* const TestSync; + + TTestTask(TSimpleEnv* env, TTestSync* testSync) + : Env(env) + , TestSync(testSync) { } - - TSubtaskCompletion Sleep; - + + TSubtaskCompletion Sleep; + TContinueFunc Start() override { - Env->SleepService.Sleep(&Sleep, TDuration::MilliSeconds(1)); - - TestSync->CheckAndIncrement(0); - - return &TTestTask::Continue; - } - - TContinueFunc Continue() { - TestSync->CheckAndIncrement(1); + Env->SleepService.Sleep(&Sleep, TDuration::MilliSeconds(1)); + + TestSync->CheckAndIncrement(0); + + return &TTestTask::Continue; + } + + TContinueFunc Continue() { + TestSync->CheckAndIncrement(1); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(Test) { - TTestSync testSync; - - TSimpleEnv env; - - TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<TTestTask>(&testSync); - - testSync.WaitForAndIncrement(2); - } -} + TTestSync testSync; + + TSimpleEnv env; + + TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<TTestTask>(&testSync); + + testSync.WaitForAndIncrement(2); + } +} diff --git a/library/cpp/messagebus/rain_check/core/spawn.cpp b/library/cpp/messagebus/rain_check/core/spawn.cpp index d8fc78c129..c570355fbe 100644 --- a/library/cpp/messagebus/rain_check/core/spawn.cpp +++ b/library/cpp/messagebus/rain_check/core/spawn.cpp @@ -1,5 +1,5 @@ -#include "spawn.h" - +#include "spawn.h" + void NRainCheck::NPrivate::SpawnTaskImpl(TTaskRunnerBase* task) { - task->Schedule(); -} + task->Schedule(); +} diff --git a/library/cpp/messagebus/rain_check/core/spawn.h b/library/cpp/messagebus/rain_check/core/spawn.h index 33ba955e0a..f2b146bf29 100644 --- a/library/cpp/messagebus/rain_check/core/spawn.h +++ b/library/cpp/messagebus/rain_check/core/spawn.h @@ -1,50 +1,50 @@ -#pragma once - -#include "coro.h" -#include "simple.h" +#pragma once + +#include "coro.h" +#include "simple.h" #include "task.h" - -namespace NRainCheck { - namespace NPrivate { - void SpawnTaskImpl(TTaskRunnerBase* task); - - template <typename TTask, typename ITask, typename TRunner, typename TEnv, typename TParam> - TIntrusivePtr<TRunner> SpawnTaskWithRunner(TEnv* env, TParam param1, ISubtaskListener* subtaskListener) { + +namespace NRainCheck { + namespace NPrivate { + void SpawnTaskImpl(TTaskRunnerBase* task); + + template <typename TTask, typename ITask, typename TRunner, typename TEnv, typename TParam> + TIntrusivePtr<TRunner> SpawnTaskWithRunner(TEnv* env, TParam param1, ISubtaskListener* subtaskListener) { static_assert((std::is_base_of<ITask, TTask>::value), "expect (std::is_base_of<ITask, TTask>::value)"); - TIntrusivePtr<TRunner> task(new TRunner(env, subtaskListener, new TTask(env, param1))); - NPrivate::SpawnTaskImpl(task.Get()); - return task; - } - - template <typename TTask, typename ITask, typename TRunner, typename TEnv> - void SpawnSubtaskWithRunner(TEnv* env, TSubtaskCompletion* completion) { + TIntrusivePtr<TRunner> task(new TRunner(env, subtaskListener, new TTask(env, param1))); + NPrivate::SpawnTaskImpl(task.Get()); + return task; + } + + template <typename TTask, typename ITask, typename TRunner, typename TEnv> + void SpawnSubtaskWithRunner(TEnv* env, TSubtaskCompletion* completion) { static_assert((std::is_base_of<ITask, TTask>::value), "expect (std::is_base_of<ITask, TTask>::value)"); - TTaskRunnerBase* current = TTaskRunnerBase::CurrentTask(); - completion->SetRunning(current); - NPrivate::SpawnTaskImpl(new TRunner(env, completion, new TTask(env))); - } - - template <typename TTask, typename ITask, typename TRunner, typename TEnv, typename TParam> - void SpawnSubtaskWithRunner(TEnv* env, TSubtaskCompletion* completion, TParam param) { + TTaskRunnerBase* current = TTaskRunnerBase::CurrentTask(); + completion->SetRunning(current); + NPrivate::SpawnTaskImpl(new TRunner(env, completion, new TTask(env))); + } + + template <typename TTask, typename ITask, typename TRunner, typename TEnv, typename TParam> + void SpawnSubtaskWithRunner(TEnv* env, TSubtaskCompletion* completion, TParam param) { static_assert((std::is_base_of<ITask, TTask>::value), "expect (std::is_base_of<ITask, TTask>::value)"); - TTaskRunnerBase* current = TTaskRunnerBase::CurrentTask(); - completion->SetRunning(current); - NPrivate::SpawnTaskImpl(new TRunner(env, completion, new TTask(env, param))); - } - - } - - // Instantiate and start a task with given parameter. - template <typename TTask, typename TEnv, typename TParam> - TIntrusivePtr<typename TTask::TTaskRunner> SpawnTask(TEnv* env, TParam param1, ISubtaskListener* subtaskListener = &TNopSubtaskListener::Instance) { - return NPrivate::SpawnTaskWithRunner< + TTaskRunnerBase* current = TTaskRunnerBase::CurrentTask(); + completion->SetRunning(current); + NPrivate::SpawnTaskImpl(new TRunner(env, completion, new TTask(env, param))); + } + + } + + // Instantiate and start a task with given parameter. + template <typename TTask, typename TEnv, typename TParam> + TIntrusivePtr<typename TTask::TTaskRunner> SpawnTask(TEnv* env, TParam param1, ISubtaskListener* subtaskListener = &TNopSubtaskListener::Instance) { + return NPrivate::SpawnTaskWithRunner< TTask, typename TTask::ITask, typename TTask::TTaskRunner, TEnv, TParam>(env, param1, subtaskListener); - } - - // Instantiate and start subtask of given task. - template <typename TTask, typename TEnv, typename TParam> - void SpawnSubtask(TEnv* env, TSubtaskCompletion* completion, TParam param) { - return NPrivate::SpawnSubtaskWithRunner<TTask, typename TTask::ITask, typename TTask::TTaskRunner>(env, completion, param); - } - -} + } + + // Instantiate and start subtask of given task. + template <typename TTask, typename TEnv, typename TParam> + void SpawnSubtask(TEnv* env, TSubtaskCompletion* completion, TParam param) { + return NPrivate::SpawnSubtaskWithRunner<TTask, typename TTask::ITask, typename TTask::TTaskRunner>(env, completion, param); + } + +} diff --git a/library/cpp/messagebus/rain_check/core/spawn_ut.cpp b/library/cpp/messagebus/rain_check/core/spawn_ut.cpp index 2b3ef75c67..ba5a5e41cf 100644 --- a/library/cpp/messagebus/rain_check/core/spawn_ut.cpp +++ b/library/cpp/messagebus/rain_check/core/spawn_ut.cpp @@ -1,145 +1,145 @@ #include <library/cpp/testing/unittest/registar.h> - + #include <library/cpp/messagebus/rain_check/test/helper/misc.h> #include <library/cpp/messagebus/rain_check/test/ut/test.h> #include <library/cpp/messagebus/latch.h> - + #include <util/system/event.h> - + #include <array> - -using namespace NRainCheck; -using namespace NActor; - + +using namespace NRainCheck; +using namespace NActor; + Y_UNIT_TEST_SUITE(Spawn) { - struct TTestTask: public ISimpleTask { - TTestSync* const TestSync; - - TTestTask(TSimpleEnv*, TTestSync* testSync) - : TestSync(testSync) - , I(0) + struct TTestTask: public ISimpleTask { + TTestSync* const TestSync; + + TTestTask(TSimpleEnv*, TTestSync* testSync) + : TestSync(testSync) + , I(0) { } - + TSystemEvent Started; - - unsigned I; - + + unsigned I; + TContinueFunc Start() override { - if (I < 4) { - I += 1; - return &TTestTask::Start; - } - TestSync->CheckAndIncrement(0); - return &TTestTask::Continue; - } - - TContinueFunc Continue() { - TestSync->CheckAndIncrement(1); - - Started.Signal(); + if (I < 4) { + I += 1; + return &TTestTask::Start; + } + TestSync->CheckAndIncrement(0); + return &TTestTask::Continue; + } + + TContinueFunc Continue() { + TestSync->CheckAndIncrement(1); + + Started.Signal(); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(Continuation) { - TTestSync testSync; - - TSimpleEnv env; - - TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<TTestTask>(&testSync); - - testSync.WaitForAndIncrement(2); - } - - struct TSubtask: public ISimpleTask { - TTestEnv* const Env; - TTestSync* const TestSync; - - TSubtask(TTestEnv* env, TTestSync* testSync) - : Env(env) - , TestSync(testSync) + TTestSync testSync; + + TSimpleEnv env; + + TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<TTestTask>(&testSync); + + testSync.WaitForAndIncrement(2); + } + + struct TSubtask: public ISimpleTask { + TTestEnv* const Env; + TTestSync* const TestSync; + + TSubtask(TTestEnv* env, TTestSync* testSync) + : Env(env) + , TestSync(testSync) { } - + TContinueFunc Start() override { - Sleep(TDuration::MilliSeconds(1)); - TestSync->CheckAndIncrement(1); + Sleep(TDuration::MilliSeconds(1)); + TestSync->CheckAndIncrement(1); return nullptr; - } - }; - - struct TSpawnTask: public ISimpleTask { - TTestEnv* const Env; - TTestSync* const TestSync; - - TSpawnTask(TTestEnv* env, TTestSync* testSync) - : Env(env) - , TestSync(testSync) + } + }; + + struct TSpawnTask: public ISimpleTask { + TTestEnv* const Env; + TTestSync* const TestSync; + + TSpawnTask(TTestEnv* env, TTestSync* testSync) + : Env(env) + , TestSync(testSync) { } - - TSubtaskCompletion SubtaskCompletion; - + + TSubtaskCompletion SubtaskCompletion; + TContinueFunc Start() override { - TestSync->CheckAndIncrement(0); - SpawnSubtask<TSubtask>(Env, &SubtaskCompletion, TestSync); - return &TSpawnTask::Continue; - } - - TContinueFunc Continue() { - TestSync->CheckAndIncrement(2); + TestSync->CheckAndIncrement(0); + SpawnSubtask<TSubtask>(Env, &SubtaskCompletion, TestSync); + return &TSpawnTask::Continue; + } + + TContinueFunc Continue() { + TestSync->CheckAndIncrement(2); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(Subtask) { - TTestSync testSync; - - TTestEnv env; - - TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<TSpawnTask>(&testSync); - - testSync.WaitForAndIncrement(3); - } - - struct TSpawnLongTask: public ISimpleTask { - TTestEnv* const Env; - TTestSync* const TestSync; - unsigned I; - + TTestSync testSync; + + TTestEnv env; + + TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<TSpawnTask>(&testSync); + + testSync.WaitForAndIncrement(3); + } + + struct TSpawnLongTask: public ISimpleTask { + TTestEnv* const Env; + TTestSync* const TestSync; + unsigned I; + TSpawnLongTask(TTestEnv* env, TTestSync* testSync) : Env(env) , TestSync(testSync) , I(0) { } - + std::array<TSubtaskCompletion, 3> Subtasks; - + TContinueFunc Start() override { - if (I == 1000) { - TestSync->CheckAndIncrement(0); + if (I == 1000) { + TestSync->CheckAndIncrement(0); return nullptr; - } - + } + for (auto& subtask : Subtasks) { SpawnSubtask<TNopSimpleTask>(Env, &subtask, ""); - } - - ++I; - return &TSpawnLongTask::Start; - } - }; - + } + + ++I; + return &TSpawnLongTask::Start; + } + }; + Y_UNIT_TEST(SubtaskLong) { - TTestSync testSync; - - TTestEnv env; - - TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<TSpawnLongTask>(&testSync); - - testSync.WaitForAndIncrement(1); - } -} + TTestSync testSync; + + TTestEnv env; + + TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<TSpawnLongTask>(&testSync); + + testSync.WaitForAndIncrement(1); + } +} diff --git a/library/cpp/messagebus/rain_check/core/task.cpp b/library/cpp/messagebus/rain_check/core/task.cpp index d20ae30402..a098437d53 100644 --- a/library/cpp/messagebus/rain_check/core/task.cpp +++ b/library/cpp/messagebus/rain_check/core/task.cpp @@ -1,216 +1,216 @@ #include "rain_check.h" - + #include <library/cpp/messagebus/actor/temp_tls_vector.h> - + #include <util/system/type_name.h> #include <util/system/tls.h> - -using namespace NRainCheck; -using namespace NRainCheck::NPrivate; - -using namespace NActor; - -namespace { + +using namespace NRainCheck; +using namespace NRainCheck::NPrivate; + +using namespace NActor; + +namespace { Y_POD_STATIC_THREAD(TTaskRunnerBase*) ThreadCurrentTask; -} - +} + void TNopSubtaskListener::SetDone() { } - -TNopSubtaskListener TNopSubtaskListener::Instance; - -TTaskRunnerBase::TTaskRunnerBase(IEnv* env, ISubtaskListener* parentTask, TAutoPtr<ITaskBase> impl) - : TActor<TTaskRunnerBase>(env->GetExecutor()) - , Impl(impl) - , ParentTask(parentTask) - //, HoldsSelfReference(false) - , Done(false) - , SetDoneCalled(false) -{ -} - -TTaskRunnerBase::~TTaskRunnerBase() { + +TNopSubtaskListener TNopSubtaskListener::Instance; + +TTaskRunnerBase::TTaskRunnerBase(IEnv* env, ISubtaskListener* parentTask, TAutoPtr<ITaskBase> impl) + : TActor<TTaskRunnerBase>(env->GetExecutor()) + , Impl(impl) + , ParentTask(parentTask) + //, HoldsSelfReference(false) + , Done(false) + , SetDoneCalled(false) +{ +} + +TTaskRunnerBase::~TTaskRunnerBase() { Y_ASSERT(Done); -} - -namespace { - struct TRunningInThisThreadGuard { - TTaskRunnerBase* const Task; - TRunningInThisThreadGuard(TTaskRunnerBase* task) - : Task(task) - { +} + +namespace { + struct TRunningInThisThreadGuard { + TTaskRunnerBase* const Task; + TRunningInThisThreadGuard(TTaskRunnerBase* task) + : Task(task) + { Y_ASSERT(!ThreadCurrentTask); - ThreadCurrentTask = task; - } - - ~TRunningInThisThreadGuard() { + ThreadCurrentTask = task; + } + + ~TRunningInThisThreadGuard() { Y_ASSERT(ThreadCurrentTask == Task); ThreadCurrentTask = nullptr; - } - }; -} - + } + }; +} + void NRainCheck::TTaskRunnerBase::Act(NActor::TDefaultTag) { Y_ASSERT(RefCount() > 0); - - TRunningInThisThreadGuard g(this); - - //RetainRef(); - - for (;;) { - TTempTlsVector<TSubtaskCompletion*> temp; - - temp.GetVector()->swap(Pending); - + + TRunningInThisThreadGuard g(this); + + //RetainRef(); + + for (;;) { + TTempTlsVector<TSubtaskCompletion*> temp; + + temp.GetVector()->swap(Pending); + for (auto& pending : *temp.GetVector()) { if (pending->IsComplete()) { pending->FireCompletionCallback(GetImplBase()); - } else { + } else { Pending.push_back(pending); - } - } - - if (!Pending.empty()) { - return; - } - - if (!Done) { - Done = !ReplyReceived(); - } else { - if (Pending.empty()) { - if (!SetDoneCalled) { - ParentTask->SetDone(); - SetDoneCalled = true; - } - //ReleaseRef(); - return; - } - } - } -} - + } + } + + if (!Pending.empty()) { + return; + } + + if (!Done) { + Done = !ReplyReceived(); + } else { + if (Pending.empty()) { + if (!SetDoneCalled) { + ParentTask->SetDone(); + SetDoneCalled = true; + } + //ReleaseRef(); + return; + } + } + } +} + bool TTaskRunnerBase::IsRunningInThisThread() const { - return ThreadCurrentTask == this; -} - + return ThreadCurrentTask == this; +} + TSubtaskCompletion::~TSubtaskCompletion() { - ESubtaskState state = State.Get(); + ESubtaskState state = State.Get(); Y_ASSERT(state == CREATED || state == DONE || state == CANCELED); -} - +} + void TSubtaskCompletion::FireCompletionCallback(ITaskBase* task) { Y_ASSERT(IsComplete()); - - if (!!CompletionFunc) { - TSubtaskCompletionFunc temp = CompletionFunc; - // completion func must be reset before calling it, - // because function may set it back - CompletionFunc = TSubtaskCompletionFunc(); - (task->*(temp.Func))(this); - } -} - + + if (!!CompletionFunc) { + TSubtaskCompletionFunc temp = CompletionFunc; + // completion func must be reset before calling it, + // because function may set it back + CompletionFunc = TSubtaskCompletionFunc(); + (task->*(temp.Func))(this); + } +} + void NRainCheck::TSubtaskCompletion::Cancel() { - for (;;) { - ESubtaskState state = State.Get(); - if (state == CREATED && State.CompareAndSet(CREATED, CANCELED)) { - return; - } - if (state == RUNNING && State.CompareAndSet(RUNNING, CANCEL_REQUESTED)) { - return; - } - if (state == DONE && State.CompareAndSet(DONE, CANCELED)) { - return; - } - if (state == CANCEL_REQUESTED || state == CANCELED) { - return; - } - } -} - + for (;;) { + ESubtaskState state = State.Get(); + if (state == CREATED && State.CompareAndSet(CREATED, CANCELED)) { + return; + } + if (state == RUNNING && State.CompareAndSet(RUNNING, CANCEL_REQUESTED)) { + return; + } + if (state == DONE && State.CompareAndSet(DONE, CANCELED)) { + return; + } + if (state == CANCEL_REQUESTED || state == CANCELED) { + return; + } + } +} + void TSubtaskCompletion::SetRunning(TTaskRunnerBase* parent) { Y_ASSERT(!TaskRunner); Y_ASSERT(!!parent); - - TaskRunner = parent; - - parent->Pending.push_back(this); - - parent->RefV(); - - for (;;) { - ESubtaskState current = State.Get(); - if (current != CREATED && current != DONE) { + + TaskRunner = parent; + + parent->Pending.push_back(this); + + parent->RefV(); + + for (;;) { + ESubtaskState current = State.Get(); + if (current != CREATED && current != DONE) { Y_FAIL("current state should be CREATED or DONE: %s", ToCString(current)); - } - if (State.CompareAndSet(current, RUNNING)) { - return; - } - } -} - + } + if (State.CompareAndSet(current, RUNNING)) { + return; + } + } +} + void TSubtaskCompletion::SetDone() { Y_ASSERT(!!TaskRunner); - TTaskRunnerBase* temp = TaskRunner; + TTaskRunnerBase* temp = TaskRunner; TaskRunner = nullptr; - - for (;;) { - ESubtaskState state = State.Get(); - if (state == RUNNING) { - if (State.CompareAndSet(RUNNING, DONE)) { - break; - } - } else if (state == CANCEL_REQUESTED) { - if (State.CompareAndSet(CANCEL_REQUESTED, CANCELED)) { - break; - } - } else { + + for (;;) { + ESubtaskState state = State.Get(); + if (state == RUNNING) { + if (State.CompareAndSet(RUNNING, DONE)) { + break; + } + } else if (state == CANCEL_REQUESTED) { + if (State.CompareAndSet(CANCEL_REQUESTED, CANCELED)) { + break; + } + } else { Y_FAIL("cannot SetDone: unknown state: %s", ToCString(state)); - } - } - - temp->ScheduleV(); - temp->UnRefV(); -} - -#if 0 -void NRainCheck::TTaskRunnerBase::RetainRef() -{ - if (HoldsSelfReference) { - return; - } - HoldsSelfReference = true; - Ref(); -} - -void NRainCheck::TTaskRunnerBase::ReleaseRef() -{ - if (!HoldsSelfReference) { - return; - } - HoldsSelfReference = false; - DecRef(); -} -#endif - + } + } + + temp->ScheduleV(); + temp->UnRefV(); +} + +#if 0 +void NRainCheck::TTaskRunnerBase::RetainRef() +{ + if (HoldsSelfReference) { + return; + } + HoldsSelfReference = true; + Ref(); +} + +void NRainCheck::TTaskRunnerBase::ReleaseRef() +{ + if (!HoldsSelfReference) { + return; + } + HoldsSelfReference = false; + DecRef(); +} +#endif + void TTaskRunnerBase::AssertInThisThread() const { Y_ASSERT(IsRunningInThisThread()); -} - +} + TTaskRunnerBase* TTaskRunnerBase::CurrentTask() { Y_VERIFY(!!ThreadCurrentTask); - return ThreadCurrentTask; -} - + return ThreadCurrentTask; +} + ITaskBase* TTaskRunnerBase::CurrentTaskImpl() { return CurrentTask()->GetImplBase(); } TString TTaskRunnerBase::GetStatusSingleLine() { return TypeName(*Impl); -} - +} + bool NRainCheck::AreWeInsideTask() { return ThreadCurrentTask != nullptr; } diff --git a/library/cpp/messagebus/rain_check/core/task.h b/library/cpp/messagebus/rain_check/core/task.h index b84e62a1eb..7d8778bcda 100644 --- a/library/cpp/messagebus/rain_check/core/task.h +++ b/library/cpp/messagebus/rain_check/core/task.h @@ -1,5 +1,5 @@ -#pragma once - +#pragma once + #include "fwd.h" #include <library/cpp/messagebus/actor/actor.h> @@ -7,55 +7,55 @@ #include <library/cpp/deprecated/enum_codegen/enum_codegen.h> -#include <util/generic/noncopyable.h> -#include <util/generic/ptr.h> -#include <util/thread/lfstack.h> - -namespace NRainCheck { - struct ISubtaskListener { - virtual void SetDone() = 0; +#include <util/generic/noncopyable.h> +#include <util/generic/ptr.h> +#include <util/thread/lfstack.h> + +namespace NRainCheck { + struct ISubtaskListener { + virtual void SetDone() = 0; virtual ~ISubtaskListener() { } - }; - - struct TNopSubtaskListener: public ISubtaskListener { + }; + + struct TNopSubtaskListener: public ISubtaskListener { void SetDone() override; - - static TNopSubtaskListener Instance; - }; - - class TSubtaskCompletionFunc { - friend class TSubtaskCompletion; - - typedef void (ITaskBase::*TFunc)(TSubtaskCompletion*); - TFunc Func; - - public: - TSubtaskCompletionFunc() + + static TNopSubtaskListener Instance; + }; + + class TSubtaskCompletionFunc { + friend class TSubtaskCompletion; + + typedef void (ITaskBase::*TFunc)(TSubtaskCompletion*); + TFunc Func; + + public: + TSubtaskCompletionFunc() : Func(nullptr) { } - - TSubtaskCompletionFunc(void*) + + TSubtaskCompletionFunc(void*) : Func(nullptr) { } - - template <typename TTask> - TSubtaskCompletionFunc(void (TTask::*func)(TSubtaskCompletion*)) + + template <typename TTask> + TSubtaskCompletionFunc(void (TTask::*func)(TSubtaskCompletion*)) : Func((TFunc)func) - { + { static_assert((std::is_base_of<ITaskBase, TTask>::value), "expect (std::is_base_of<ITaskBase, TTask>::value)"); - } - - bool operator!() const { - return !Func; - } - }; - - template <typename T> - class TTaskFuture; - + } + + bool operator!() const { + return !Func; + } + }; + + template <typename T> + class TTaskFuture; + #define SUBTASK_STATE_MAP(XX) \ XX(CREATED, "Initial") \ XX(RUNNING, "Running") \ @@ -63,33 +63,33 @@ namespace NRainCheck { XX(CANCEL_REQUESTED, "Cancel requested, but still executing") \ XX(CANCELED, "Canceled") \ /**/ - - enum ESubtaskState { - SUBTASK_STATE_MAP(ENUM_VALUE_GEN_NO_VALUE) - }; - - ENUM_TO_STRING(ESubtaskState, SUBTASK_STATE_MAP) - + + enum ESubtaskState { + SUBTASK_STATE_MAP(ENUM_VALUE_GEN_NO_VALUE) + }; + + ENUM_TO_STRING(ESubtaskState, SUBTASK_STATE_MAP) + class TSubtaskCompletion : TNonCopyable, public ISubtaskListener { - friend struct TTaskAccessor; + friend struct TTaskAccessor; - private: - TAtomicBox<ESubtaskState> State; - TTaskRunnerBase* volatile TaskRunner; - TSubtaskCompletionFunc CompletionFunc; + private: + TAtomicBox<ESubtaskState> State; + TTaskRunnerBase* volatile TaskRunner; + TSubtaskCompletionFunc CompletionFunc; - public: + public: TSubtaskCompletion() : State(CREATED) , TaskRunner() { } ~TSubtaskCompletion() override; - - // Either done or cancel requested or cancelled - bool IsComplete() const { - ESubtaskState state = State.Get(); - switch (state) { + + // Either done or cancel requested or cancelled + bool IsComplete() const { + ESubtaskState state = State.Get(); + switch (state) { case RUNNING: return false; case DONE: @@ -102,82 +102,82 @@ namespace NRainCheck { Y_FAIL("not started"); default: Y_FAIL("unknown value: %u", (unsigned)state); - } - } - - void FireCompletionCallback(ITaskBase*); - - void SetCompletionCallback(TSubtaskCompletionFunc func) { - CompletionFunc = func; - } - - // Completed, but not cancelled - bool IsDone() const { - return State.Get() == DONE; - } - - // Request cancel by actor - // Does nothing but marks task cancelled, - // and allows proceeding to next callback - void Cancel(); - - // called by service provider implementations - // must not be called by actor - void SetRunning(TTaskRunnerBase* parent); + } + } + + void FireCompletionCallback(ITaskBase*); + + void SetCompletionCallback(TSubtaskCompletionFunc func) { + CompletionFunc = func; + } + + // Completed, but not cancelled + bool IsDone() const { + return State.Get() == DONE; + } + + // Request cancel by actor + // Does nothing but marks task cancelled, + // and allows proceeding to next callback + void Cancel(); + + // called by service provider implementations + // must not be called by actor + void SetRunning(TTaskRunnerBase* parent); void SetDone() override; - }; - - // See ISimpleTask, ICoroTask + }; + + // See ISimpleTask, ICoroTask class TTaskRunnerBase: public TAtomicRefCount<TTaskRunnerBase>, public NActor::TActor<TTaskRunnerBase> { - friend class NActor::TActor<TTaskRunnerBase>; - friend class TContinueFunc; - friend struct TTaskAccessor; - friend class TSubtaskCompletion; - - private: - THolder<ITaskBase> Impl; - - ISubtaskListener* const ParentTask; - // While task is running, it holds extra reference to self. - //bool HoldsSelfReference; - bool Done; - bool SetDoneCalled; - - // Subtasks currently executed. + friend class NActor::TActor<TTaskRunnerBase>; + friend class TContinueFunc; + friend struct TTaskAccessor; + friend class TSubtaskCompletion; + + private: + THolder<ITaskBase> Impl; + + ISubtaskListener* const ParentTask; + // While task is running, it holds extra reference to self. + //bool HoldsSelfReference; + bool Done; + bool SetDoneCalled; + + // Subtasks currently executed. TVector<TSubtaskCompletion*> Pending; - - void Act(NActor::TDefaultTag); - - public: - // Construct task. Task is not automatically started. - TTaskRunnerBase(IEnv*, ISubtaskListener* parent, TAutoPtr<ITaskBase> impl); + + void Act(NActor::TDefaultTag); + + public: + // Construct task. Task is not automatically started. + TTaskRunnerBase(IEnv*, ISubtaskListener* parent, TAutoPtr<ITaskBase> impl); ~TTaskRunnerBase() override; - - bool IsRunningInThisThread() const; - void AssertInThisThread() const; - static TTaskRunnerBase* CurrentTask(); + + bool IsRunningInThisThread() const; + void AssertInThisThread() const; + static TTaskRunnerBase* CurrentTask(); static ITaskBase* CurrentTaskImpl(); - + TString GetStatusSingleLine(); - - protected: - //void RetainRef(); - //void ReleaseRef(); + + protected: + //void RetainRef(); + //void ReleaseRef(); ITaskBase* GetImplBase() { return Impl.Get(); } - - private: - // true if need to call again - virtual bool ReplyReceived() = 0; - }; - - class ITaskBase { - public: + + private: + // true if need to call again + virtual bool ReplyReceived() = 0; + }; + + class ITaskBase { + public: virtual ~ITaskBase() { } - }; - + }; + // Check that current method executed inside some task. bool AreWeInsideTask(); diff --git a/library/cpp/messagebus/rain_check/core/track.cpp b/library/cpp/messagebus/rain_check/core/track.cpp index cc3747b9f6..092a51a214 100644 --- a/library/cpp/messagebus/rain_check/core/track.cpp +++ b/library/cpp/messagebus/rain_check/core/track.cpp @@ -1,66 +1,66 @@ -#include "track.h" - -using namespace NRainCheck; -using namespace NRainCheck::NPrivate; - +#include "track.h" + +using namespace NRainCheck; +using namespace NRainCheck::NPrivate; + void TTaskTrackerReceipt::SetDone() { - TaskTracker->GetQueue<TTaskTrackerReceipt*>()->EnqueueAndSchedule(this); -} - + TaskTracker->GetQueue<TTaskTrackerReceipt*>()->EnqueueAndSchedule(this); +} + TString TTaskTrackerReceipt::GetStatusSingleLine() { - return Task->GetStatusSingleLine(); -} - + return Task->GetStatusSingleLine(); +} + TTaskTracker::TTaskTracker(NActor::TExecutor* executor) : NActor::TActor<TTaskTracker>(executor) -{ -} - +{ +} + TTaskTracker::~TTaskTracker() { Y_ASSERT(Tasks.Empty()); -} - -void TTaskTracker::Shutdown() { - ShutdownFlag.Set(true); - Schedule(); - ShutdownEvent.WaitI(); -} - -void TTaskTracker::ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, ITaskFactory* taskFactory) { - THolder<ITaskFactory> holder(taskFactory); - - THolder<TTaskTrackerReceipt> receipt(new TTaskTrackerReceipt(this)); - receipt->Task = taskFactory->NewTask(receipt.Get()); - - Tasks.PushBack(receipt.Release()); -} - -void TTaskTracker::ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, TTaskTrackerReceipt* receipt) { +} + +void TTaskTracker::Shutdown() { + ShutdownFlag.Set(true); + Schedule(); + ShutdownEvent.WaitI(); +} + +void TTaskTracker::ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, ITaskFactory* taskFactory) { + THolder<ITaskFactory> holder(taskFactory); + + THolder<TTaskTrackerReceipt> receipt(new TTaskTrackerReceipt(this)); + receipt->Task = taskFactory->NewTask(receipt.Get()); + + Tasks.PushBack(receipt.Release()); +} + +void TTaskTracker::ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, TTaskTrackerReceipt* receipt) { Y_ASSERT(!receipt->Empty()); - receipt->Unlink(); - delete receipt; -} - -void TTaskTracker::ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, TAsyncResult<TTaskTrackerStatus>* status) { - TTaskTrackerStatus s; - s.Size = Tasks.Size(); - status->SetResult(s); -} - + receipt->Unlink(); + delete receipt; +} + +void TTaskTracker::ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, TAsyncResult<TTaskTrackerStatus>* status) { + TTaskTrackerStatus s; + s.Size = Tasks.Size(); + status->SetResult(s); +} + void TTaskTracker::Act(NActor::TDefaultTag) { - GetQueue<TAsyncResult<TTaskTrackerStatus>*>()->DequeueAll(); - GetQueue<ITaskFactory*>()->DequeueAll(); - GetQueue<TTaskTrackerReceipt*>()->DequeueAll(); - - if (ShutdownFlag.Get()) { - if (Tasks.Empty()) { - ShutdownEvent.Signal(); - } - } -} - -ui32 TTaskTracker::Size() { - TAsyncResult<TTaskTrackerStatus> r; - GetQueue<TAsyncResult<TTaskTrackerStatus>*>()->EnqueueAndSchedule(&r); - return r.GetResult().Size; -} + GetQueue<TAsyncResult<TTaskTrackerStatus>*>()->DequeueAll(); + GetQueue<ITaskFactory*>()->DequeueAll(); + GetQueue<TTaskTrackerReceipt*>()->DequeueAll(); + + if (ShutdownFlag.Get()) { + if (Tasks.Empty()) { + ShutdownEvent.Signal(); + } + } +} + +ui32 TTaskTracker::Size() { + TAsyncResult<TTaskTrackerStatus> r; + GetQueue<TAsyncResult<TTaskTrackerStatus>*>()->EnqueueAndSchedule(&r); + return r.GetResult().Size; +} diff --git a/library/cpp/messagebus/rain_check/core/track.h b/library/cpp/messagebus/rain_check/core/track.h index a7f3d099f0..d387de7574 100644 --- a/library/cpp/messagebus/rain_check/core/track.h +++ b/library/cpp/messagebus/rain_check/core/track.h @@ -1,97 +1,97 @@ -#pragma once - +#pragma once + #include "spawn.h" #include "task.h" - + #include <library/cpp/messagebus/async_result.h> #include <library/cpp/messagebus/actor/queue_in_actor.h> #include <library/cpp/messagebus/misc/atomic_box.h> - + #include <util/generic/intrlist.h> #include <util/system/event.h> -namespace NRainCheck { - class TTaskTracker; - - namespace NPrivate { - struct ITaskFactory { - virtual TIntrusivePtr<TTaskRunnerBase> NewTask(ISubtaskListener*) = 0; +namespace NRainCheck { + class TTaskTracker; + + namespace NPrivate { + struct ITaskFactory { + virtual TIntrusivePtr<TTaskRunnerBase> NewTask(ISubtaskListener*) = 0; virtual ~ITaskFactory() { } - }; - - struct TTaskTrackerReceipt: public ISubtaskListener, public TIntrusiveListItem<TTaskTrackerReceipt> { - TTaskTracker* const TaskTracker; - TIntrusivePtr<TTaskRunnerBase> Task; - + }; + + struct TTaskTrackerReceipt: public ISubtaskListener, public TIntrusiveListItem<TTaskTrackerReceipt> { + TTaskTracker* const TaskTracker; + TIntrusivePtr<TTaskRunnerBase> Task; + TTaskTrackerReceipt(TTaskTracker* taskTracker) : TaskTracker(taskTracker) { } - + void SetDone() override; - + TString GetStatusSingleLine(); - }; - - struct TTaskTrackerStatus { - ui32 Size; - }; - - } - - class TTaskTracker + }; + + struct TTaskTrackerStatus { + ui32 Size; + }; + + } + + class TTaskTracker : public TAtomicRefCount<TTaskTracker>, public NActor::TActor<TTaskTracker>, public NActor::TQueueInActor<TTaskTracker, NPrivate::ITaskFactory*>, public NActor::TQueueInActor<TTaskTracker, NPrivate::TTaskTrackerReceipt*>, public NActor::TQueueInActor<TTaskTracker, TAsyncResult<NPrivate::TTaskTrackerStatus>*> { - friend struct NPrivate::TTaskTrackerReceipt; - - private: - TAtomicBox<bool> ShutdownFlag; + friend struct NPrivate::TTaskTrackerReceipt; + + private: + TAtomicBox<bool> ShutdownFlag; TSystemEvent ShutdownEvent; - - TIntrusiveList<NPrivate::TTaskTrackerReceipt> Tasks; - - template <typename TItem> - NActor::TQueueInActor<TTaskTracker, TItem>* GetQueue() { - return this; - } - - public: - TTaskTracker(NActor::TExecutor* executor); + + TIntrusiveList<NPrivate::TTaskTrackerReceipt> Tasks; + + template <typename TItem> + NActor::TQueueInActor<TTaskTracker, TItem>* GetQueue() { + return this; + } + + public: + TTaskTracker(NActor::TExecutor* executor); ~TTaskTracker() override; - - void Shutdown(); - - void ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, NPrivate::ITaskFactory*); - void ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, NPrivate::TTaskTrackerReceipt*); - void ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, TAsyncResult<NPrivate::TTaskTrackerStatus>*); - - void Act(NActor::TDefaultTag); - - template <typename TTask, typename TEnv, typename TParam> - void Spawn(TEnv* env, TParam param) { - struct TTaskFactory: public NPrivate::ITaskFactory { - TEnv* const Env; - TParam Param; - + + void Shutdown(); + + void ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, NPrivate::ITaskFactory*); + void ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, NPrivate::TTaskTrackerReceipt*); + void ProcessItem(NActor::TDefaultTag, NActor::TDefaultTag, TAsyncResult<NPrivate::TTaskTrackerStatus>*); + + void Act(NActor::TDefaultTag); + + template <typename TTask, typename TEnv, typename TParam> + void Spawn(TEnv* env, TParam param) { + struct TTaskFactory: public NPrivate::ITaskFactory { + TEnv* const Env; + TParam Param; + TTaskFactory(TEnv* env, TParam param) : Env(env) , Param(param) { } - + TIntrusivePtr<TTaskRunnerBase> NewTask(ISubtaskListener* subtaskListener) override { - return NRainCheck::SpawnTask<TTask>(Env, Param, subtaskListener).Get(); - } - }; - - GetQueue<NPrivate::ITaskFactory*>()->EnqueueAndSchedule(new TTaskFactory(env, param)); - } - - ui32 Size(); - }; - -} + return NRainCheck::SpawnTask<TTask>(Env, Param, subtaskListener).Get(); + } + }; + + GetQueue<NPrivate::ITaskFactory*>()->EnqueueAndSchedule(new TTaskFactory(env, param)); + } + + ui32 Size(); + }; + +} diff --git a/library/cpp/messagebus/rain_check/core/track_ut.cpp b/library/cpp/messagebus/rain_check/core/track_ut.cpp index f2ac90fa3c..05f7de1319 100644 --- a/library/cpp/messagebus/rain_check/core/track_ut.cpp +++ b/library/cpp/messagebus/rain_check/core/track_ut.cpp @@ -1,45 +1,45 @@ #include <library/cpp/testing/unittest/registar.h> - + #include "track.h" #include <library/cpp/messagebus/rain_check/test/helper/misc.h> #include <library/cpp/messagebus/rain_check/test/ut/test.h> - -using namespace NRainCheck; - + +using namespace NRainCheck; + Y_UNIT_TEST_SUITE(TaskTracker) { - struct TTaskForTracker: public ISimpleTask { - TTestSync* const TestSync; - + struct TTaskForTracker: public ISimpleTask { + TTestSync* const TestSync; + TTaskForTracker(TTestEnv*, TTestSync* testSync) : TestSync(testSync) { } - + TContinueFunc Start() override { - TestSync->WaitForAndIncrement(0); - TestSync->WaitForAndIncrement(2); + TestSync->WaitForAndIncrement(0); + TestSync->WaitForAndIncrement(2); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(Simple) { - TTestEnv env; - - TIntrusivePtr<TTaskTracker> tracker(new TTaskTracker(env.GetExecutor())); - - TTestSync testSync; - - tracker->Spawn<TTaskForTracker>(&env, &testSync); - - testSync.WaitFor(1); - + TTestEnv env; + + TIntrusivePtr<TTaskTracker> tracker(new TTaskTracker(env.GetExecutor())); + + TTestSync testSync; + + tracker->Spawn<TTaskForTracker>(&env, &testSync); + + testSync.WaitFor(1); + UNIT_ASSERT_VALUES_EQUAL(1u, tracker->Size()); - - testSync.CheckAndIncrement(1); - - testSync.WaitForAndIncrement(3); - - tracker->Shutdown(); - } -} + + testSync.CheckAndIncrement(1); + + testSync.WaitForAndIncrement(3); + + tracker->Shutdown(); + } +} diff --git a/library/cpp/messagebus/rain_check/core/ya.make b/library/cpp/messagebus/rain_check/core/ya.make index 497e452729..c6fb5640d4 100644 --- a/library/cpp/messagebus/rain_check/core/ya.make +++ b/library/cpp/messagebus/rain_check/core/ya.make @@ -1,25 +1,25 @@ -LIBRARY() - +LIBRARY() + OWNER(g:messagebus) - -PEERDIR( + +PEERDIR( library/cpp/coroutine/engine library/cpp/deprecated/enum_codegen library/cpp/messagebus library/cpp/messagebus/actor library/cpp/messagebus/scheduler -) - -SRCS( - coro.cpp - coro_stack.cpp - env.cpp - rain_check.cpp - simple.cpp - sleep.cpp - spawn.cpp - task.cpp - track.cpp -) - -END() +) + +SRCS( + coro.cpp + coro_stack.cpp + env.cpp + rain_check.cpp + simple.cpp + sleep.cpp + spawn.cpp + task.cpp + track.cpp +) + +END() diff --git a/library/cpp/messagebus/rain_check/http/client_ut.cpp b/library/cpp/messagebus/rain_check/http/client_ut.cpp index c6e4a151bd..1628114391 100644 --- a/library/cpp/messagebus/rain_check/http/client_ut.cpp +++ b/library/cpp/messagebus/rain_check/http/client_ut.cpp @@ -25,7 +25,7 @@ #include <utility> using namespace NRainCheck; -using namespace NBus::NTest; +using namespace NBus::NTest; namespace { class THttpClientEnv: public TTestEnvTemplate<THttpClientEnv> { @@ -145,11 +145,11 @@ Y_UNIT_TEST_SUITE(RainCheckHttpClient) { static const TIpPort SERVER_PORT = 4000; Y_UNIT_TEST(Simple) { - // TODO: randomize port - if (!IsFixedPortTestAllowed()) { - return; - } - + // TODO: randomize port + if (!IsFixedPortTestAllowed()) { + return; + } + TSimpleServer server; NNeh::IServicesRef runner = RunServer(SERVER_PORT, server); diff --git a/library/cpp/messagebus/rain_check/messagebus/messagebus_client.cpp b/library/cpp/messagebus/rain_check/messagebus/messagebus_client.cpp index 13d3132fb7..daac8d9a99 100644 --- a/library/cpp/messagebus/rain_check/messagebus/messagebus_client.cpp +++ b/library/cpp/messagebus/rain_check/messagebus/messagebus_client.cpp @@ -1,98 +1,98 @@ -#include "messagebus_client.h" - -using namespace NRainCheck; -using namespace NBus; - -TBusClientService::TBusClientService( +#include "messagebus_client.h" + +using namespace NRainCheck; +using namespace NBus; + +TBusClientService::TBusClientService( const NBus::TBusSessionConfig& config, NBus::TBusProtocol* proto, NBus::TBusMessageQueue* queue) { - Session = queue->CreateSource(proto, this, config); -} - + Session = queue->CreateSource(proto, this, config); +} + TBusClientService::~TBusClientService() { - Session->Shutdown(); -} - + Session->Shutdown(); +} + void TBusClientService::SendCommon(NBus::TBusMessage* message, const NBus::TNetAddr&, TBusFuture* future) { - TTaskRunnerBase* current = TTaskRunnerBase::CurrentTask(); - - future->SetRunning(current); - - future->Task = current; - - // after this statement message is owned by both messagebus and future - future->Request.Reset(message); - - // TODO: allow cookie in messagebus - message->Data = future; -} - -void TBusClientService::ProcessResultCommon(NBus::TBusMessageAutoPtr message, + TTaskRunnerBase* current = TTaskRunnerBase::CurrentTask(); + + future->SetRunning(current); + + future->Task = current; + + // after this statement message is owned by both messagebus and future + future->Request.Reset(message); + + // TODO: allow cookie in messagebus + message->Data = future; +} + +void TBusClientService::ProcessResultCommon(NBus::TBusMessageAutoPtr message, const NBus::TNetAddr&, TBusFuture* future, NBus::EMessageStatus status) { Y_UNUSED(message.Release()); - - if (status == NBus::MESSAGE_OK) { - return; - } - + + if (status == NBus::MESSAGE_OK) { + return; + } + future->SetDoneAndSchedule(status, nullptr); -} - -void TBusClientService::SendOneWay( +} + +void TBusClientService::SendOneWay( NBus::TBusMessageAutoPtr message, const NBus::TNetAddr& addr, TBusFuture* future) { - SendCommon(message.Get(), addr, future); - - EMessageStatus ok = Session->SendMessageOneWay(message.Get(), &addr, false); - ProcessResultCommon(message, addr, future, ok); -} - + SendCommon(message.Get(), addr, future); + + EMessageStatus ok = Session->SendMessageOneWay(message.Get(), &addr, false); + ProcessResultCommon(message, addr, future, ok); +} + NBus::TBusClientSessionPtr TBusClientService::GetSessionForMonitoring() const { return Session; } -void TBusClientService::Send( +void TBusClientService::Send( TBusMessageAutoPtr message, const TNetAddr& addr, TBusFuture* future) { - SendCommon(message.Get(), addr, future); - - EMessageStatus ok = Session->SendMessage(message.Get(), &addr, false); - ProcessResultCommon(message, addr, future, ok); -} - -void TBusClientService::OnReply( + SendCommon(message.Get(), addr, future); + + EMessageStatus ok = Session->SendMessage(message.Get(), &addr, false); + ProcessResultCommon(message, addr, future, ok); +} + +void TBusClientService::OnReply( TAutoPtr<TBusMessage> request, TAutoPtr<TBusMessage> response) { TBusFuture* future = (TBusFuture*)request->Data; Y_ASSERT(future->Request.Get() == request.Get()); Y_UNUSED(request.Release()); - future->SetDoneAndSchedule(MESSAGE_OK, response); -} - -void NRainCheck::TBusClientService::OnMessageSentOneWay( + future->SetDoneAndSchedule(MESSAGE_OK, response); +} + +void NRainCheck::TBusClientService::OnMessageSentOneWay( TAutoPtr<NBus::TBusMessage> request) { TBusFuture* future = (TBusFuture*)request->Data; Y_ASSERT(future->Request.Get() == request.Get()); Y_UNUSED(request.Release()); future->SetDoneAndSchedule(MESSAGE_OK, nullptr); -} - -void TBusClientService::OnError( +} + +void TBusClientService::OnError( TAutoPtr<TBusMessage> message, NBus::EMessageStatus status) { if (message->Data == nullptr) { - return; - } - + return; + } + TBusFuture* future = (TBusFuture*)message->Data; Y_ASSERT(future->Request.Get() == message.Get()); Y_UNUSED(message.Release()); future->SetDoneAndSchedule(status, nullptr); -} - +} + void TBusFuture::SetDoneAndSchedule(EMessageStatus status, TAutoPtr<TBusMessage> response) { - Status = status; - Response.Reset(response.Release()); - SetDone(); -} + Status = status; + Response.Reset(response.Release()); + SetDone(); +} diff --git a/library/cpp/messagebus/rain_check/messagebus/messagebus_client.h b/library/cpp/messagebus/rain_check/messagebus/messagebus_client.h index 8bcc03b8d9..0a291cdea6 100644 --- a/library/cpp/messagebus/rain_check/messagebus/messagebus_client.h +++ b/library/cpp/messagebus/rain_check/messagebus/messagebus_client.h @@ -1,67 +1,67 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/rain_check/core/task.h> #include <library/cpp/messagebus/ybus.h> - -namespace NRainCheck { - class TBusFuture: public TSubtaskCompletion { - friend class TBusClientService; - - private: - THolder<NBus::TBusMessage> Request; - THolder<NBus::TBusMessage> Response; - NBus::EMessageStatus Status; - - private: - TTaskRunnerBase* Task; - - void SetDoneAndSchedule(NBus::EMessageStatus, TAutoPtr<NBus::TBusMessage>); - - public: - // TODO: add MESSAGE_UNDEFINED + +namespace NRainCheck { + class TBusFuture: public TSubtaskCompletion { + friend class TBusClientService; + + private: + THolder<NBus::TBusMessage> Request; + THolder<NBus::TBusMessage> Response; + NBus::EMessageStatus Status; + + private: + TTaskRunnerBase* Task; + + void SetDoneAndSchedule(NBus::EMessageStatus, TAutoPtr<NBus::TBusMessage>); + + public: + // TODO: add MESSAGE_UNDEFINED TBusFuture() : Status(NBus::MESSAGE_DONT_ASK) , Task(nullptr) { } - - NBus::TBusMessage* GetRequest() const { - return Request.Get(); - } - - NBus::TBusMessage* GetResponse() const { + + NBus::TBusMessage* GetRequest() const { + return Request.Get(); + } + + NBus::TBusMessage* GetResponse() const { Y_ASSERT(IsDone()); - return Response.Get(); - } - - NBus::EMessageStatus GetStatus() const { + return Response.Get(); + } + + NBus::EMessageStatus GetStatus() const { Y_ASSERT(IsDone()); - return Status; - } - }; - - class TBusClientService: private NBus::IBusClientHandler { - private: - NBus::TBusClientSessionPtr Session; - - public: - TBusClientService(const NBus::TBusSessionConfig&, NBus::TBusProtocol*, NBus::TBusMessageQueue*); + return Status; + } + }; + + class TBusClientService: private NBus::IBusClientHandler { + private: + NBus::TBusClientSessionPtr Session; + + public: + TBusClientService(const NBus::TBusSessionConfig&, NBus::TBusProtocol*, NBus::TBusMessageQueue*); ~TBusClientService() override; - - void Send(NBus::TBusMessageAutoPtr, const NBus::TNetAddr&, TBusFuture* future); - void SendOneWay(NBus::TBusMessageAutoPtr, const NBus::TNetAddr&, TBusFuture* future); - + + void Send(NBus::TBusMessageAutoPtr, const NBus::TNetAddr&, TBusFuture* future); + void SendOneWay(NBus::TBusMessageAutoPtr, const NBus::TNetAddr&, TBusFuture* future); + // Use it only for monitoring NBus::TBusClientSessionPtr GetSessionForMonitoring() const; - private: - void SendCommon(NBus::TBusMessage*, const NBus::TNetAddr&, TBusFuture* future); - void ProcessResultCommon(NBus::TBusMessageAutoPtr, const NBus::TNetAddr&, TBusFuture* future, NBus::EMessageStatus); - + private: + void SendCommon(NBus::TBusMessage*, const NBus::TNetAddr&, TBusFuture* future); + void ProcessResultCommon(NBus::TBusMessageAutoPtr, const NBus::TNetAddr&, TBusFuture* future, NBus::EMessageStatus); + void OnReply(TAutoPtr<NBus::TBusMessage> pMessage, TAutoPtr<NBus::TBusMessage> pReply) override; void OnError(TAutoPtr<NBus::TBusMessage> pMessage, NBus::EMessageStatus status) override; void OnMessageSentOneWay(TAutoPtr<NBus::TBusMessage>) override; - }; - -} + }; + +} diff --git a/library/cpp/messagebus/rain_check/messagebus/messagebus_client_ut.cpp b/library/cpp/messagebus/rain_check/messagebus/messagebus_client_ut.cpp index 4571f6f74a..1b3618558b 100644 --- a/library/cpp/messagebus/rain_check/messagebus/messagebus_client_ut.cpp +++ b/library/cpp/messagebus/rain_check/messagebus/messagebus_client_ut.cpp @@ -1,146 +1,146 @@ #include <library/cpp/testing/unittest/registar.h> - + #include "messagebus_client.h" #include <library/cpp/messagebus/rain_check/test/ut/test.h> #include <library/cpp/messagebus/test/helper/example.h> #include <library/cpp/messagebus/test/helper/object_count_check.h> - + #include <util/generic/cast.h> - -using namespace NBus; -using namespace NBus::NTest; -using namespace NRainCheck; - -struct TMessageBusClientEnv: public TTestEnvTemplate<TMessageBusClientEnv> { - // TODO: use same thread pool - TBusMessageQueuePtr Queue; - TExampleProtocol Proto; - TBusClientService BusClientService; - - static TBusQueueConfig QueueConfig() { - TBusQueueConfig r; - r.NumWorkers = 4; - return r; - } - - TMessageBusClientEnv() - : Queue(CreateMessageQueue(GetExecutor())) - , BusClientService(TBusSessionConfig(), &Proto, Queue.Get()) + +using namespace NBus; +using namespace NBus::NTest; +using namespace NRainCheck; + +struct TMessageBusClientEnv: public TTestEnvTemplate<TMessageBusClientEnv> { + // TODO: use same thread pool + TBusMessageQueuePtr Queue; + TExampleProtocol Proto; + TBusClientService BusClientService; + + static TBusQueueConfig QueueConfig() { + TBusQueueConfig r; + r.NumWorkers = 4; + return r; + } + + TMessageBusClientEnv() + : Queue(CreateMessageQueue(GetExecutor())) + , BusClientService(TBusSessionConfig(), &Proto, Queue.Get()) { } -}; - +}; + Y_UNIT_TEST_SUITE(RainCheckMessageBusClient) { - struct TSimpleTask: public ISimpleTask { - TMessageBusClientEnv* const Env; - - const unsigned ServerPort; - - TSimpleTask(TMessageBusClientEnv* env, unsigned serverPort) - : Env(env) - , ServerPort(serverPort) - { - } - + struct TSimpleTask: public ISimpleTask { + TMessageBusClientEnv* const Env; + + const unsigned ServerPort; + + TSimpleTask(TMessageBusClientEnv* env, unsigned serverPort) + : Env(env) + , ServerPort(serverPort) + { + } + TVector<TSimpleSharedPtr<TBusFuture>> Requests; - + TContinueFunc Start() override { - for (unsigned i = 0; i < 3; ++i) { - Requests.push_back(new TBusFuture); - TNetAddr addr("localhost", ServerPort); - Env->BusClientService.Send(new TExampleRequest(&Env->Proto.RequestCount), addr, Requests[i].Get()); - } - - return TContinueFunc(&TSimpleTask::GotReplies); - } - - TContinueFunc GotReplies() { - for (unsigned i = 0; i < Requests.size(); ++i) { + for (unsigned i = 0; i < 3; ++i) { + Requests.push_back(new TBusFuture); + TNetAddr addr("localhost", ServerPort); + Env->BusClientService.Send(new TExampleRequest(&Env->Proto.RequestCount), addr, Requests[i].Get()); + } + + return TContinueFunc(&TSimpleTask::GotReplies); + } + + TContinueFunc GotReplies() { + for (unsigned i = 0; i < Requests.size(); ++i) { Y_VERIFY(Requests[i]->GetStatus() == MESSAGE_OK); - VerifyDynamicCast<TExampleResponse*>(Requests[i]->GetResponse()); - } - Env->TestSync.CheckAndIncrement(0); + VerifyDynamicCast<TExampleResponse*>(Requests[i]->GetResponse()); + } + Env->TestSync.CheckAndIncrement(0); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(Simple) { - TObjectCountCheck objectCountCheck; - - TExampleServer server; - - TMessageBusClientEnv env; - - TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<TSimpleTask>(server.GetActualListenPort()); - - env.TestSync.WaitForAndIncrement(1); - } - - struct TOneWayServer: public NBus::IBusServerHandler { - TTestSync* const TestSync; - TExampleProtocol Proto; - NBus::TBusMessageQueuePtr Queue; - NBus::TBusServerSessionPtr Session; - - TOneWayServer(TTestSync* testSync) - : TestSync(testSync) - { - Queue = CreateMessageQueue(); - Session = Queue->CreateDestination(&Proto, this, NBus::TBusSessionConfig()); - } - + TObjectCountCheck objectCountCheck; + + TExampleServer server; + + TMessageBusClientEnv env; + + TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<TSimpleTask>(server.GetActualListenPort()); + + env.TestSync.WaitForAndIncrement(1); + } + + struct TOneWayServer: public NBus::IBusServerHandler { + TTestSync* const TestSync; + TExampleProtocol Proto; + NBus::TBusMessageQueuePtr Queue; + NBus::TBusServerSessionPtr Session; + + TOneWayServer(TTestSync* testSync) + : TestSync(testSync) + { + Queue = CreateMessageQueue(); + Session = Queue->CreateDestination(&Proto, this, NBus::TBusSessionConfig()); + } + void OnMessage(NBus::TOnMessageContext& context) override { - TestSync->CheckAndIncrement(1); - context.ForgetRequest(); - } - }; - - struct TOneWayTask: public ISimpleTask { - TMessageBusClientEnv* const Env; - - const unsigned ServerPort; - - TOneWayTask(TMessageBusClientEnv* env, unsigned serverPort) - : Env(env) - , ServerPort(serverPort) - { - } - + TestSync->CheckAndIncrement(1); + context.ForgetRequest(); + } + }; + + struct TOneWayTask: public ISimpleTask { + TMessageBusClientEnv* const Env; + + const unsigned ServerPort; + + TOneWayTask(TMessageBusClientEnv* env, unsigned serverPort) + : Env(env) + , ServerPort(serverPort) + { + } + TVector<TSimpleSharedPtr<TBusFuture>> Requests; - + TContinueFunc Start() override { - Env->TestSync.CheckAndIncrement(0); - - for (unsigned i = 0; i < 1; ++i) { - Requests.push_back(new TBusFuture); - TNetAddr addr("localhost", ServerPort); - Env->BusClientService.SendOneWay(new TExampleRequest(&Env->Proto.RequestCount), addr, Requests[i].Get()); - } - - return TContinueFunc(&TOneWayTask::GotReplies); - } - - TContinueFunc GotReplies() { - for (unsigned i = 0; i < Requests.size(); ++i) { + Env->TestSync.CheckAndIncrement(0); + + for (unsigned i = 0; i < 1; ++i) { + Requests.push_back(new TBusFuture); + TNetAddr addr("localhost", ServerPort); + Env->BusClientService.SendOneWay(new TExampleRequest(&Env->Proto.RequestCount), addr, Requests[i].Get()); + } + + return TContinueFunc(&TOneWayTask::GotReplies); + } + + TContinueFunc GotReplies() { + for (unsigned i = 0; i < Requests.size(); ++i) { Y_VERIFY(Requests[i]->GetStatus() == MESSAGE_OK); Y_VERIFY(!Requests[i]->GetResponse()); - } - Env->TestSync.WaitForAndIncrement(2); + } + Env->TestSync.WaitForAndIncrement(2); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(OneWay) { - TObjectCountCheck objectCountCheck; - - TMessageBusClientEnv env; - - TOneWayServer server(&env.TestSync); - - TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<TOneWayTask>(server.Session->GetActualListenPort()); - - env.TestSync.WaitForAndIncrement(3); - } -} + TObjectCountCheck objectCountCheck; + + TMessageBusClientEnv env; + + TOneWayServer server(&env.TestSync); + + TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<TOneWayTask>(server.Session->GetActualListenPort()); + + env.TestSync.WaitForAndIncrement(3); + } +} diff --git a/library/cpp/messagebus/rain_check/messagebus/messagebus_server.cpp b/library/cpp/messagebus/rain_check/messagebus/messagebus_server.cpp index 1346ef3243..5d4b13d664 100644 --- a/library/cpp/messagebus/rain_check/messagebus/messagebus_server.cpp +++ b/library/cpp/messagebus/rain_check/messagebus/messagebus_server.cpp @@ -1,17 +1,17 @@ #include "messagebus_server.h" #include <library/cpp/messagebus/rain_check/core/spawn.h> - -using namespace NRainCheck; - -TBusTaskStarter::TBusTaskStarter(TAutoPtr<ITaskFactory> taskFactory) - : TaskFactory(taskFactory) -{ -} - + +using namespace NRainCheck; + +TBusTaskStarter::TBusTaskStarter(TAutoPtr<ITaskFactory> taskFactory) + : TaskFactory(taskFactory) +{ +} + void TBusTaskStarter::OnMessage(NBus::TOnMessageContext& onMessage) { - TaskFactory->NewTask(onMessage); -} - + TaskFactory->NewTask(onMessage); +} + TBusTaskStarter::~TBusTaskStarter() { -} +} diff --git a/library/cpp/messagebus/rain_check/messagebus/messagebus_server.h b/library/cpp/messagebus/rain_check/messagebus/messagebus_server.h index 28d016599a..1334f05fe4 100644 --- a/library/cpp/messagebus/rain_check/messagebus/messagebus_server.h +++ b/library/cpp/messagebus/rain_check/messagebus/messagebus_server.h @@ -1,46 +1,46 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/rain_check/core/spawn.h> #include <library/cpp/messagebus/rain_check/core/task.h> - + #include <library/cpp/messagebus/ybus.h> - + #include <util/system/yassert.h> - -namespace NRainCheck { - class TBusTaskStarter: public NBus::IBusServerHandler { - private: - struct ITaskFactory { - virtual void NewTask(NBus::TOnMessageContext&) = 0; + +namespace NRainCheck { + class TBusTaskStarter: public NBus::IBusServerHandler { + private: + struct ITaskFactory { + virtual void NewTask(NBus::TOnMessageContext&) = 0; virtual ~ITaskFactory() { } - }; - - THolder<ITaskFactory> TaskFactory; - + }; + + THolder<ITaskFactory> TaskFactory; + void OnMessage(NBus::TOnMessageContext&) override; - public: - TBusTaskStarter(TAutoPtr<ITaskFactory>); + public: + TBusTaskStarter(TAutoPtr<ITaskFactory>); ~TBusTaskStarter() override; - - public: - template <typename TTask, typename TEnv> - static TAutoPtr<TBusTaskStarter> NewStarter(TEnv* env) { - struct TTaskFactory: public ITaskFactory { - TEnv* const Env; - + + public: + template <typename TTask, typename TEnv> + static TAutoPtr<TBusTaskStarter> NewStarter(TEnv* env) { + struct TTaskFactory: public ITaskFactory { + TEnv* const Env; + TTaskFactory(TEnv* env) : Env(env) { } - + void NewTask(NBus::TOnMessageContext& context) override { - SpawnTask<TTask, TEnv, NBus::TOnMessageContext&>(Env, context); - } - }; - - return new TBusTaskStarter(new TTaskFactory(env)); - } - }; -} + SpawnTask<TTask, TEnv, NBus::TOnMessageContext&>(Env, context); + } + }; + + return new TBusTaskStarter(new TTaskFactory(env)); + } + }; +} diff --git a/library/cpp/messagebus/rain_check/messagebus/messagebus_server_ut.cpp b/library/cpp/messagebus/rain_check/messagebus/messagebus_server_ut.cpp index fcb718c3ba..7c11399f1b 100644 --- a/library/cpp/messagebus/rain_check/messagebus/messagebus_server_ut.cpp +++ b/library/cpp/messagebus/rain_check/messagebus/messagebus_server_ut.cpp @@ -1,51 +1,51 @@ #include <library/cpp/testing/unittest/registar.h> - + #include "messagebus_server.h" - + #include <library/cpp/messagebus/rain_check/test/ut/test.h> - + #include <library/cpp/messagebus/test/helper/example.h> - -using namespace NBus; -using namespace NBus::NTest; -using namespace NRainCheck; - -struct TMessageBusServerEnv: public TTestEnvTemplate<TMessageBusServerEnv> { - TExampleProtocol Proto; -}; - + +using namespace NBus; +using namespace NBus::NTest; +using namespace NRainCheck; + +struct TMessageBusServerEnv: public TTestEnvTemplate<TMessageBusServerEnv> { + TExampleProtocol Proto; +}; + Y_UNIT_TEST_SUITE(RainCheckMessageBusServer) { - struct TSimpleServerTask: public ISimpleTask { - private: - TMessageBusServerEnv* const Env; - TOnMessageContext MessageContext; - - public: - TSimpleServerTask(TMessageBusServerEnv* env, TOnMessageContext& messageContext) - : Env(env) - { - MessageContext.Swap(messageContext); - } - + struct TSimpleServerTask: public ISimpleTask { + private: + TMessageBusServerEnv* const Env; + TOnMessageContext MessageContext; + + public: + TSimpleServerTask(TMessageBusServerEnv* env, TOnMessageContext& messageContext) + : Env(env) + { + MessageContext.Swap(messageContext); + } + TContinueFunc Start() override { - MessageContext.SendReplyMove(new TExampleResponse(&Env->Proto.ResponseCount)); + MessageContext.SendReplyMove(new TExampleResponse(&Env->Proto.ResponseCount)); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(Simple) { - TMessageBusServerEnv env; - - THolder<TBusTaskStarter> starter(TBusTaskStarter::NewStarter<TSimpleServerTask>(&env)); - - TBusMessageQueuePtr queue(CreateMessageQueue(env.GetExecutor())); - - TExampleProtocol proto; - - TBusServerSessionPtr session = queue->CreateDestination(&env.Proto, starter.Get(), TBusSessionConfig()); - - TExampleClient client; - - client.SendMessagesWaitReplies(1, TNetAddr("localhost", session->GetActualListenPort())); - } -} + TMessageBusServerEnv env; + + THolder<TBusTaskStarter> starter(TBusTaskStarter::NewStarter<TSimpleServerTask>(&env)); + + TBusMessageQueuePtr queue(CreateMessageQueue(env.GetExecutor())); + + TExampleProtocol proto; + + TBusServerSessionPtr session = queue->CreateDestination(&env.Proto, starter.Get(), TBusSessionConfig()); + + TExampleClient client; + + client.SendMessagesWaitReplies(1, TNetAddr("localhost", session->GetActualListenPort())); + } +} diff --git a/library/cpp/messagebus/rain_check/messagebus/ya.make b/library/cpp/messagebus/rain_check/messagebus/ya.make index d7dc902ad1..defdac9a61 100644 --- a/library/cpp/messagebus/rain_check/messagebus/ya.make +++ b/library/cpp/messagebus/rain_check/messagebus/ya.make @@ -1,15 +1,15 @@ -LIBRARY() - +LIBRARY() + OWNER(g:messagebus) - -PEERDIR( + +PEERDIR( library/cpp/messagebus library/cpp/messagebus/rain_check/core -) - -SRCS( - messagebus_client.cpp - messagebus_server.cpp -) - -END() +) + +SRCS( + messagebus_client.cpp + messagebus_server.cpp +) + +END() diff --git a/library/cpp/messagebus/rain_check/test/helper/misc.cpp b/library/cpp/messagebus/rain_check/test/helper/misc.cpp index 2a75c42744..c0fcb27252 100644 --- a/library/cpp/messagebus/rain_check/test/helper/misc.cpp +++ b/library/cpp/messagebus/rain_check/test/helper/misc.cpp @@ -1,27 +1,27 @@ #include "misc.h" -#include <util/system/yassert.h> - -using namespace NRainCheck; - +#include <util/system/yassert.h> + +using namespace NRainCheck; + void TSpawnNopTasksCoroTask::Run() { Y_VERIFY(Count <= Completion.size()); - for (unsigned i = 0; i < Count; ++i) { - SpawnSubtask<TNopCoroTask>(Env, &Completion[i], ""); - } - - WaitForSubtasks(); -} - + for (unsigned i = 0; i < Count; ++i) { + SpawnSubtask<TNopCoroTask>(Env, &Completion[i], ""); + } + + WaitForSubtasks(); +} + TContinueFunc TSpawnNopTasksSimpleTask::Start() { Y_VERIFY(Count <= Completion.size()); - for (unsigned i = 0; i < Count; ++i) { - SpawnSubtask<TNopSimpleTask>(Env, &Completion[i], ""); - } - - return &TSpawnNopTasksSimpleTask::Join; -} - + for (unsigned i = 0; i < Count; ++i) { + SpawnSubtask<TNopSimpleTask>(Env, &Completion[i], ""); + } + + return &TSpawnNopTasksSimpleTask::Join; +} + TContinueFunc TSpawnNopTasksSimpleTask::Join() { return nullptr; -} +} diff --git a/library/cpp/messagebus/rain_check/test/helper/misc.h b/library/cpp/messagebus/rain_check/test/helper/misc.h index dbcc04778d..9150be4d2f 100644 --- a/library/cpp/messagebus/rain_check/test/helper/misc.h +++ b/library/cpp/messagebus/rain_check/test/helper/misc.h @@ -1,57 +1,57 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/rain_check/core/rain_check.h> - + #include <array> - -namespace NRainCheck { - struct TNopSimpleTask: public ISimpleTask { + +namespace NRainCheck { + struct TNopSimpleTask: public ISimpleTask { TNopSimpleTask(IEnv*, const void*) { } - + TContinueFunc Start() override { return nullptr; - } - }; - - struct TNopCoroTask: public ICoroTask { + } + }; + + struct TNopCoroTask: public ICoroTask { TNopCoroTask(IEnv*, const void*) { } - + void Run() override { } - }; - - struct TSpawnNopTasksCoroTask: public ICoroTask { - IEnv* const Env; - unsigned const Count; - - TSpawnNopTasksCoroTask(IEnv* env, unsigned count) - : Env(env) - , Count(count) + }; + + struct TSpawnNopTasksCoroTask: public ICoroTask { + IEnv* const Env; + unsigned const Count; + + TSpawnNopTasksCoroTask(IEnv* env, unsigned count) + : Env(env) + , Count(count) { } - + std::array<TSubtaskCompletion, 2> Completion; - + void Run() override; - }; - - struct TSpawnNopTasksSimpleTask: public ISimpleTask { - IEnv* const Env; - unsigned const Count; - - TSpawnNopTasksSimpleTask(IEnv* env, unsigned count) - : Env(env) - , Count(count) + }; + + struct TSpawnNopTasksSimpleTask: public ISimpleTask { + IEnv* const Env; + unsigned const Count; + + TSpawnNopTasksSimpleTask(IEnv* env, unsigned count) + : Env(env) + , Count(count) { } - + std::array<TSubtaskCompletion, 2> Completion; - + TContinueFunc Start() override; - - TContinueFunc Join(); - }; - -} + + TContinueFunc Join(); + }; + +} diff --git a/library/cpp/messagebus/rain_check/test/helper/ya.make b/library/cpp/messagebus/rain_check/test/helper/ya.make index 08265167a7..aa9e4e6d81 100644 --- a/library/cpp/messagebus/rain_check/test/helper/ya.make +++ b/library/cpp/messagebus/rain_check/test/helper/ya.make @@ -1,13 +1,13 @@ -LIBRARY(messagebus-rain_check-test-helper) - +LIBRARY(messagebus-rain_check-test-helper) + OWNER(g:messagebus) - + PEERDIR( library/cpp/messagebus/rain_check/core ) -SRCS( - misc.cpp -) - -END() +SRCS( + misc.cpp +) + +END() diff --git a/library/cpp/messagebus/rain_check/test/perftest/perftest.cpp b/library/cpp/messagebus/rain_check/test/perftest/perftest.cpp index d0c6451f47..22edbd8c6b 100644 --- a/library/cpp/messagebus/rain_check/test/perftest/perftest.cpp +++ b/library/cpp/messagebus/rain_check/test/perftest/perftest.cpp @@ -1,154 +1,154 @@ #include <library/cpp/messagebus/rain_check/test/helper/misc.h> - + #include <library/cpp/messagebus/rain_check/core/rain_check.h> - + #include <util/datetime/base.h> #include <array> - -using namespace NRainCheck; - -static const unsigned SUBTASKS = 2; - -struct TRainCheckPerftestEnv: public TSimpleEnvTemplate<TRainCheckPerftestEnv> { - unsigned SubtasksPerTask; - - TRainCheckPerftestEnv() - : TSimpleEnvTemplate<TRainCheckPerftestEnv>(4) - , SubtasksPerTask(1000) + +using namespace NRainCheck; + +static const unsigned SUBTASKS = 2; + +struct TRainCheckPerftestEnv: public TSimpleEnvTemplate<TRainCheckPerftestEnv> { + unsigned SubtasksPerTask; + + TRainCheckPerftestEnv() + : TSimpleEnvTemplate<TRainCheckPerftestEnv>(4) + , SubtasksPerTask(1000) { } -}; - -struct TCoroOuter: public ICoroTask { - TRainCheckPerftestEnv* const Env; - +}; + +struct TCoroOuter: public ICoroTask { + TRainCheckPerftestEnv* const Env; + TCoroOuter(TRainCheckPerftestEnv* env) : Env(env) { } - + void Run() override { - for (;;) { - TInstant start = TInstant::Now(); - - unsigned count = 0; - - unsigned current = 1000; - - do { - for (unsigned i = 0; i < current; ++i) { + for (;;) { + TInstant start = TInstant::Now(); + + unsigned count = 0; + + unsigned current = 1000; + + do { + for (unsigned i = 0; i < current; ++i) { std::array<TSubtaskCompletion, SUBTASKS> completion; - - for (unsigned j = 0; j < SUBTASKS; ++j) { - //SpawnSubtask<TNopSimpleTask>(Env, &completion[j]); - //SpawnSubtask<TSpawnNopTasksCoroTask>(Env, &completion[j], SUBTASKS); - SpawnSubtask<TSpawnNopTasksSimpleTask>(Env, &completion[j], SUBTASKS); - } - - WaitForSubtasks(); - } - - count += current; - current *= 2; - } while (TInstant::Now() - start < TDuration::Seconds(1)); - - TDuration d = TInstant::Now() - start; - unsigned dns = d.NanoSeconds() / count; - Cerr << dns << "ns per spawn/join\n"; - } - } -}; - -struct TSimpleOuter: public ISimpleTask { - TRainCheckPerftestEnv* const Env; - + + for (unsigned j = 0; j < SUBTASKS; ++j) { + //SpawnSubtask<TNopSimpleTask>(Env, &completion[j]); + //SpawnSubtask<TSpawnNopTasksCoroTask>(Env, &completion[j], SUBTASKS); + SpawnSubtask<TSpawnNopTasksSimpleTask>(Env, &completion[j], SUBTASKS); + } + + WaitForSubtasks(); + } + + count += current; + current *= 2; + } while (TInstant::Now() - start < TDuration::Seconds(1)); + + TDuration d = TInstant::Now() - start; + unsigned dns = d.NanoSeconds() / count; + Cerr << dns << "ns per spawn/join\n"; + } + } +}; + +struct TSimpleOuter: public ISimpleTask { + TRainCheckPerftestEnv* const Env; + TSimpleOuter(TRainCheckPerftestEnv* env, const void*) : Env(env) { } - - TInstant StartInstant; - unsigned Count; - unsigned Current; - unsigned I; - + + TInstant StartInstant; + unsigned Count; + unsigned Current; + unsigned I; + TContinueFunc Start() override { - StartInstant = TInstant::Now(); - Count = 0; - Current = 1000; - I = 0; - - return &TSimpleOuter::Spawn; - } - + StartInstant = TInstant::Now(); + Count = 0; + Current = 1000; + I = 0; + + return &TSimpleOuter::Spawn; + } + std::array<TSubtaskCompletion, SUBTASKS> Completion; - - TContinueFunc Spawn() { - for (unsigned j = 0; j < SUBTASKS; ++j) { - //SpawnSubtask<TNopSimpleTask>(Env, &Completion[j]); - //SpawnSubtask<TSpawnNopTasksCoroTask>(Env, &Completion[j], SUBTASKS); - SpawnSubtask<TSpawnNopTasksSimpleTask>(Env, &Completion[j], SUBTASKS); - } - - return &TSimpleOuter::Join; - } - - TContinueFunc Join() { - I += 1; - if (I != Current) { - return &TSimpleOuter::Spawn; - } - - I = 0; - Count += Current; - Current *= 2; - - TDuration d = TInstant::Now() - StartInstant; - if (d < TDuration::Seconds(1)) { - return &TSimpleOuter::Spawn; - } - - unsigned dns = d.NanoSeconds() / Count; - Cerr << dns << "ns per spawn/join\n"; - - return &TSimpleOuter::Start; - } -}; - -struct TReproduceCrashTask: public ISimpleTask { - TRainCheckPerftestEnv* const Env; - + + TContinueFunc Spawn() { + for (unsigned j = 0; j < SUBTASKS; ++j) { + //SpawnSubtask<TNopSimpleTask>(Env, &Completion[j]); + //SpawnSubtask<TSpawnNopTasksCoroTask>(Env, &Completion[j], SUBTASKS); + SpawnSubtask<TSpawnNopTasksSimpleTask>(Env, &Completion[j], SUBTASKS); + } + + return &TSimpleOuter::Join; + } + + TContinueFunc Join() { + I += 1; + if (I != Current) { + return &TSimpleOuter::Spawn; + } + + I = 0; + Count += Current; + Current *= 2; + + TDuration d = TInstant::Now() - StartInstant; + if (d < TDuration::Seconds(1)) { + return &TSimpleOuter::Spawn; + } + + unsigned dns = d.NanoSeconds() / Count; + Cerr << dns << "ns per spawn/join\n"; + + return &TSimpleOuter::Start; + } +}; + +struct TReproduceCrashTask: public ISimpleTask { + TRainCheckPerftestEnv* const Env; + TReproduceCrashTask(TRainCheckPerftestEnv* env) : Env(env) { } - + std::array<TSubtaskCompletion, SUBTASKS> Completion; - + TContinueFunc Start() override { - for (unsigned j = 0; j < 2; ++j) { - //SpawnSubtask<TNopSimpleTask>(Env, &Completion[j]); - SpawnSubtask<TSpawnNopTasksSimpleTask>(Env, &Completion[j], SUBTASKS); - } - - return &TReproduceCrashTask::Start; - } -}; - -int main(int argc, char** argv) { + for (unsigned j = 0; j < 2; ++j) { + //SpawnSubtask<TNopSimpleTask>(Env, &Completion[j]); + SpawnSubtask<TSpawnNopTasksSimpleTask>(Env, &Completion[j], SUBTASKS); + } + + return &TReproduceCrashTask::Start; + } +}; + +int main(int argc, char** argv) { Y_UNUSED(argc); Y_UNUSED(argv); - - TRainCheckPerftestEnv env; - - env.SpawnTask<TSimpleOuter>(""); - //env.SpawnTask<TCoroOuter>(); - //env.SpawnTask<TReproduceCrashTask>(); - - for (;;) { - Sleep(TDuration::Hours(1)); - } - - return 0; -} + + TRainCheckPerftestEnv env; + + env.SpawnTask<TSimpleOuter>(""); + //env.SpawnTask<TCoroOuter>(); + //env.SpawnTask<TReproduceCrashTask>(); + + for (;;) { + Sleep(TDuration::Hours(1)); + } + + return 0; +} diff --git a/library/cpp/messagebus/rain_check/test/perftest/ya.make b/library/cpp/messagebus/rain_check/test/perftest/ya.make index f80ddf2c05..7330a71700 100644 --- a/library/cpp/messagebus/rain_check/test/perftest/ya.make +++ b/library/cpp/messagebus/rain_check/test/perftest/ya.make @@ -1,14 +1,14 @@ -PROGRAM(messagebus_rain_check_perftest) - +PROGRAM(messagebus_rain_check_perftest) + OWNER(g:messagebus) - -PEERDIR( + +PEERDIR( library/cpp/messagebus/rain_check/core library/cpp/messagebus/rain_check/test/helper -) - -SRCS( - perftest.cpp -) - -END() +) + +SRCS( + perftest.cpp +) + +END() diff --git a/library/cpp/messagebus/rain_check/test/ut/test.h b/library/cpp/messagebus/rain_check/test/ut/test.h index 922f0f06cb..724f6b7530 100644 --- a/library/cpp/messagebus/rain_check/test/ut/test.h +++ b/library/cpp/messagebus/rain_check/test/ut/test.h @@ -1,13 +1,13 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/rain_check/core/rain_check.h> #include <library/cpp/messagebus/misc/test_sync.h> - -template <typename TSelf> -struct TTestEnvTemplate: public NRainCheck::TSimpleEnvTemplate<TSelf> { - TTestSync TestSync; -}; - -struct TTestEnv: public TTestEnvTemplate<TTestEnv> { -}; + +template <typename TSelf> +struct TTestEnvTemplate: public NRainCheck::TSimpleEnvTemplate<TSelf> { + TTestSync TestSync; +}; + +struct TTestEnv: public TTestEnvTemplate<TTestEnv> { +}; diff --git a/library/cpp/messagebus/rain_check/test/ut/ya.make b/library/cpp/messagebus/rain_check/test/ut/ya.make index 6191fe9fe0..9f7a93417a 100644 --- a/library/cpp/messagebus/rain_check/test/ut/ya.make +++ b/library/cpp/messagebus/rain_check/test/ut/ya.make @@ -1,24 +1,24 @@ PROGRAM(library-messagebus-rain_check-test-ut) - + OWNER(g:messagebus) - -PEERDIR( + +PEERDIR( library/cpp/testing/unittest_main library/cpp/messagebus/rain_check/core library/cpp/messagebus/rain_check/http library/cpp/messagebus/rain_check/messagebus library/cpp/messagebus/test/helper -) - -SRCS( - ../../core/coro_ut.cpp - ../../core/simple_ut.cpp - ../../core/sleep_ut.cpp - ../../core/spawn_ut.cpp - ../../core/track_ut.cpp +) + +SRCS( + ../../core/coro_ut.cpp + ../../core/simple_ut.cpp + ../../core/sleep_ut.cpp + ../../core/spawn_ut.cpp + ../../core/track_ut.cpp ../../http/client_ut.cpp - ../../messagebus/messagebus_client_ut.cpp - ../../messagebus/messagebus_server_ut.cpp -) - -END() + ../../messagebus/messagebus_client_ut.cpp + ../../messagebus/messagebus_server_ut.cpp +) + +END() diff --git a/library/cpp/messagebus/rain_check/test/ya.make b/library/cpp/messagebus/rain_check/test/ya.make index 83cdb16977..4c1d6f8161 100644 --- a/library/cpp/messagebus/rain_check/test/ya.make +++ b/library/cpp/messagebus/rain_check/test/ya.make @@ -1,6 +1,6 @@ OWNER(g:messagebus) -RECURSE( +RECURSE( perftest ut -) +) diff --git a/library/cpp/messagebus/rain_check/ya.make b/library/cpp/messagebus/rain_check/ya.make index c408615f42..966d54c232 100644 --- a/library/cpp/messagebus/rain_check/ya.make +++ b/library/cpp/messagebus/rain_check/ya.make @@ -1,8 +1,8 @@ OWNER(g:messagebus) -RECURSE( +RECURSE( core http messagebus test -) +) diff --git a/library/cpp/messagebus/ref_counted.h b/library/cpp/messagebus/ref_counted.h index bbe908b7c2..29b87764e3 100644 --- a/library/cpp/messagebus/ref_counted.h +++ b/library/cpp/messagebus/ref_counted.h @@ -1,6 +1,6 @@ -#pragma once - +#pragma once + class TAtomicRefCountedObject: public TAtomicRefCount<TAtomicRefCountedObject> { virtual ~TAtomicRefCountedObject() { } -}; +}; diff --git a/library/cpp/messagebus/remote_client_connection.cpp b/library/cpp/messagebus/remote_client_connection.cpp index b7b05e7bed..8c7a6db3a8 100644 --- a/library/cpp/messagebus/remote_client_connection.cpp +++ b/library/cpp/messagebus/remote_client_connection.cpp @@ -1,143 +1,143 @@ -#include "remote_client_connection.h" - +#include "remote_client_connection.h" + #include "mb_lwtrace.h" #include "network.h" -#include "remote_client_session.h" - +#include "remote_client_session.h" + #include <library/cpp/messagebus/actor/executor.h> #include <library/cpp/messagebus/actor/temp_tls_vector.h> - + #include <util/generic/cast.h> #include <util/thread/singleton.h> - -LWTRACE_USING(LWTRACE_MESSAGEBUS_PROVIDER) - -using namespace NActor; -using namespace NBus; -using namespace NBus::NPrivate; - -TRemoteClientConnection::TRemoteClientConnection(TRemoteClientSessionPtr session, ui64 id, TNetAddr addr) - : TRemoteConnection(session.Get(), id, addr) - , ClientHandler(GetSession()->ClientHandler) -{ + +LWTRACE_USING(LWTRACE_MESSAGEBUS_PROVIDER) + +using namespace NActor; +using namespace NBus; +using namespace NBus::NPrivate; + +TRemoteClientConnection::TRemoteClientConnection(TRemoteClientSessionPtr session, ui64 id, TNetAddr addr) + : TRemoteConnection(session.Get(), id, addr) + , ClientHandler(GetSession()->ClientHandler) +{ Y_VERIFY(addr.GetPort() > 0, "must connect to non-zero port"); - - ScheduleWrite(); -} - -TRemoteClientSession* TRemoteClientConnection::GetSession() { - return CheckedCast<TRemoteClientSession*>(Session.Get()); -} - -TBusMessage* TRemoteClientConnection::PopAck(TBusKey id) { - return AckMessages.Pop(id); -} - + + ScheduleWrite(); +} + +TRemoteClientSession* TRemoteClientConnection::GetSession() { + return CheckedCast<TRemoteClientSession*>(Session.Get()); +} + +TBusMessage* TRemoteClientConnection::PopAck(TBusKey id) { + return AckMessages.Pop(id); +} + SOCKET TRemoteClientConnection::CreateSocket(const TNetAddr& addr) { - SOCKET handle = socket(addr.Addr()->sa_family, SOCK_STREAM, 0); + SOCKET handle = socket(addr.Addr()->sa_family, SOCK_STREAM, 0); Y_VERIFY(handle != INVALID_SOCKET, "failed to create socket: %s", LastSystemErrorText()); - - TSocketHolder s(handle); - - SetNonBlock(s, true); - SetNoDelay(s, Config.TcpNoDelay); - SetSockOptTcpCork(s, Config.TcpCork); - SetCloseOnExec(s, true); - SetKeepAlive(s, true); - if (Config.SocketRecvBufferSize != 0) { - SetInputBuffer(s, Config.SocketRecvBufferSize); - } - if (Config.SocketSendBufferSize != 0) { - SetOutputBuffer(s, Config.SocketSendBufferSize); - } - if (Config.SocketToS >= 0) { - SetSocketToS(s, &addr, Config.SocketToS); - } - - return s.Release(); -} - -void TRemoteClientConnection::TryConnect() { - if (AtomicGet(WriterData.Down)) { - return; - } + + TSocketHolder s(handle); + + SetNonBlock(s, true); + SetNoDelay(s, Config.TcpNoDelay); + SetSockOptTcpCork(s, Config.TcpCork); + SetCloseOnExec(s, true); + SetKeepAlive(s, true); + if (Config.SocketRecvBufferSize != 0) { + SetInputBuffer(s, Config.SocketRecvBufferSize); + } + if (Config.SocketSendBufferSize != 0) { + SetOutputBuffer(s, Config.SocketSendBufferSize); + } + if (Config.SocketToS >= 0) { + SetSocketToS(s, &addr, Config.SocketToS); + } + + return s.Release(); +} + +void TRemoteClientConnection::TryConnect() { + if (AtomicGet(WriterData.Down)) { + return; + } Y_VERIFY(!WriterData.Status.Connected); - - TInstant now = TInstant::Now(); - - if (!WriterData.Channel) { - if ((now - LastConnectAttempt) < TDuration::MilliSeconds(Config.RetryInterval)) { + + TInstant now = TInstant::Now(); + + if (!WriterData.Channel) { + if ((now - LastConnectAttempt) < TDuration::MilliSeconds(Config.RetryInterval)) { DropEnqueuedData(MESSAGE_CONNECT_FAILED, MESSAGE_CONNECT_FAILED); - return; - } - LastConnectAttempt = now; - - TSocket connectSocket(CreateSocket(PeerAddr)); - WriterData.SetChannel(Session->WriteEventLoop.Register(connectSocket, this, WriteCookie)); - } - + return; + } + LastConnectAttempt = now; + + TSocket connectSocket(CreateSocket(PeerAddr)); + WriterData.SetChannel(Session->WriteEventLoop.Register(connectSocket, this, WriteCookie)); + } + if (BeforeSendQueue.IsEmpty() && WriterData.SendQueue.Empty() && !Config.ReconnectWhenIdle) { // TryConnect is called from Writer::Act, which is called in cycle // from session's ScheduleTimeoutMessages via Cron. This prevent these excessive connects. return; } - ++WriterData.Status.ConnectSyscalls; - - int ret = connect(WriterData.Channel->GetSocket(), PeerAddr.Addr(), PeerAddr.Len()); - int err = ret ? LastSystemError() : 0; - - if (!ret || (ret && err == EISCONN)) { - WriterData.Status.ConnectTime = now; - ++WriterData.SocketVersion; - - WriterData.Channel->DisableWrite(); - WriterData.Status.Connected = true; - AtomicSet(ReturnConnectFailedImmediately, false); - - WriterData.Status.MyAddr = TNetAddr(GetSockAddr(WriterData.Channel->GetSocket())); - - TSocket readSocket = WriterData.Channel->GetSocketPtr(); - - ReaderGetSocketQueue()->EnqueueAndSchedule(TWriterToReaderSocketMessage(readSocket, WriterData.SocketVersion)); - - FireClientConnectionEvent(TClientConnectionEvent::CONNECTED); - - ScheduleWrite(); - } else { - if (WouldBlock() || err == EALREADY) { - WriterData.Channel->EnableWrite(); - } else { - WriterData.DropChannel(); - WriterData.Status.MyAddr = TNetAddr(); - WriterData.Status.Connected = false; - WriterData.Status.ConnectError = err; - + ++WriterData.Status.ConnectSyscalls; + + int ret = connect(WriterData.Channel->GetSocket(), PeerAddr.Addr(), PeerAddr.Len()); + int err = ret ? LastSystemError() : 0; + + if (!ret || (ret && err == EISCONN)) { + WriterData.Status.ConnectTime = now; + ++WriterData.SocketVersion; + + WriterData.Channel->DisableWrite(); + WriterData.Status.Connected = true; + AtomicSet(ReturnConnectFailedImmediately, false); + + WriterData.Status.MyAddr = TNetAddr(GetSockAddr(WriterData.Channel->GetSocket())); + + TSocket readSocket = WriterData.Channel->GetSocketPtr(); + + ReaderGetSocketQueue()->EnqueueAndSchedule(TWriterToReaderSocketMessage(readSocket, WriterData.SocketVersion)); + + FireClientConnectionEvent(TClientConnectionEvent::CONNECTED); + + ScheduleWrite(); + } else { + if (WouldBlock() || err == EALREADY) { + WriterData.Channel->EnableWrite(); + } else { + WriterData.DropChannel(); + WriterData.Status.MyAddr = TNetAddr(); + WriterData.Status.Connected = false; + WriterData.Status.ConnectError = err; + DropEnqueuedData(MESSAGE_CONNECT_FAILED, MESSAGE_CONNECT_FAILED); - } - } -} - -void TRemoteClientConnection::HandleEvent(SOCKET socket, void* cookie) { + } + } +} + +void TRemoteClientConnection::HandleEvent(SOCKET socket, void* cookie) { Y_UNUSED(socket); Y_ASSERT(cookie == WriteCookie || cookie == ReadCookie); - if (cookie == ReadCookie) { - ScheduleRead(); - } else { - ScheduleWrite(); - } -} - -void TRemoteClientConnection::WriterFillStatus() { - TRemoteConnection::WriterFillStatus(); - WriterData.Status.AckMessagesSize = AckMessages.Size(); -} - -void TRemoteClientConnection::BeforeTryWrite() { - ProcessReplyQueue(); - TimeoutMessages(); -} - + if (cookie == ReadCookie) { + ScheduleRead(); + } else { + ScheduleWrite(); + } +} + +void TRemoteClientConnection::WriterFillStatus() { + TRemoteConnection::WriterFillStatus(); + WriterData.Status.AckMessagesSize = AckMessages.Size(); +} + +void TRemoteClientConnection::BeforeTryWrite() { + ProcessReplyQueue(); + TimeoutMessages(); +} + namespace NBus { namespace NPrivate { class TInvokeOnReply: public IWorkItem { @@ -145,7 +145,7 @@ namespace NBus { TRemoteClientSession* RemoteClientSession; TNonDestroyingHolder<TBusMessage> Request; TBusMessagePtrAndHeader Response; - + public: TInvokeOnReply(TRemoteClientSession* session, TNonDestroyingAutoPtr<TBusMessage> request, TBusMessagePtrAndHeader& response) @@ -154,7 +154,7 @@ namespace NBus { { Response.Swap(response); } - + void DoWork() override { THolder<TInvokeOnReply> holder(this); RemoteClientSession->ReleaseInFlightAndCallOnReply(Request.Release(), Response); @@ -162,182 +162,182 @@ namespace NBus { RemoteClientSession->JobCount.Decrement(); } }; - + } } - -void TRemoteClientConnection::ProcessReplyQueue() { - if (AtomicGet(WriterData.Down)) { - return; - } - - bool executeInWorkerPool = Session->Config.ExecuteOnReplyInWorkerPool; - - TTempTlsVector<TBusMessagePtrAndHeader, void, TVectorSwaps> replyQueueTemp; - TTempTlsVector< ::NActor::IWorkItem*> workQueueTemp; - - ReplyQueue.DequeueAllSingleConsumer(replyQueueTemp.GetVector()); - if (executeInWorkerPool) { - workQueueTemp.GetVector()->reserve(replyQueueTemp.GetVector()->size()); - } - + +void TRemoteClientConnection::ProcessReplyQueue() { + if (AtomicGet(WriterData.Down)) { + return; + } + + bool executeInWorkerPool = Session->Config.ExecuteOnReplyInWorkerPool; + + TTempTlsVector<TBusMessagePtrAndHeader, void, TVectorSwaps> replyQueueTemp; + TTempTlsVector< ::NActor::IWorkItem*> workQueueTemp; + + ReplyQueue.DequeueAllSingleConsumer(replyQueueTemp.GetVector()); + if (executeInWorkerPool) { + workQueueTemp.GetVector()->reserve(replyQueueTemp.GetVector()->size()); + } + for (auto& resp : *replyQueueTemp.GetVector()) { TBusMessage* req = PopAck(resp.Header.Id); - - if (!req) { + + if (!req) { WriterErrorMessage(resp.MessagePtr.Release(), MESSAGE_UNKNOWN); - continue; - } - - if (executeInWorkerPool) { + continue; + } + + if (executeInWorkerPool) { workQueueTemp.GetVector()->push_back(new TInvokeOnReply(GetSession(), req, resp)); - } else { + } else { GetSession()->ReleaseInFlightAndCallOnReply(req, resp); - } - } - - if (executeInWorkerPool) { - Session->JobCount.Add(workQueueTemp.GetVector()->size()); - Session->Queue->EnqueueWork(*workQueueTemp.GetVector()); - } -} - -void TRemoteClientConnection::TimeoutMessages() { - if (!TimeToTimeoutMessages.FetchTask()) { - return; - } - - TMessagesPtrs timedOutMessages; - - TInstant sendDeadline; - TInstant ackDeadline; - if (IsReturnConnectFailedImmediately()) { - sendDeadline = TInstant::Max(); - ackDeadline = TInstant::Max(); - } else { - TInstant now = TInstant::Now(); - sendDeadline = now - TDuration::MilliSeconds(Session->Config.SendTimeout); - ackDeadline = now - TDuration::MilliSeconds(Session->Config.TotalTimeout); - } - - { - TMessagesPtrs temp; - WriterData.SendQueue.Timeout(sendDeadline, &temp); - timedOutMessages.insert(timedOutMessages.end(), temp.begin(), temp.end()); - } - - // Ignores message that is being written currently (that is stored - // in WriteMessage). It is not a big problem, because after written - // to the network, message will be placed to the AckMessages queue, - // and timed out on the next iteration of this procedure. - - { - TMessagesPtrs temp; - AckMessages.Timeout(ackDeadline, &temp); - timedOutMessages.insert(timedOutMessages.end(), temp.begin(), temp.end()); - } - - ResetOneWayFlag(timedOutMessages); - - GetSession()->ReleaseInFlight(timedOutMessages); - WriterErrorMessages(timedOutMessages, MESSAGE_TIMEOUT); -} - -void TRemoteClientConnection::ScheduleTimeoutMessages() { - TimeToTimeoutMessages.AddTask(); - ScheduleWrite(); -} - + } + } + + if (executeInWorkerPool) { + Session->JobCount.Add(workQueueTemp.GetVector()->size()); + Session->Queue->EnqueueWork(*workQueueTemp.GetVector()); + } +} + +void TRemoteClientConnection::TimeoutMessages() { + if (!TimeToTimeoutMessages.FetchTask()) { + return; + } + + TMessagesPtrs timedOutMessages; + + TInstant sendDeadline; + TInstant ackDeadline; + if (IsReturnConnectFailedImmediately()) { + sendDeadline = TInstant::Max(); + ackDeadline = TInstant::Max(); + } else { + TInstant now = TInstant::Now(); + sendDeadline = now - TDuration::MilliSeconds(Session->Config.SendTimeout); + ackDeadline = now - TDuration::MilliSeconds(Session->Config.TotalTimeout); + } + + { + TMessagesPtrs temp; + WriterData.SendQueue.Timeout(sendDeadline, &temp); + timedOutMessages.insert(timedOutMessages.end(), temp.begin(), temp.end()); + } + + // Ignores message that is being written currently (that is stored + // in WriteMessage). It is not a big problem, because after written + // to the network, message will be placed to the AckMessages queue, + // and timed out on the next iteration of this procedure. + + { + TMessagesPtrs temp; + AckMessages.Timeout(ackDeadline, &temp); + timedOutMessages.insert(timedOutMessages.end(), temp.begin(), temp.end()); + } + + ResetOneWayFlag(timedOutMessages); + + GetSession()->ReleaseInFlight(timedOutMessages); + WriterErrorMessages(timedOutMessages, MESSAGE_TIMEOUT); +} + +void TRemoteClientConnection::ScheduleTimeoutMessages() { + TimeToTimeoutMessages.AddTask(); + ScheduleWrite(); +} + void TRemoteClientConnection::ReaderProcessMessageUnknownVersion(TArrayRef<const char>) { - LWPROBE(Error, ToString(MESSAGE_INVALID_VERSION), ToString(PeerAddr), ""); - ReaderData.Status.Incremental.StatusCounter[MESSAGE_INVALID_VERSION] += 1; - // TODO: close connection + LWPROBE(Error, ToString(MESSAGE_INVALID_VERSION), ToString(PeerAddr), ""); + ReaderData.Status.Incremental.StatusCounter[MESSAGE_INVALID_VERSION] += 1; + // TODO: close connection Y_FAIL("unknown message"); -} - -void TRemoteClientConnection::ClearOutgoingQueue(TMessagesPtrs& result, bool reconnect) { +} + +void TRemoteClientConnection::ClearOutgoingQueue(TMessagesPtrs& result, bool reconnect) { Y_ASSERT(result.empty()); - - TRemoteConnection::ClearOutgoingQueue(result, reconnect); - AckMessages.Clear(&result); - - ResetOneWayFlag(result); - GetSession()->ReleaseInFlight(result); -} - + + TRemoteConnection::ClearOutgoingQueue(result, reconnect); + AckMessages.Clear(&result); + + ResetOneWayFlag(result); + GetSession()->ReleaseInFlight(result); +} + void TRemoteClientConnection::MessageSent(TArrayRef<TBusMessagePtrAndHeader> messages) { for (auto& message : messages) { bool oneWay = message.LocalFlags & MESSAGE_ONE_WAY_INTERNAL; - - if (oneWay) { + + if (oneWay) { message.MessagePtr->LocalFlags &= ~MESSAGE_ONE_WAY_INTERNAL; - + TBusMessage* ackMsg = this->PopAck(message.Header.Id); - if (!ackMsg) { - // TODO: expired? - } - + if (!ackMsg) { + // TODO: expired? + } + if (ackMsg != message.MessagePtr.Get()) { - // TODO: non-unique id? - } - + // TODO: non-unique id? + } + GetSession()->ReleaseInFlight({message.MessagePtr.Get()}); ClientHandler->OnMessageSentOneWay(message.MessagePtr.Release()); - } else { + } else { ClientHandler->OnMessageSent(message.MessagePtr.Get()); AckMessages.Push(message); - } - } -} - -EMessageStatus TRemoteClientConnection::SendMessage(TBusMessage* req, bool wait) { - return SendMessageImpl(req, wait, false); -} - -EMessageStatus TRemoteClientConnection::SendMessageOneWay(TBusMessage* req, bool wait) { - return SendMessageImpl(req, wait, true); -} - -EMessageStatus TRemoteClientConnection::SendMessageImpl(TBusMessage* msg, bool wait, bool oneWay) { - msg->CheckClean(); - - if (Session->IsDown()) { - return MESSAGE_SHUTDOWN; - } - - if (wait) { + } + } +} + +EMessageStatus TRemoteClientConnection::SendMessage(TBusMessage* req, bool wait) { + return SendMessageImpl(req, wait, false); +} + +EMessageStatus TRemoteClientConnection::SendMessageOneWay(TBusMessage* req, bool wait) { + return SendMessageImpl(req, wait, true); +} + +EMessageStatus TRemoteClientConnection::SendMessageImpl(TBusMessage* msg, bool wait, bool oneWay) { + msg->CheckClean(); + + if (Session->IsDown()) { + return MESSAGE_SHUTDOWN; + } + + if (wait) { Y_VERIFY(!Session->Queue->GetExecutor()->IsInExecutorThread()); - GetSession()->ClientRemoteInFlight.Wait(); - } else { - if (!GetSession()->ClientRemoteInFlight.TryWait()) { - return MESSAGE_BUSY; - } - } - + GetSession()->ClientRemoteInFlight.Wait(); + } else { + if (!GetSession()->ClientRemoteInFlight.TryWait()) { + return MESSAGE_BUSY; + } + } + GetSession()->AcquireInFlight({msg}); - - EMessageStatus ret = MESSAGE_OK; - - if (oneWay) { - msg->LocalFlags |= MESSAGE_ONE_WAY_INTERNAL; - } - - msg->GetHeader()->SendTime = Now(); - - if (IsReturnConnectFailedImmediately()) { - ret = MESSAGE_CONNECT_FAILED; - goto clean; - } - - Send(msg); - - return MESSAGE_OK; -clean: - msg->LocalFlags &= ~MESSAGE_ONE_WAY_INTERNAL; + + EMessageStatus ret = MESSAGE_OK; + + if (oneWay) { + msg->LocalFlags |= MESSAGE_ONE_WAY_INTERNAL; + } + + msg->GetHeader()->SendTime = Now(); + + if (IsReturnConnectFailedImmediately()) { + ret = MESSAGE_CONNECT_FAILED; + goto clean; + } + + Send(msg); + + return MESSAGE_OK; +clean: + msg->LocalFlags &= ~MESSAGE_ONE_WAY_INTERNAL; GetSession()->ReleaseInFlight({msg}); - return ret; -} - -void TRemoteClientConnection::OpenConnection() { - // TODO -} + return ret; +} + +void TRemoteClientConnection::OpenConnection() { + // TODO +} diff --git a/library/cpp/messagebus/remote_client_connection.h b/library/cpp/messagebus/remote_client_connection.h index 124a37a07a..fe80b7d2f9 100644 --- a/library/cpp/messagebus/remote_client_connection.h +++ b/library/cpp/messagebus/remote_client_connection.h @@ -1,10 +1,10 @@ -#pragma once - +#pragma once + #include "connection.h" -#include "local_tasks.h" +#include "local_tasks.h" #include "remote_client_session.h" -#include "remote_connection.h" - +#include "remote_connection.h" + #include <util/generic/object_counter.h> namespace NBus { @@ -13,53 +13,53 @@ namespace NBus { friend class TRemoteConnection; friend struct TBusSessionImpl; friend class TRemoteClientSession; - + private: TObjectCounter<TRemoteClientConnection> ObjectCounter; - + TSyncAckMessages AckMessages; - + TLocalTasks TimeToTimeoutMessages; - + IBusClientHandler* const ClientHandler; - + public: TRemoteClientConnection(TRemoteClientSessionPtr session, ui64 id, TNetAddr addr); - + inline TRemoteClientSession* GetSession(); - + SOCKET CreateSocket(const TNetAddr& addr); - + void TryConnect() override; - + void HandleEvent(SOCKET socket, void* cookie) override; - + TBusMessage* PopAck(TBusKey id); - + void WriterFillStatus() override; - + void ClearOutgoingQueue(TMessagesPtrs& result, bool reconnect) override; - + void BeforeTryWrite() override; - + void ProcessReplyQueue(); - + void MessageSent(TArrayRef<TBusMessagePtrAndHeader> messages) override; - + void TimeoutMessages(); - + void ScheduleTimeoutMessages(); - + void ReaderProcessMessageUnknownVersion(TArrayRef<const char> dataRef) override; - + EMessageStatus SendMessage(TBusMessage* pMes, bool wait) override; - + EMessageStatus SendMessageOneWay(TBusMessage* pMes, bool wait) override; - + EMessageStatus SendMessageImpl(TBusMessage*, bool wait, bool oneWay); - + void OpenConnection() override; }; - + } } diff --git a/library/cpp/messagebus/remote_client_session.cpp b/library/cpp/messagebus/remote_client_session.cpp index 70c20b9063..3bc421944f 100644 --- a/library/cpp/messagebus/remote_client_session.cpp +++ b/library/cpp/messagebus/remote_client_session.cpp @@ -1,127 +1,127 @@ -#include "remote_client_session.h" +#include "remote_client_session.h" #include "mb_lwtrace.h" -#include "remote_client_connection.h" - +#include "remote_client_connection.h" + #include <library/cpp/messagebus/scheduler/scheduler.h> #include <util/generic/cast.h> #include <util/system/defaults.h> - -LWTRACE_USING(LWTRACE_MESSAGEBUS_PROVIDER) - -using namespace NBus; -using namespace NBus::NPrivate; - -TRemoteClientSession::TRemoteClientSession(TBusMessageQueue* queue, + +LWTRACE_USING(LWTRACE_MESSAGEBUS_PROVIDER) + +using namespace NBus; +using namespace NBus::NPrivate; + +TRemoteClientSession::TRemoteClientSession(TBusMessageQueue* queue, TBusProtocol* proto, IBusClientHandler* handler, const TBusClientSessionConfig& config, const TString& name) - : TBusSessionImpl(true, queue, proto, handler, config, name) - , ClientRemoteInFlight(config.MaxInFlight, "ClientRemoteInFlight") - , ClientHandler(handler) + : TBusSessionImpl(true, queue, proto, handler, config, name) + , ClientRemoteInFlight(config.MaxInFlight, "ClientRemoteInFlight") + , ClientHandler(handler) { } -TRemoteClientSession::~TRemoteClientSession() { - //Cerr << "~TRemoteClientSession" << Endl; -} - -void TRemoteClientSession::OnMessageReceived(TRemoteConnection* c, TVectorSwaps<TBusMessagePtrAndHeader>& newMsg) { +TRemoteClientSession::~TRemoteClientSession() { + //Cerr << "~TRemoteClientSession" << Endl; +} + +void TRemoteClientSession::OnMessageReceived(TRemoteConnection* c, TVectorSwaps<TBusMessagePtrAndHeader>& newMsg) { TAutoPtr<TVectorSwaps<TBusMessagePtrAndHeader>> temp(new TVectorSwaps<TBusMessagePtrAndHeader>); - temp->swap(newMsg); - c->ReplyQueue.EnqueueAll(temp); - c->ScheduleWrite(); + temp->swap(newMsg); + c->ReplyQueue.EnqueueAll(temp); + c->ScheduleWrite(); } - -EMessageStatus TRemoteClientSession::SendMessageImpl(TBusMessage* msg, const TNetAddr* addr, bool wait, bool oneWay) { + +EMessageStatus TRemoteClientSession::SendMessageImpl(TBusMessage* msg, const TNetAddr* addr, bool wait, bool oneWay) { if (Y_UNLIKELY(IsDown())) { - return MESSAGE_SHUTDOWN; - } - - TBusSocketAddr resolvedAddr; - EMessageStatus ret = GetMessageDestination(msg, addr, &resolvedAddr); - if (ret != MESSAGE_OK) { - return ret; - } - - msg->ReplyTo = resolvedAddr; - + return MESSAGE_SHUTDOWN; + } + + TBusSocketAddr resolvedAddr; + EMessageStatus ret = GetMessageDestination(msg, addr, &resolvedAddr); + if (ret != MESSAGE_OK) { + return ret; + } + + msg->ReplyTo = resolvedAddr; + TRemoteConnectionPtr c = ((TBusSessionImpl*)this)->GetConnection(resolvedAddr, true); Y_ASSERT(!!c); - - return CheckedCast<TRemoteClientConnection*>(c.Get())->SendMessageImpl(msg, wait, oneWay); -} - -EMessageStatus TRemoteClientSession::SendMessage(TBusMessage* msg, const TNetAddr* addr, bool wait) { - return SendMessageImpl(msg, addr, wait, false); -} - -EMessageStatus TRemoteClientSession::SendMessageOneWay(TBusMessage* pMes, const TNetAddr* addr, bool wait) { - return SendMessageImpl(pMes, addr, wait, true); -} - + + return CheckedCast<TRemoteClientConnection*>(c.Get())->SendMessageImpl(msg, wait, oneWay); +} + +EMessageStatus TRemoteClientSession::SendMessage(TBusMessage* msg, const TNetAddr* addr, bool wait) { + return SendMessageImpl(msg, addr, wait, false); +} + +EMessageStatus TRemoteClientSession::SendMessageOneWay(TBusMessage* pMes, const TNetAddr* addr, bool wait) { + return SendMessageImpl(pMes, addr, wait, true); +} + int TRemoteClientSession::GetInFlight() const noexcept { - return ClientRemoteInFlight.GetCurrent(); -} - -void TRemoteClientSession::FillStatus() { - TBusSessionImpl::FillStatus(); - - StatusData.Status.InFlightCount = ClientRemoteInFlight.GetCurrent(); - StatusData.Status.InputPaused = false; -} - + return ClientRemoteInFlight.GetCurrent(); +} + +void TRemoteClientSession::FillStatus() { + TBusSessionImpl::FillStatus(); + + StatusData.Status.InFlightCount = ClientRemoteInFlight.GetCurrent(); + StatusData.Status.InputPaused = false; +} + void TRemoteClientSession::AcquireInFlight(TArrayRef<TBusMessage* const> messages) { for (auto message : messages) { Y_ASSERT(!(message->LocalFlags & MESSAGE_IN_FLIGHT_ON_CLIENT)); message->LocalFlags |= MESSAGE_IN_FLIGHT_ON_CLIENT; - } - ClientRemoteInFlight.IncrementMultiple(messages.size()); -} - + } + ClientRemoteInFlight.IncrementMultiple(messages.size()); +} + void TRemoteClientSession::ReleaseInFlight(TArrayRef<TBusMessage* const> messages) { for (auto message : messages) { Y_ASSERT(message->LocalFlags & MESSAGE_IN_FLIGHT_ON_CLIENT); message->LocalFlags &= ~MESSAGE_IN_FLIGHT_ON_CLIENT; - } - ClientRemoteInFlight.ReleaseMultiple(messages.size()); -} - -void TRemoteClientSession::ReleaseInFlightAndCallOnReply(TNonDestroyingAutoPtr<TBusMessage> request, TBusMessagePtrAndHeader& response) { + } + ClientRemoteInFlight.ReleaseMultiple(messages.size()); +} + +void TRemoteClientSession::ReleaseInFlightAndCallOnReply(TNonDestroyingAutoPtr<TBusMessage> request, TBusMessagePtrAndHeader& response) { ReleaseInFlight({request.Get()}); if (Y_UNLIKELY(AtomicGet(Down))) { - InvokeOnError(request, MESSAGE_SHUTDOWN); - InvokeOnError(response.MessagePtr.Release(), MESSAGE_SHUTDOWN); - - TRemoteConnectionReaderIncrementalStatus counter; - LWPROBE(Error, ToString(MESSAGE_SHUTDOWN), "", ""); - counter.StatusCounter[MESSAGE_SHUTDOWN] += 1; - GetDeadConnectionReaderStatusQueue()->EnqueueAndSchedule(counter); - } else { - TWhatThreadDoesPushPop pp("OnReply"); - ClientHandler->OnReply(request, response.MessagePtr.Release()); - } -} - + InvokeOnError(request, MESSAGE_SHUTDOWN); + InvokeOnError(response.MessagePtr.Release(), MESSAGE_SHUTDOWN); + + TRemoteConnectionReaderIncrementalStatus counter; + LWPROBE(Error, ToString(MESSAGE_SHUTDOWN), "", ""); + counter.StatusCounter[MESSAGE_SHUTDOWN] += 1; + GetDeadConnectionReaderStatusQueue()->EnqueueAndSchedule(counter); + } else { + TWhatThreadDoesPushPop pp("OnReply"); + ClientHandler->OnReply(request, response.MessagePtr.Release()); + } +} + EMessageStatus TRemoteClientSession::GetMessageDestination(TBusMessage* mess, const TNetAddr* addrp, TBusSocketAddr* dest) { - if (addrp) { - *dest = *addrp; - } else { - TNetAddr tmp; - EMessageStatus ret = const_cast<TBusProtocol*>(GetProto())->GetDestination(this, mess, GetQueue()->GetLocator(), &tmp); - if (ret != MESSAGE_OK) { - return ret; - } - *dest = tmp; - } - return MESSAGE_OK; -} - -void TRemoteClientSession::OpenConnection(const TNetAddr& addr) { - GetConnection(addr)->OpenConnection(); -} - -TBusClientConnectionPtr TRemoteClientSession::GetConnection(const TNetAddr& addr) { - // TODO: GetConnection should not open + if (addrp) { + *dest = *addrp; + } else { + TNetAddr tmp; + EMessageStatus ret = const_cast<TBusProtocol*>(GetProto())->GetDestination(this, mess, GetQueue()->GetLocator(), &tmp); + if (ret != MESSAGE_OK) { + return ret; + } + *dest = tmp; + } + return MESSAGE_OK; +} + +void TRemoteClientSession::OpenConnection(const TNetAddr& addr) { + GetConnection(addr)->OpenConnection(); +} + +TBusClientConnectionPtr TRemoteClientSession::GetConnection(const TNetAddr& addr) { + // TODO: GetConnection should not open return CheckedCast<TRemoteClientConnection*>(((TBusSessionImpl*)this)->GetConnection(addr, true).Get()); -} +} diff --git a/library/cpp/messagebus/remote_client_session.h b/library/cpp/messagebus/remote_client_session.h index 8268a6c0a3..7160d0dae9 100644 --- a/library/cpp/messagebus/remote_client_session.h +++ b/library/cpp/messagebus/remote_client_session.h @@ -1,8 +1,8 @@ #pragma once -#include "remote_client_session_semaphore.h" -#include "session_impl.h" - +#include "remote_client_session_semaphore.h" +#include "session_impl.h" + #include <util/generic/array_ref.h> #include <util/generic/object_counter.h> @@ -10,7 +10,7 @@ #pragma warning(push) #pragma warning(disable : 4250) // 'NBus::NPrivate::TRemoteClientSession' : inherits 'NBus::NPrivate::TBusSessionImpl::NBus::NPrivate::TBusSessionImpl::GetConfig' via dominance #endif - + namespace NBus { namespace NPrivate { using TRemoteClientSessionPtr = TIntrusivePtr<TRemoteClientSession>; @@ -18,39 +18,39 @@ namespace NBus { class TRemoteClientSession: public TBusClientSession, public TBusSessionImpl { friend class TRemoteClientConnection; friend class TInvokeOnReply; - + public: TObjectCounter<TRemoteClientSession> ObjectCounter; - + TRemoteClientSessionSemaphore ClientRemoteInFlight; IBusClientHandler* const ClientHandler; - + public: TRemoteClientSession(TBusMessageQueue* queue, TBusProtocol* proto, IBusClientHandler* handler, const TBusSessionConfig& config, const TString& name); - + ~TRemoteClientSession() override; - + void OnMessageReceived(TRemoteConnection* c, TVectorSwaps<TBusMessagePtrAndHeader>& newMsg) override; - + EMessageStatus SendMessageImpl(TBusMessage* msg, const TNetAddr* addr, bool wait, bool oneWay); EMessageStatus SendMessage(TBusMessage* msg, const TNetAddr* addr = nullptr, bool wait = false) override; EMessageStatus SendMessageOneWay(TBusMessage* msg, const TNetAddr* addr = nullptr, bool wait = false) override; - + int GetInFlight() const noexcept override; void FillStatus() override; void AcquireInFlight(TArrayRef<TBusMessage* const> messages); void ReleaseInFlight(TArrayRef<TBusMessage* const> messages); void ReleaseInFlightAndCallOnReply(TNonDestroyingAutoPtr<TBusMessage> request, TBusMessagePtrAndHeader& response); - + EMessageStatus GetMessageDestination(TBusMessage* mess, const TNetAddr* addrp, TBusSocketAddr* dest); - + void OpenConnection(const TNetAddr&) override; - + TBusClientConnectionPtr GetConnection(const TNetAddr&) override; }; - + #ifdef _MSC_VER #pragma warning(pop) #endif diff --git a/library/cpp/messagebus/remote_client_session_semaphore.cpp b/library/cpp/messagebus/remote_client_session_semaphore.cpp index f1d02cc5c2..f877ed4257 100644 --- a/library/cpp/messagebus/remote_client_session_semaphore.cpp +++ b/library/cpp/messagebus/remote_client_session_semaphore.cpp @@ -1,67 +1,67 @@ #include "remote_client_session_semaphore.h" #include <util/stream/output.h> -#include <util/system/yassert.h> - -using namespace NBus; -using namespace NBus::NPrivate; - -TRemoteClientSessionSemaphore::TRemoteClientSessionSemaphore(TAtomicBase limit, const char* name) - : Name(name) - , Limit(limit) - , Current(0) - , StopSignal(0) -{ +#include <util/system/yassert.h> + +using namespace NBus; +using namespace NBus::NPrivate; + +TRemoteClientSessionSemaphore::TRemoteClientSessionSemaphore(TAtomicBase limit, const char* name) + : Name(name) + , Limit(limit) + , Current(0) + , StopSignal(0) +{ Y_VERIFY(limit > 0, "limit must be > 0"); Y_UNUSED(Name); -} - +} + TRemoteClientSessionSemaphore::~TRemoteClientSessionSemaphore() { Y_VERIFY(AtomicGet(Current) == 0); -} - -bool TRemoteClientSessionSemaphore::TryAcquire() { - if (!TryWait()) { - return false; - } - - AtomicIncrement(Current); - return true; -} - -bool TRemoteClientSessionSemaphore::TryWait() { - if (AtomicGet(Current) < Limit) - return true; +} + +bool TRemoteClientSessionSemaphore::TryAcquire() { + if (!TryWait()) { + return false; + } + + AtomicIncrement(Current); + return true; +} + +bool TRemoteClientSessionSemaphore::TryWait() { + if (AtomicGet(Current) < Limit) + return true; if (Y_UNLIKELY(AtomicGet(StopSignal))) - return true; - return false; -} - -void TRemoteClientSessionSemaphore::Acquire() { - Wait(); - - Increment(); -} - -void TRemoteClientSessionSemaphore::Increment() { - IncrementMultiple(1); -} - -void TRemoteClientSessionSemaphore::IncrementMultiple(TAtomicBase count) { - AtomicAdd(Current, count); - Updated(); -} - -void TRemoteClientSessionSemaphore::Release() { - ReleaseMultiple(1); -} - -void TRemoteClientSessionSemaphore::ReleaseMultiple(TAtomicBase count) { - AtomicSub(Current, count); - Updated(); -} - -void TRemoteClientSessionSemaphore::Stop() { - AtomicSet(StopSignal, 1); - Updated(); -} + return true; + return false; +} + +void TRemoteClientSessionSemaphore::Acquire() { + Wait(); + + Increment(); +} + +void TRemoteClientSessionSemaphore::Increment() { + IncrementMultiple(1); +} + +void TRemoteClientSessionSemaphore::IncrementMultiple(TAtomicBase count) { + AtomicAdd(Current, count); + Updated(); +} + +void TRemoteClientSessionSemaphore::Release() { + ReleaseMultiple(1); +} + +void TRemoteClientSessionSemaphore::ReleaseMultiple(TAtomicBase count) { + AtomicSub(Current, count); + Updated(); +} + +void TRemoteClientSessionSemaphore::Stop() { + AtomicSet(StopSignal, 1); + Updated(); +} diff --git a/library/cpp/messagebus/remote_client_session_semaphore.h b/library/cpp/messagebus/remote_client_session_semaphore.h index 3bb86213c2..286ca3c86f 100644 --- a/library/cpp/messagebus/remote_client_session_semaphore.h +++ b/library/cpp/messagebus/remote_client_session_semaphore.h @@ -1,30 +1,30 @@ -#pragma once - +#pragma once + #include "cc_semaphore.h" -#include <util/generic/noncopyable.h> +#include <util/generic/noncopyable.h> #include <util/system/atomic.h> #include <util/system/condvar.h> -#include <util/system/mutex.h> - +#include <util/system/mutex.h> + namespace NBus { namespace NPrivate { class TRemoteClientSessionSemaphore: public TComplexConditionSemaphore<TRemoteClientSessionSemaphore> { private: const char* const Name; - + TAtomicBase const Limit; TAtomic Current; TAtomic StopSignal; - + public: TRemoteClientSessionSemaphore(TAtomicBase limit, const char* name = "unnamed"); ~TRemoteClientSessionSemaphore(); - + TAtomicBase GetCurrent() const { return AtomicGet(Current); } - + void Acquire(); bool TryAcquire(); void Increment(); @@ -33,10 +33,10 @@ namespace NBus { void Release(); void ReleaseMultiple(TAtomicBase count); void Stop(); - + private: void CheckNeedToUnlock(); }; - + } } diff --git a/library/cpp/messagebus/remote_connection.cpp b/library/cpp/messagebus/remote_connection.cpp index 2e14d78eb4..22932569db 100644 --- a/library/cpp/messagebus/remote_connection.cpp +++ b/library/cpp/messagebus/remote_connection.cpp @@ -1,11 +1,11 @@ #include "remote_connection.h" - -#include "key_value_printer.h" + +#include "key_value_printer.h" #include "mb_lwtrace.h" #include "network.h" -#include "remote_client_connection.h" -#include "remote_client_session.h" -#include "remote_server_session.h" +#include "remote_client_connection.h" +#include "remote_client_session.h" +#include "remote_server_session.h" #include "session_impl.h" #include <library/cpp/messagebus/actor/what_thread_does.h> @@ -14,12 +14,12 @@ #include <util/network/init.h> #include <util/system/atomic.h> -LWTRACE_USING(LWTRACE_MESSAGEBUS_PROVIDER) - -using namespace NActor; -using namespace NBus; -using namespace NBus::NPrivate; - +LWTRACE_USING(LWTRACE_MESSAGEBUS_PROVIDER) + +using namespace NActor; +using namespace NBus; +using namespace NBus::NPrivate; + namespace NBus { namespace NPrivate { TRemoteConnection::TRemoteConnection(TRemoteSessionPtr session, ui64 connectionId, TNetAddr addr) @@ -46,7 +46,7 @@ namespace NBus { ReaderData.Status.ConnectionId = connectionId; const TInstant now = TInstant::Now(); - + WriterFillStatus(); GranStatus.Writer.Update(WriterData.Status, now, true); @@ -56,7 +56,7 @@ namespace NBus { TRemoteConnection::~TRemoteConnection() { Y_VERIFY(ReplyQueue.IsEmpty()); } - + TRemoteConnection::TWriterData::TWriterData() : Down(0) , SocketVersion(0) @@ -65,7 +65,7 @@ namespace NBus { , State(WRITER_FILLING) { } - + TRemoteConnection::TWriterData::~TWriterData() { Y_VERIFY(AtomicGet(Down)); Y_VERIFY(SendQueue.Empty()); @@ -76,7 +76,7 @@ namespace NBus { return (MoreBytes = left >= bytes ? 0 : bytes - left) == 0; } - + void TRemoteConnection::TWriterData::SetChannel(NEventLoop::TChannelPtr channel) { Y_VERIFY(!Channel, "must not have channel"); Y_VERIFY(Buffer.GetBuffer().Empty() && Buffer.LeftSize() == 0, "buffer must be empty"); @@ -95,11 +95,11 @@ namespace NBus { Channel->Unregister(); Channel.Drop(); } - + Buffer.Reset(); State = WRITER_FILLING; } - + void TRemoteConnection::TReaderData::DropChannel() { // TODO: make Drop call Unregister if (!!Channel) { @@ -109,7 +109,7 @@ namespace NBus { Buffer.Reset(); Offset = 0; } - + TRemoteConnection::TReaderData::TReaderData() : Down(0) , SocketVersion(0) @@ -117,31 +117,31 @@ namespace NBus { , MoreBytes(0) { } - + TRemoteConnection::TReaderData::~TReaderData() { Y_VERIFY(AtomicGet(Down)); } - + void TRemoteConnection::Send(TNonDestroyingAutoPtr<TBusMessage> msg) { BeforeSendQueue.Enqueue(msg.Release()); AtomicIncrement(WriterData.InFlight); ScheduleWrite(); } - + void TRemoteConnection::ClearOutgoingQueue(TMessagesPtrs& result, bool reconnect) { if (!reconnect) { // Do not clear send queue if reconnecting WriterData.SendQueue.Clear(&result); } } - + void TRemoteConnection::Shutdown(EMessageStatus status) { ScheduleShutdown(status); ReaderData.ShutdownComplete.WaitI(); WriterData.ShutdownComplete.WaitI(); } - + void TRemoteConnection::TryConnect() { Y_FAIL("TryConnect is client connection only operation"); } @@ -158,27 +158,27 @@ namespace NBus { if (!WriterData.TimeToRotateCounters.FetchTask()) { return; } - + WriterData.Status.DurationCounterPrev = WriterData.Status.DurationCounter; Reset(WriterData.Status.DurationCounter); } - + void TRemoteConnection::WriterSendStatus(TInstant now, bool force) { GranStatus.Writer.Update(std::bind(&TRemoteConnection::WriterGetStatus, this), now, force); } - + void TRemoteConnection::ReaderSendStatus(TInstant now, bool force) { GranStatus.Reader.Update(std::bind(&TRemoteConnection::ReaderFillStatus, this), now, force); } - + const TRemoteConnectionReaderStatus& TRemoteConnection::ReaderFillStatus() { ReaderData.Status.BufferSize = ReaderData.Buffer.Capacity(); ReaderData.Status.QuotaMsg = QuotaMsg.Tokens(); ReaderData.Status.QuotaBytes = QuotaBytes.Tokens(); - + return ReaderData.Status; } - + void TRemoteConnection::ProcessItem(TReaderTag, ::NActor::TDefaultTag, TWriterToReaderSocketMessage readSocket) { if (AtomicGet(ReaderData.Down)) { ReaderData.Status.Fd = INVALID_SOCKET; @@ -189,48 +189,48 @@ namespace NBus { ReaderData.Status.Fd = readSocket.Socket; ReaderData.SocketVersion = readSocket.SocketVersion; - + if (readSocket.Socket != INVALID_SOCKET) { ReaderData.SetChannel(Session->ReadEventLoop.Register(readSocket.Socket, this, ReadCookie)); ReaderData.Channel->EnableRead(); } } - + void TRemoteConnection::ProcessItem(TWriterTag, TReconnectTag, ui32 socketVersion) { Y_VERIFY(socketVersion <= WriterData.SocketVersion, "something weird"); - + if (WriterData.SocketVersion != socketVersion) { return; } Y_VERIFY(WriterData.Status.Connected, "must be connected at this point"); Y_VERIFY(!!WriterData.Channel, "must have channel at this point"); - + WriterData.Status.Connected = false; WriterData.DropChannel(); WriterData.Status.MyAddr = TNetAddr(); ++WriterData.SocketVersion; LastConnectAttempt = TInstant(); - + TMessagesPtrs cleared; ClearOutgoingQueue(cleared, true); WriterErrorMessages(cleared, MESSAGE_DELIVERY_FAILED); - + FireClientConnectionEvent(TClientConnectionEvent::DISCONNECTED); - + ReaderGetSocketQueue()->EnqueueAndSchedule(TWriterToReaderSocketMessage(INVALID_SOCKET, WriterData.SocketVersion)); } - + void TRemoteConnection::ProcessItem(TWriterTag, TWakeReaderTag, ui32 awakeFlags) { WriterData.AwakeFlags |= awakeFlags; - + ReadQuotaWakeup(); } - + void TRemoteConnection::Act(TReaderTag) { TInstant now = TInstant::Now(); - + ReaderData.Status.Acts += 1; - + ReaderGetSocketQueue()->DequeueAllLikelyEmpty(); if (AtomicGet(ReaderData.Down)) { @@ -238,41 +238,41 @@ namespace NBus { ReaderProcessStatusDown(); ReaderData.ShutdownComplete.Signal(); - + } else if (!!ReaderData.Channel) { Y_ASSERT(ReaderData.ReadMessages.empty()); - + for (int i = 0;; ++i) { if (i == 100) { // perform other tasks GetReaderActor()->AddTaskFromActorLoop(); break; } - + if (NeedInterruptRead()) { ReaderData.Channel->EnableRead(); break; } - + if (!ReaderFillBuffer()) break; - + if (!ReaderProcessBuffer()) break; } - + ReaderFlushMessages(); } - + ReaderSendStatus(now); - } - + } + bool TRemoteConnection::QuotaAcquire(size_t msg, size_t bytes) { ui32 wakeFlags = 0; - + if (!QuotaMsg.Acquire(msg)) wakeFlags |= WAKE_QUOTA_MSG; - + else if (!QuotaBytes.Acquire(bytes)) wakeFlags |= WAKE_QUOTA_BYTES; @@ -380,7 +380,7 @@ namespace NBus { ReaderData.Buffer.ChopHead(ReaderData.Offset); ReaderData.Offset = 0; - + if (ReaderData.Buffer.Capacity() > MaxBufferSize && ReaderData.Buffer.Size() <= MaxBufferSize) { ReaderData.Status.Incremental.BufferDrops += 1; @@ -388,7 +388,7 @@ namespace NBus { // probably should use another constant temp.Reserve(Config.DefaultBufferSize); temp.Append(ReaderData.Buffer.Data(), ReaderData.Buffer.Size()); - + ReaderData.Buffer.Swap(temp); } @@ -398,14 +398,14 @@ namespace NBus { bool TRemoteConnection::ReaderFillBuffer() { if (!ReaderData.BufferMore()) return true; - + if (ReaderData.Buffer.Avail() == 0) { if (ReaderData.Buffer.Size() == 0) { ReaderData.Buffer.Reserve(Config.DefaultBufferSize); } else { ReaderData.Buffer.Reserve(ReaderData.Buffer.Size() * 2); } - } + } Y_ASSERT(ReaderData.Buffer.Avail() > 0); @@ -414,7 +414,7 @@ namespace NBus { TWhatThreadDoesPushPop pp("recv syscall"); bytes = SocketRecv(ReaderData.Channel->GetSocket(), TArrayRef<char>(ReaderData.Buffer.Pos(), ReaderData.Buffer.Avail())); } - + if (bytes < 0) { if (WouldBlock()) { ReaderData.Channel->EnableRead(); @@ -425,30 +425,30 @@ namespace NBus { return false; } } - + if (bytes == 0) { ReaderData.Channel->DisableRead(); // TODO: incorrect: it is possible that only input is shutdown, and output is available ScheduleShutdownOnServerOrReconnectOnClient(MESSAGE_DELIVERY_FAILED, false); return false; } - + ReaderData.Status.Incremental.NetworkOps += 1; - + ReaderData.Buffer.Advance(bytes); ReaderData.MoreBytes = 0; return true; } - + void TRemoteConnection::ClearBeforeSendQueue(EMessageStatus reason) { BeforeSendQueue.DequeueAll(std::bind(&TRemoteConnection::WriterBeforeWriteErrorMessage, this, std::placeholders::_1, reason)); } - + void TRemoteConnection::ClearReplyQueue(EMessageStatus reason) { TVectorSwaps<TBusMessagePtrAndHeader> replyQueueTemp; Y_ASSERT(replyQueueTemp.empty()); ReplyQueue.DequeueAllSingleConsumer(&replyQueueTemp); - + TVector<TBusMessage*> messages; for (TVectorSwaps<TBusMessagePtrAndHeader>::reverse_iterator message = replyQueueTemp.rbegin(); message != replyQueueTemp.rend(); ++message) { @@ -458,8 +458,8 @@ namespace NBus { WriterErrorMessages(messages, reason); replyQueueTemp.clear(); - } - + } + void TRemoteConnection::ProcessBeforeSendQueueMessage(TBusMessage* message, TInstant now) { // legacy clients expect this field to be set if (!Session->IsSource_) { @@ -482,7 +482,7 @@ namespace NBus { const TRemoteConnectionWriterStatus& TRemoteConnection::WriterGetStatus() { WriterRotateCounters(); WriterFillStatus(); - + return WriterData.Status; } @@ -496,40 +496,40 @@ namespace NBus { WriterData.Status.SendQueueSize = WriterData.SendQueue.Size(); WriterData.Status.State = WriterData.State; } - + void TRemoteConnection::WriterProcessStatusDown() { Session->GetDeadConnectionWriterStatusQueue()->EnqueueAndSchedule(WriterData.Status.Incremental); Reset(WriterData.Status.Incremental); } - + void TRemoteConnection::ReaderProcessStatusDown() { Session->GetDeadConnectionReaderStatusQueue()->EnqueueAndSchedule(ReaderData.Status.Incremental); Reset(ReaderData.Status.Incremental); } - + void TRemoteConnection::ProcessWriterDown() { if (!RemovedFromSession) { Session->GetRemoveConnectionQueue()->EnqueueAndSchedule(this); - + if (Session->IsSource_) { if (WriterData.Status.Connected) { FireClientConnectionEvent(TClientConnectionEvent::DISCONNECTED); } } - + LWPROBE(Disconnected, ToString(PeerAddr)); RemovedFromSession = true; } - + WriterData.DropChannel(); - + DropEnqueuedData(ShutdownReason, MESSAGE_SHUTDOWN); - + WriterProcessStatusDown(); - + WriterData.ShutdownComplete.Signal(); } - + void TRemoteConnection::DropEnqueuedData(EMessageStatus reason, EMessageStatus reasonForQueues) { ClearReplyQueue(reasonForQueues); ClearBeforeSendQueue(reasonForQueues); @@ -554,23 +554,23 @@ namespace NBus { void TRemoteConnection::BeforeTryWrite() { } - + void TRemoteConnection::Act(TWriterTag) { TInstant now = TInstant::Now(); - + WriterData.Status.Acts += 1; - + if (Y_UNLIKELY(AtomicGet(WriterData.Down))) { // dump status must work even if WriterDown WriterSendStatus(now, true); ProcessWriterDown(); return; - } - + } + ProcessBeforeSendQueue(now); - + BeforeTryWrite(); - + WriterFillInFlight(); WriterGetReconnectQueue()->DequeueAllLikelyEmpty(); @@ -587,43 +587,43 @@ namespace NBus { if (WriterData.State == WRITER_FILLING) { WriterFillBuffer(); - + if (WriterData.State == WRITER_FILLING) { WriterData.Channel->DisableWrite(); break; } - + Y_ASSERT(!WriterData.Buffer.Empty()); } - + if (WriterData.State == WRITER_FLUSHING) { WriterFlushBuffer(); - + if (WriterData.State == WRITER_FLUSHING) { break; } } } } - + WriterGetWakeQueue()->DequeueAllLikelyEmpty(); - + WriterSendStatus(now); } - + void TRemoteConnection::WriterFlushBuffer() { Y_ASSERT(WriterData.State == WRITER_FLUSHING); Y_ASSERT(!WriterData.Buffer.Empty()); - + WriterData.CorkUntil = TInstant::Zero(); - + while (!WriterData.Buffer.Empty()) { ssize_t bytes; { TWhatThreadDoesPushPop pp("send syscall"); bytes = SocketSend(WriterData.Channel->GetSocket(), TArrayRef<const char>(WriterData.Buffer.LeftPos(), WriterData.Buffer.Size())); } - + if (bytes < 0) { if (WouldBlock()) { WriterData.Channel->EnableWrite(); @@ -634,18 +634,18 @@ namespace NBus { return; } } - + WriterData.Status.Incremental.NetworkOps += 1; - + WriterData.Buffer.LeftProceed(bytes); } - + WriterData.Buffer.Clear(); if (WriterData.Buffer.Capacity() > MaxBufferSize) { WriterData.Status.Incremental.BufferDrops += 1; WriterData.Buffer.Reset(); } - + WriterData.State = WRITER_FILLING; } @@ -655,8 +655,8 @@ namespace NBus { } else { ScheduleShutdown(status); } - } - + } + void TRemoteConnection::ScheduleShutdown(EMessageStatus status) { ShutdownReason = status; @@ -673,20 +673,20 @@ namespace NBus { Y_VERIFY(buffer.Size() >= posForAssertion, "incorrect Serialize implementation, pos before serialize: %d, pos after serialize: %d", int(posForAssertion), int(buffer.Size())); - } - + } + namespace { inline void WriteHeader(const TBusHeader& header, TBuffer& data) { data.Reserve(data.Size() + sizeof(TBusHeader)); /// \todo hton instead of memcpy memcpy(data.Data() + data.Size(), &header, sizeof(TBusHeader)); data.Advance(sizeof(TBusHeader)); - } - + } + inline void WriteDummyHeader(TBuffer& data) { data.Resize(data.Size() + sizeof(TBusHeader)); } - + } void TRemoteConnection::SerializeMessage(TBusMessage* msg, TBuffer* data, TMessageCounter* counter) const { @@ -695,17 +695,17 @@ namespace NBus { size_t dataSize; bool compressionRequested = msg->IsCompressed(); - + if (compressionRequested) { TBuffer compdata; TBuffer plaindata; CallSerialize(msg, plaindata); - + dataSize = sizeof(TBusHeader) + plaindata.Size(); - + NCodecs::TCodecPtr c = Proto->GetTransportCodec(); c->Encode(TStringBuf{plaindata.data(), plaindata.size()}, compdata); - + if (compdata.Size() < plaindata.Size()) { plaindata.Clear(); msg->GetHeader()->Size = sizeof(TBusHeader) + compdata.Size(); @@ -721,21 +721,21 @@ namespace NBus { } else { WriteDummyHeader(*data); CallSerialize(msg, *data); - + dataSize = msg->GetHeader()->Size = data->Size() - pos; - + data->Proceed(pos); WriteHeader(*msg->GetHeader(), *data); data->Proceed(pos + msg->GetHeader()->Size); } - + Y_ASSERT(msg->GetHeader()->Size == data->Size() - pos); counter->AddMessage(dataSize, data->Size() - pos, msg->IsCompressed(), compressionRequested); } - + TBusMessage* TRemoteConnection::DeserializeMessage(TArrayRef<const char> dataRef, const TBusHeader* header, TMessageCounter* messageCounter, EMessageStatus* status) const { size_t dataSize; - + TBusMessage* message; if (header->FlagsInternal & MESSAGE_COMPRESS_INTERNAL) { TBuffer msg; @@ -751,7 +751,7 @@ namespace NBus { *status = MESSAGE_DECOMPRESS_ERROR; return nullptr; } - + msg.Append(dataRef.data(), sizeof(TBusHeader)); msg.Append(plaindata.Data(), plaindata.Size()); } @@ -774,39 +774,39 @@ namespace NBus { } *message->GetHeader() = *header; } - + messageCounter->AddMessage(dataSize, dataRef.size(), header->FlagsInternal & MESSAGE_COMPRESS_INTERNAL, false); - + return message; } - + void TRemoteConnection::ResetOneWayFlag(TArrayRef<TBusMessage*> messages) { for (auto message : messages) { message->LocalFlags &= ~MESSAGE_ONE_WAY_INTERNAL; } - } - + } + void TRemoteConnection::ReaderFlushMessages() { if (!ReaderData.ReadMessages.empty()) { Session->OnMessageReceived(this, ReaderData.ReadMessages); ReaderData.ReadMessages.clear(); - } - } - + } + } + // @return false if actor should break bool TRemoteConnection::MessageRead(TArrayRef<const char> readDataRef, TInstant now) { TBusHeader header(readDataRef); - + Y_ASSERT(readDataRef.size() == header.Size); - + if (header.GetVersionInternal() != YBUS_VERSION) { ReaderProcessMessageUnknownVersion(readDataRef); return true; } - + EMessageStatus deserializeFailureStatus = MESSAGE_OK; TBusMessage* r = DeserializeMessage(readDataRef, &header, &ReaderData.Status.Incremental.MessageCounter, &deserializeFailureStatus); - + if (!r) { Y_VERIFY(deserializeFailureStatus != MESSAGE_OK, "state check"); LWPROBE(Error, ToString(deserializeFailureStatus), ToString(PeerAddr), ""); @@ -814,16 +814,16 @@ namespace NBus { ScheduleShutdownOnServerOrReconnectOnClient(deserializeFailureStatus, false); return false; } - + LWPROBE(Read, r->GetHeader()->Size); - + r->ReplyTo = PeerAddrSocketAddr; - + TBusMessagePtrAndHeader h(r); r->RecvTime = now; QuotaConsume(1, header.Size); - + ReaderData.ReadMessages.push_back(h); if (ReaderData.ReadMessages.size() >= 100) { ReaderFlushMessages(); @@ -831,12 +831,12 @@ namespace NBus { return true; } - + void TRemoteConnection::WriterFillBuffer() { Y_ASSERT(WriterData.State == WRITER_FILLING); Y_ASSERT(WriterData.Buffer.LeftSize() == 0); - + if (Y_UNLIKELY(!WrongVersionRequests.IsEmpty())) { TVector<TBusHeader> headers; WrongVersionRequests.DequeueAllSingleConsumer(&headers); @@ -849,12 +849,12 @@ namespace NBus { response.SetVersionInternal(YBUS_VERSION); WriteHeader(response, WriterData.Buffer.GetBuffer()); } - + Y_ASSERT(!WriterData.Buffer.Empty()); WriterData.State = WRITER_FLUSHING; return; } - + TTempTlsVector<TBusMessagePtrAndHeader, void, TVectorSwaps> writeMessages; for (;;) { @@ -862,7 +862,7 @@ namespace NBus { if (!writeMessage) { break; } - + if (Config.Cork != TDuration::Zero()) { if (WriterData.CorkUntil == TInstant::Zero()) { WriterData.CorkUntil = TInstant::Now() + Config.Cork; @@ -870,29 +870,29 @@ namespace NBus { } size_t sizeBeforeSerialize = WriterData.Buffer.Size(); - + TMessageCounter messageCounter = WriterData.Status.Incremental.MessageCounter; - + SerializeMessage(writeMessage.Get(), &WriterData.Buffer.GetBuffer(), &messageCounter); - + size_t written = WriterData.Buffer.Size() - sizeBeforeSerialize; if (written > Config.MaxMessageSize) { WriterData.Buffer.GetBuffer().EraseBack(written); WriterBeforeWriteErrorMessage(writeMessage.Release(), MESSAGE_MESSAGE_TOO_LARGE); continue; } - + WriterData.Status.Incremental.MessageCounter = messageCounter; - + TBusMessagePtrAndHeader h(writeMessage.Release()); writeMessages.GetVector()->push_back(h); - + Y_ASSERT(!WriterData.Buffer.Empty()); if (WriterData.Buffer.Size() >= Config.SendThreshold) { break; } - } - + } + if (!WriterData.Buffer.Empty()) { if (WriterData.Buffer.Size() >= Config.SendThreshold) { WriterData.State = WRITER_FLUSHING; @@ -909,31 +909,31 @@ namespace NBus { // keep filling Y_ASSERT(WriterData.State == WRITER_FILLING); } - + size_t bytes = MessageSize(*writeMessages.GetVector()); - + QuotaReturnSelf(writeMessages.GetVector()->size(), bytes); - + // This is called before `send` syscall inducing latency MessageSent(*writeMessages.GetVector()); - } - + } + size_t TRemoteConnection::MessageSize(TArrayRef<TBusMessagePtrAndHeader> messages) { size_t size = 0; for (const auto& message : messages) size += message.MessagePtr->RequestSize; - + return size; } - + size_t TRemoteConnection::GetInFlight() { return AtomicGet(WriterData.InFlight); - } - + } + size_t TRemoteConnection::GetConnectSyscallsNumForTest() { return WriterData.Status.ConnectSyscalls; - } - + } + void TRemoteConnection::WriterBeforeWriteErrorMessage(TBusMessage* message, EMessageStatus status) { if (Session->IsSource_) { CheckedCast<TRemoteClientSession*>(Session.Get())->ReleaseInFlight({message}); @@ -970,5 +970,5 @@ namespace NBus { return !AtomicGet(WriterData.Down); } - } -} + } +} diff --git a/library/cpp/messagebus/remote_connection.h b/library/cpp/messagebus/remote_connection.h index 5481b2c6ed..4538947368 100644 --- a/library/cpp/messagebus/remote_connection.h +++ b/library/cpp/messagebus/remote_connection.h @@ -1,17 +1,17 @@ #pragma once -#include "async_result.h" +#include "async_result.h" #include "defs.h" #include "event_loop.h" #include "left_right_buffer.h" #include "lfqueue_batch.h" #include "message_ptr_and_header.h" -#include "nondestroying_holder.h" -#include "remote_connection_status.h" -#include "scheduler_actor.h" -#include "socket_addr.h" +#include "nondestroying_holder.h" +#include "remote_connection_status.h" +#include "scheduler_actor.h" +#include "socket_addr.h" #include "storage.h" -#include "vector_swaps.h" +#include "vector_swaps.h" #include "ybus.h" #include "misc/granup.h" #include "misc/tokenquota.h" @@ -29,23 +29,23 @@ namespace NBus { namespace NPrivate { class TRemoteConnection; - + typedef TIntrusivePtr<TRemoteConnection> TRemoteConnectionPtr; typedef TIntrusivePtr<TBusSessionImpl> TRemoteSessionPtr; - + static void* const WriteCookie = (void*)1; static void* const ReadCookie = (void*)2; - + enum { WAKE_QUOTA_MSG = 0x01, WAKE_QUOTA_BYTES = 0x02 }; - + struct TWriterTag {}; struct TReaderTag {}; struct TReconnectTag {}; struct TWakeReaderTag {}; - + struct TWriterToReaderSocketMessage { TSocket Socket; ui32 SocketVersion; @@ -56,7 +56,7 @@ namespace NBus { { } }; - + class TRemoteConnection : public NEventLoop::IEventHandler, public ::NActor::TActor<TRemoteConnection, TWriterTag>, @@ -71,43 +71,43 @@ namespace NBus { friend class ::NActor::TQueueInActor<TRemoteConnection, TWriterToReaderSocketMessage, TReaderTag>; friend class ::NActor::TQueueInActor<TRemoteConnection, ui32, TWriterTag, TReconnectTag>; friend class ::NActor::TQueueInActor<TRemoteConnection, ui32, TWriterTag, TWakeReaderTag>; - + protected: ::NActor::TQueueInActor<TRemoteConnection, TWriterToReaderSocketMessage, TReaderTag>* ReaderGetSocketQueue() { return this; } - + ::NActor::TQueueInActor<TRemoteConnection, ui32, TWriterTag, TReconnectTag>* WriterGetReconnectQueue() { return this; } - + ::NActor::TQueueInActor<TRemoteConnection, ui32, TWriterTag, TWakeReaderTag>* WriterGetWakeQueue() { return this; } - + protected: TRemoteConnection(TRemoteSessionPtr session, ui64 connectionId, TNetAddr addr); ~TRemoteConnection() override; - + virtual void ClearOutgoingQueue(TMessagesPtrs&, bool reconnect /* or shutdown */); - + public: void Send(TNonDestroyingAutoPtr<TBusMessage> msg); void Shutdown(EMessageStatus status); - + inline const TNetAddr& GetAddr() const noexcept; private: friend class TScheduleConnect; friend class TWorkIO; - + protected: static size_t MessageSize(TArrayRef<TBusMessagePtrAndHeader>); bool QuotaAcquire(size_t msg, size_t bytes); void QuotaConsume(size_t msg, size_t bytes); void QuotaReturnSelf(size_t items, size_t bytes); bool QuotaReturnValues(size_t items, size_t bytes); - + bool ReaderProcessBuffer(); bool ReaderFillBuffer(); void ReaderFlushMessages(); @@ -170,22 +170,22 @@ namespace NBus { inline TScheduleActor<TRemoteConnection, TWriterTag>* GetWriterSchedulerActor() { return this; } - + void WriterErrorMessage(TNonDestroyingAutoPtr<TBusMessage> m, EMessageStatus status); // takes ownership of ms void WriterErrorMessages(const TArrayRef<TBusMessage*> ms, EMessageStatus status); void FireClientConnectionEvent(TClientConnectionEvent::EType); - + size_t GetInFlight(); size_t GetConnectSyscallsNumForTest(); - + bool IsReturnConnectFailedImmediately() { return (bool)AtomicGet(ReturnConnectFailedImmediately); } - + bool IsAlive() const; - + TRemoteSessionPtr Session; TBusProtocol* const Proto; TBusSessionConfig const Config; @@ -193,15 +193,15 @@ namespace NBus { const ui64 ConnectionId; const TNetAddr PeerAddr; const TBusSocketAddr PeerAddrSocketAddr; - + const TInstant CreatedTime; TInstant LastConnectAttempt; TAtomic ReturnConnectFailedImmediately; - + protected: ::NActor::TQueueForActor<TBusMessage*> BeforeSendQueue; TLockFreeStack<TBusHeader> WrongVersionRequests; - + struct TWriterData { TAtomic Down; @@ -212,7 +212,7 @@ namespace NBus { TInstant StatusLastSendTime; TLocalTasks TimeToRotateCounters; - + TAtomic InFlight; TTimedMessages SendQueue; @@ -220,44 +220,44 @@ namespace NBus { EWriterState State; TLeftRightBuffer Buffer; TInstant CorkUntil; - + TSystemEvent ShutdownComplete; - + void SetChannel(NEventLoop::TChannelPtr channel); void DropChannel(); - + TWriterData(); ~TWriterData(); }; - + struct TReaderData { TAtomic Down; - + NEventLoop::TChannelPtr Channel; ui32 SocketVersion; - + TRemoteConnectionReaderStatus Status; TInstant StatusLastSendTime; - + TBuffer Buffer; size_t Offset; /* offset in read buffer */ size_t MoreBytes; /* more bytes required from socket */ TVectorSwaps<TBusMessagePtrAndHeader> ReadMessages; - + TSystemEvent ShutdownComplete; - + bool BufferMore() const noexcept { return MoreBytes > 0; } - + bool HasBytesInBuf(size_t bytes) noexcept; void SetChannel(NEventLoop::TChannelPtr channel); void DropChannel(); - + TReaderData(); ~TReaderData(); }; - + // owned by session status actor struct TGranStatus { TGranStatus(TDuration gran) @@ -265,7 +265,7 @@ namespace NBus { , Reader(gran) { } - + TGranUp<TRemoteConnectionWriterStatus> Writer; TGranUp<TRemoteConnectionReaderStatus> Reader; }; @@ -275,15 +275,15 @@ namespace NBus { TGranStatus GranStatus; TTokenQuota QuotaMsg; TTokenQuota QuotaBytes; - + size_t MaxBufferSize; - + // client connection only TLockFreeQueueBatch<TBusMessagePtrAndHeader, TVectorSwaps> ReplyQueue; EMessageStatus ShutdownReason; - }; - + }; + inline const TNetAddr& TRemoteConnection::GetAddr() const noexcept { return PeerAddr; } diff --git a/library/cpp/messagebus/remote_connection_status.cpp b/library/cpp/messagebus/remote_connection_status.cpp index 0a1706ae31..2c48b2a287 100644 --- a/library/cpp/messagebus/remote_connection_status.cpp +++ b/library/cpp/messagebus/remote_connection_status.cpp @@ -1,133 +1,133 @@ #include "remote_connection_status.h" - -#include "key_value_printer.h" - + +#include "key_value_printer.h" + #include <library/cpp/messagebus/monitoring/mon_proto.pb.h> #include <util/stream/format.h> #include <util/stream/output.h> #include <util/system/yassert.h> -using namespace NBus; -using namespace NBus::NPrivate; - -template <typename T> -static void Add(T& thiz, const T& that) { - thiz += that; -} - -template <typename T> -static void Max(T& thiz, const T& that) { - if (that > thiz) { - thiz = that; - } -} - -template <typename T> -static void AssertZero(T& thiz, const T& that) { +using namespace NBus; +using namespace NBus::NPrivate; + +template <typename T> +static void Add(T& thiz, const T& that) { + thiz += that; +} + +template <typename T> +static void Max(T& thiz, const T& that) { + if (that > thiz) { + thiz = that; + } +} + +template <typename T> +static void AssertZero(T& thiz, const T& that) { Y_ASSERT(thiz == T()); Y_UNUSED(that); -} - -TDurationCounter::TDurationCounter() - : DURATION_COUNTER_MAP(STRUCT_FIELD_INIT_DEFAULT, COMMA) -{ -} - -TDuration TDurationCounter::AvgDuration() const { - if (Count == 0) { - return TDuration::Zero(); - } else { - return SumDuration / Count; - } -} - -TDurationCounter& TDurationCounter::operator+=(const TDurationCounter& that) { - DURATION_COUNTER_MAP(STRUCT_FIELD_ADD, ) - return *this; -} - +} + +TDurationCounter::TDurationCounter() + : DURATION_COUNTER_MAP(STRUCT_FIELD_INIT_DEFAULT, COMMA) +{ +} + +TDuration TDurationCounter::AvgDuration() const { + if (Count == 0) { + return TDuration::Zero(); + } else { + return SumDuration / Count; + } +} + +TDurationCounter& TDurationCounter::operator+=(const TDurationCounter& that) { + DURATION_COUNTER_MAP(STRUCT_FIELD_ADD, ) + return *this; +} + TString TDurationCounter::ToString() const { - if (Count == 0) { - return "0"; - } else { - TStringStream ss; - ss << "avg: " << AvgDuration() << ", max: " << MaxDuration << ", count: " << Count; - return ss.Str(); - } -} - -TRemoteConnectionStatusBase::TRemoteConnectionStatusBase() - : REMOTE_CONNECTION_STATUS_BASE_MAP(STRUCT_FIELD_INIT_DEFAULT, COMMA) -{ -} - + if (Count == 0) { + return "0"; + } else { + TStringStream ss; + ss << "avg: " << AvgDuration() << ", max: " << MaxDuration << ", count: " << Count; + return ss.Str(); + } +} + +TRemoteConnectionStatusBase::TRemoteConnectionStatusBase() + : REMOTE_CONNECTION_STATUS_BASE_MAP(STRUCT_FIELD_INIT_DEFAULT, COMMA) +{ +} + TRemoteConnectionStatusBase& TRemoteConnectionStatusBase ::operator+=(const TRemoteConnectionStatusBase& that) { - REMOTE_CONNECTION_STATUS_BASE_MAP(STRUCT_FIELD_ADD, ) - return *this; -} - -TRemoteConnectionIncrementalStatusBase::TRemoteConnectionIncrementalStatusBase() - : REMOTE_CONNECTION_INCREMENTAL_STATUS_BASE_MAP(STRUCT_FIELD_INIT_DEFAULT, COMMA) -{ -} - + REMOTE_CONNECTION_STATUS_BASE_MAP(STRUCT_FIELD_ADD, ) + return *this; +} + +TRemoteConnectionIncrementalStatusBase::TRemoteConnectionIncrementalStatusBase() + : REMOTE_CONNECTION_INCREMENTAL_STATUS_BASE_MAP(STRUCT_FIELD_INIT_DEFAULT, COMMA) +{ +} + TRemoteConnectionIncrementalStatusBase& TRemoteConnectionIncrementalStatusBase::operator+=( const TRemoteConnectionIncrementalStatusBase& that) { - REMOTE_CONNECTION_INCREMENTAL_STATUS_BASE_MAP(STRUCT_FIELD_ADD, ) - return *this; -} - -TRemoteConnectionReaderIncrementalStatus::TRemoteConnectionReaderIncrementalStatus() - : REMOTE_CONNECTION_READER_INCREMENTAL_STATUS_MAP(STRUCT_FIELD_INIT_DEFAULT, COMMA) -{ -} - -TRemoteConnectionReaderIncrementalStatus& TRemoteConnectionReaderIncrementalStatus::operator+=( + REMOTE_CONNECTION_INCREMENTAL_STATUS_BASE_MAP(STRUCT_FIELD_ADD, ) + return *this; +} + +TRemoteConnectionReaderIncrementalStatus::TRemoteConnectionReaderIncrementalStatus() + : REMOTE_CONNECTION_READER_INCREMENTAL_STATUS_MAP(STRUCT_FIELD_INIT_DEFAULT, COMMA) +{ +} + +TRemoteConnectionReaderIncrementalStatus& TRemoteConnectionReaderIncrementalStatus::operator+=( const TRemoteConnectionReaderIncrementalStatus& that) { TRemoteConnectionIncrementalStatusBase::operator+=(that); - REMOTE_CONNECTION_READER_INCREMENTAL_STATUS_MAP(STRUCT_FIELD_ADD, ) - return *this; -} - -TRemoteConnectionReaderStatus::TRemoteConnectionReaderStatus() - : REMOTE_CONNECTION_READER_STATUS_MAP(STRUCT_FIELD_INIT_DEFAULT, COMMA) -{ -} - -TRemoteConnectionReaderStatus& TRemoteConnectionReaderStatus::operator+=(const TRemoteConnectionReaderStatus& that) { + REMOTE_CONNECTION_READER_INCREMENTAL_STATUS_MAP(STRUCT_FIELD_ADD, ) + return *this; +} + +TRemoteConnectionReaderStatus::TRemoteConnectionReaderStatus() + : REMOTE_CONNECTION_READER_STATUS_MAP(STRUCT_FIELD_INIT_DEFAULT, COMMA) +{ +} + +TRemoteConnectionReaderStatus& TRemoteConnectionReaderStatus::operator+=(const TRemoteConnectionReaderStatus& that) { TRemoteConnectionStatusBase::operator+=(that); - REMOTE_CONNECTION_READER_STATUS_MAP(STRUCT_FIELD_ADD, ) - return *this; -} - -TRemoteConnectionWriterIncrementalStatus::TRemoteConnectionWriterIncrementalStatus() - : REMOTE_CONNECTION_WRITER_INCREMENTAL_STATUS(STRUCT_FIELD_INIT_DEFAULT, COMMA) -{ -} - -TRemoteConnectionWriterIncrementalStatus& TRemoteConnectionWriterIncrementalStatus::operator+=( + REMOTE_CONNECTION_READER_STATUS_MAP(STRUCT_FIELD_ADD, ) + return *this; +} + +TRemoteConnectionWriterIncrementalStatus::TRemoteConnectionWriterIncrementalStatus() + : REMOTE_CONNECTION_WRITER_INCREMENTAL_STATUS(STRUCT_FIELD_INIT_DEFAULT, COMMA) +{ +} + +TRemoteConnectionWriterIncrementalStatus& TRemoteConnectionWriterIncrementalStatus::operator+=( const TRemoteConnectionWriterIncrementalStatus& that) { TRemoteConnectionIncrementalStatusBase::operator+=(that); - REMOTE_CONNECTION_WRITER_INCREMENTAL_STATUS(STRUCT_FIELD_ADD, ) - return *this; -} - -TRemoteConnectionWriterStatus::TRemoteConnectionWriterStatus() - : REMOTE_CONNECTION_WRITER_STATUS(STRUCT_FIELD_INIT_DEFAULT, COMMA) -{ -} - -TRemoteConnectionWriterStatus& TRemoteConnectionWriterStatus::operator+=(const TRemoteConnectionWriterStatus& that) { + REMOTE_CONNECTION_WRITER_INCREMENTAL_STATUS(STRUCT_FIELD_ADD, ) + return *this; +} + +TRemoteConnectionWriterStatus::TRemoteConnectionWriterStatus() + : REMOTE_CONNECTION_WRITER_STATUS(STRUCT_FIELD_INIT_DEFAULT, COMMA) +{ +} + +TRemoteConnectionWriterStatus& TRemoteConnectionWriterStatus::operator+=(const TRemoteConnectionWriterStatus& that) { TRemoteConnectionStatusBase::operator+=(that); - REMOTE_CONNECTION_WRITER_STATUS(STRUCT_FIELD_ADD, ) - return *this; -} - -size_t TRemoteConnectionWriterStatus::GetInFlight() const { - return SendQueueSize + AckMessagesSize; -} - + REMOTE_CONNECTION_WRITER_STATUS(STRUCT_FIELD_ADD, ) + return *this; +} + +size_t TRemoteConnectionWriterStatus::GetInFlight() const { + return SendQueueSize + AckMessagesSize; +} + TConnectionStatusMonRecord TRemoteConnectionStatus::GetStatusProtobuf() const { TConnectionStatusMonRecord status; @@ -155,31 +155,31 @@ TConnectionStatusMonRecord TRemoteConnectionStatus::GetStatusProtobuf() const { } TString TRemoteConnectionStatus::PrintToString() const { - TStringStream ss; - - TKeyValuePrinter p; - - if (!Summary) { - // TODO: print MyAddr too, but only if it is set - ss << WriterStatus.PeerAddr << " (" << WriterStatus.ConnectionId << ")" + TStringStream ss; + + TKeyValuePrinter p; + + if (!Summary) { + // TODO: print MyAddr too, but only if it is set + ss << WriterStatus.PeerAddr << " (" << WriterStatus.ConnectionId << ")" << ", writefd=" << WriterStatus.Fd << ", readfd=" << ReaderStatus.Fd << Endl; - if (WriterStatus.Connected) { - p.AddRow("connect time", WriterStatus.ConnectTime.ToString()); - p.AddRow("writer state", ToCString(WriterStatus.State)); - } else { - ss << "not connected"; - if (WriterStatus.ConnectError != 0) { - ss << ", last connect error: " << LastSystemErrorText(WriterStatus.ConnectError); - } - ss << Endl; - } - } - if (!Server) { - p.AddRow("connect syscalls", WriterStatus.ConnectSyscalls); - } - + if (WriterStatus.Connected) { + p.AddRow("connect time", WriterStatus.ConnectTime.ToString()); + p.AddRow("writer state", ToCString(WriterStatus.State)); + } else { + ss << "not connected"; + if (WriterStatus.ConnectError != 0) { + ss << ", last connect error: " << LastSystemErrorText(WriterStatus.ConnectError); + } + ss << Endl; + } + } + if (!Server) { + p.AddRow("connect syscalls", WriterStatus.ConnectSyscalls); + } + p.AddRow("send queue", LeftPad(WriterStatus.SendQueueSize, 6)); if (Server) { @@ -189,77 +189,77 @@ TString TRemoteConnectionStatus::PrintToString() const { p.AddRow("reader wakeups", LeftPad(WriterStatus.ReaderWakeups, 6)); } else { p.AddRow("ack messages", LeftPad(WriterStatus.AckMessagesSize, 6)); - } - - p.AddRow("written", WriterStatus.Incremental.MessageCounter.ToString(false)); - p.AddRow("read", ReaderStatus.Incremental.MessageCounter.ToString(true)); - - p.AddRow("write syscalls", LeftPad(WriterStatus.Incremental.NetworkOps, 12)); - p.AddRow("read syscalls", LeftPad(ReaderStatus.Incremental.NetworkOps, 12)); - - p.AddRow("write acts", LeftPad(WriterStatus.Acts, 12)); - p.AddRow("read acts", LeftPad(ReaderStatus.Acts, 12)); - - p.AddRow("write buffer cap", LeftPad(WriterStatus.BufferSize, 12)); - p.AddRow("read buffer cap", LeftPad(ReaderStatus.BufferSize, 12)); - - p.AddRow("write buffer drops", LeftPad(WriterStatus.Incremental.BufferDrops, 10)); - p.AddRow("read buffer drops", LeftPad(ReaderStatus.Incremental.BufferDrops, 10)); - - if (Server) { - p.AddRow("process dur", WriterStatus.DurationCounterPrev.ToString()); - } - - ss << p.PrintToString(); - - if (false && Server) { - ss << "time histogram:\n"; - ss << WriterStatus.Incremental.ProcessDurationHistogram.PrintToString(); - } - - TMessageStatusCounter sumStatusCounter; - sumStatusCounter += WriterStatus.Incremental.StatusCounter; - sumStatusCounter += ReaderStatus.Incremental.StatusCounter; - - ss << sumStatusCounter.PrintToString(); - - return ss.Str(); -} - -TRemoteConnectionStatus::TRemoteConnectionStatus() - : REMOTE_CONNECTION_STATUS_MAP(STRUCT_FIELD_INIT_DEFAULT, COMMA) -{ -} - + } + + p.AddRow("written", WriterStatus.Incremental.MessageCounter.ToString(false)); + p.AddRow("read", ReaderStatus.Incremental.MessageCounter.ToString(true)); + + p.AddRow("write syscalls", LeftPad(WriterStatus.Incremental.NetworkOps, 12)); + p.AddRow("read syscalls", LeftPad(ReaderStatus.Incremental.NetworkOps, 12)); + + p.AddRow("write acts", LeftPad(WriterStatus.Acts, 12)); + p.AddRow("read acts", LeftPad(ReaderStatus.Acts, 12)); + + p.AddRow("write buffer cap", LeftPad(WriterStatus.BufferSize, 12)); + p.AddRow("read buffer cap", LeftPad(ReaderStatus.BufferSize, 12)); + + p.AddRow("write buffer drops", LeftPad(WriterStatus.Incremental.BufferDrops, 10)); + p.AddRow("read buffer drops", LeftPad(ReaderStatus.Incremental.BufferDrops, 10)); + + if (Server) { + p.AddRow("process dur", WriterStatus.DurationCounterPrev.ToString()); + } + + ss << p.PrintToString(); + + if (false && Server) { + ss << "time histogram:\n"; + ss << WriterStatus.Incremental.ProcessDurationHistogram.PrintToString(); + } + + TMessageStatusCounter sumStatusCounter; + sumStatusCounter += WriterStatus.Incremental.StatusCounter; + sumStatusCounter += ReaderStatus.Incremental.StatusCounter; + + ss << sumStatusCounter.PrintToString(); + + return ss.Str(); +} + +TRemoteConnectionStatus::TRemoteConnectionStatus() + : REMOTE_CONNECTION_STATUS_MAP(STRUCT_FIELD_INIT_DEFAULT, COMMA) +{ +} + TString TSessionDumpStatus::PrintToString() const { - if (Shutdown) { - return "shutdown"; - } - - TStringStream ss; - ss << Head; - if (ConnectionStatusSummary.Server) { - ss << "\n"; - ss << Acceptors; - } - ss << "\n"; - ss << "connections summary:" << Endl; - ss << ConnectionsSummary; - if (!!Connections) { - ss << "\n"; - ss << Connections; - } - ss << "\n"; - ss << Config.PrintToString(); - return ss.Str(); -} - + if (Shutdown) { + return "shutdown"; + } + + TStringStream ss; + ss << Head; + if (ConnectionStatusSummary.Server) { + ss << "\n"; + ss << Acceptors; + } + ss << "\n"; + ss << "connections summary:" << Endl; + ss << ConnectionsSummary; + if (!!Connections) { + ss << "\n"; + ss << Connections; + } + ss << "\n"; + ss << Config.PrintToString(); + return ss.Str(); +} + TString TBusMessageQueueStatus::PrintToString() const { - TStringStream ss; - ss << "work queue:\n"; - ss << ExecutorStatus.Status; - ss << "\n"; - ss << "queue config:\n"; - ss << Config.PrintToString(); - return ss.Str(); -} + TStringStream ss; + ss << "work queue:\n"; + ss << ExecutorStatus.Status; + ss << "\n"; + ss << "queue config:\n"; + ss << Config.PrintToString(); + return ss.Str(); +} diff --git a/library/cpp/messagebus/remote_connection_status.h b/library/cpp/messagebus/remote_connection_status.h index 0431d7eb32..5db10e51ea 100644 --- a/library/cpp/messagebus/remote_connection_status.h +++ b/library/cpp/messagebus/remote_connection_status.h @@ -1,12 +1,12 @@ -#pragma once - -#include "codegen.h" +#pragma once + +#include "codegen.h" #include "duration_histogram.h" #include "message_counter.h" -#include "message_status_counter.h" -#include "queue_config.h" -#include "session_config.h" - +#include "message_status_counter.h" +#include "queue_config.h" +#include "session_config.h" + #include <library/cpp/messagebus/actor/executor.h> #include <library/cpp/deprecated/enum_codegen/enum_codegen.h> @@ -17,40 +17,40 @@ namespace NBus { namespace NBus { namespace NPrivate { -#define WRITER_STATE_MAP(XX) \ +#define WRITER_STATE_MAP(XX) \ XX(WRITER_UNKNOWN) \ XX(WRITER_FILLING) \ XX(WRITER_FLUSHING) \ - /**/ - + /**/ + // TODO: move elsewhere enum EWriterState { WRITER_STATE_MAP(ENUM_VALUE_GEN_NO_VALUE) }; - + ENUM_TO_STRING(EWriterState, WRITER_STATE_MAP) - -#define STRUCT_FIELD_ADD(name, type, func) func(name, that.name); - + +#define STRUCT_FIELD_ADD(name, type, func) func(name, that.name); + template <typename T> void Reset(T& t) { t.~T(); new (&t) T(); } - + #define DURATION_COUNTER_MAP(XX, comma) \ XX(Count, unsigned, Add) \ comma \ XX(SumDuration, TDuration, Add) comma \ XX(MaxDuration, TDuration, Max) /**/ - + struct TDurationCounter { DURATION_COUNTER_MAP(STRUCT_FIELD_GEN, ) - + TDuration AvgDuration() const; - + TDurationCounter(); - + void AddDuration(TDuration d) { Count += 1; SumDuration += d; @@ -58,82 +58,82 @@ namespace NBus { MaxDuration = d; } } - + TDurationCounter& operator+=(const TDurationCounter&); - + TString ToString() const; }; - -#define REMOTE_CONNECTION_STATUS_BASE_MAP(XX, comma) \ + +#define REMOTE_CONNECTION_STATUS_BASE_MAP(XX, comma) \ XX(ConnectionId, ui64, AssertZero) \ comma \ XX(Fd, SOCKET, AssertZero) comma \ XX(Acts, ui64, Add) comma \ XX(BufferSize, ui64, Add) /**/ - + struct TRemoteConnectionStatusBase { REMOTE_CONNECTION_STATUS_BASE_MAP(STRUCT_FIELD_GEN, ) - + TRemoteConnectionStatusBase& operator+=(const TRemoteConnectionStatusBase&); - + TRemoteConnectionStatusBase(); }; - -#define REMOTE_CONNECTION_INCREMENTAL_STATUS_BASE_MAP(XX, comma) \ + +#define REMOTE_CONNECTION_INCREMENTAL_STATUS_BASE_MAP(XX, comma) \ XX(BufferDrops, unsigned, Add) \ comma \ XX(NetworkOps, unsigned, Add) /**/ - + struct TRemoteConnectionIncrementalStatusBase { REMOTE_CONNECTION_INCREMENTAL_STATUS_BASE_MAP(STRUCT_FIELD_GEN, ) - + TRemoteConnectionIncrementalStatusBase& operator+=(const TRemoteConnectionIncrementalStatusBase&); - + TRemoteConnectionIncrementalStatusBase(); }; - -#define REMOTE_CONNECTION_READER_INCREMENTAL_STATUS_MAP(XX, comma) \ + +#define REMOTE_CONNECTION_READER_INCREMENTAL_STATUS_MAP(XX, comma) \ XX(MessageCounter, TMessageCounter, Add) \ comma \ XX(StatusCounter, TMessageStatusCounter, Add) /**/ - + struct TRemoteConnectionReaderIncrementalStatus: public TRemoteConnectionIncrementalStatusBase { REMOTE_CONNECTION_READER_INCREMENTAL_STATUS_MAP(STRUCT_FIELD_GEN, ) - + TRemoteConnectionReaderIncrementalStatus& operator+=(const TRemoteConnectionReaderIncrementalStatus&); - + TRemoteConnectionReaderIncrementalStatus(); }; - -#define REMOTE_CONNECTION_READER_STATUS_MAP(XX, comma) \ + +#define REMOTE_CONNECTION_READER_STATUS_MAP(XX, comma) \ XX(QuotaMsg, size_t, Add) \ comma \ XX(QuotaBytes, size_t, Add) comma \ XX(QuotaExhausted, size_t, Add) comma \ XX(Incremental, TRemoteConnectionReaderIncrementalStatus, Add) /**/ - + struct TRemoteConnectionReaderStatus: public TRemoteConnectionStatusBase { REMOTE_CONNECTION_READER_STATUS_MAP(STRUCT_FIELD_GEN, ) - + TRemoteConnectionReaderStatus& operator+=(const TRemoteConnectionReaderStatus&); - + TRemoteConnectionReaderStatus(); }; - -#define REMOTE_CONNECTION_WRITER_INCREMENTAL_STATUS(XX, comma) \ + +#define REMOTE_CONNECTION_WRITER_INCREMENTAL_STATUS(XX, comma) \ XX(MessageCounter, TMessageCounter, Add) \ comma \ XX(StatusCounter, TMessageStatusCounter, Add) comma \ XX(ProcessDurationHistogram, TDurationHistogram, Add) /**/ - + struct TRemoteConnectionWriterIncrementalStatus: public TRemoteConnectionIncrementalStatusBase { REMOTE_CONNECTION_WRITER_INCREMENTAL_STATUS(STRUCT_FIELD_GEN, ) - + TRemoteConnectionWriterIncrementalStatus& operator+=(const TRemoteConnectionWriterIncrementalStatus&); - + TRemoteConnectionWriterIncrementalStatus(); }; - + #define REMOTE_CONNECTION_WRITER_STATUS(XX, comma) \ XX(Connected, bool, AssertZero) \ comma \ @@ -149,42 +149,42 @@ namespace NBus { XX(DurationCounterPrev, TDurationCounter, Add) comma /* server only */ \ XX(Incremental, TRemoteConnectionWriterIncrementalStatus, Add) comma \ XX(ReaderWakeups, size_t, Add) /**/ - + struct TRemoteConnectionWriterStatus: public TRemoteConnectionStatusBase { REMOTE_CONNECTION_WRITER_STATUS(STRUCT_FIELD_GEN, ) - + TRemoteConnectionWriterStatus(); - + TRemoteConnectionWriterStatus& operator+=(const TRemoteConnectionWriterStatus&); - + size_t GetInFlight() const; }; - -#define REMOTE_CONNECTION_STATUS_MAP(XX, comma) \ + +#define REMOTE_CONNECTION_STATUS_MAP(XX, comma) \ XX(Summary, bool) \ comma \ XX(Server, bool) /**/ - + struct TRemoteConnectionStatus { REMOTE_CONNECTION_STATUS_MAP(STRUCT_FIELD_GEN, ) - + TRemoteConnectionReaderStatus ReaderStatus; TRemoteConnectionWriterStatus WriterStatus; - + TRemoteConnectionStatus(); - + TString PrintToString() const; TConnectionStatusMonRecord GetStatusProtobuf() const; }; - + struct TBusSessionStatus { size_t InFlightCount; size_t InFlightSize; bool InputPaused; - + TBusSessionStatus(); }; - + struct TSessionDumpStatus { bool Shutdown; TString Head; @@ -194,20 +194,20 @@ namespace NBus { TBusSessionStatus Status; TRemoteConnectionStatus ConnectionStatusSummary; TBusSessionConfig Config; - + TSessionDumpStatus() : Shutdown(false) { } - + TString PrintToString() const; }; - + // without sessions struct TBusMessageQueueStatus { NActor::NPrivate::TExecutorStatus ExecutorStatus; TBusQueueConfig Config; - + TString PrintToString() const; }; } diff --git a/library/cpp/messagebus/remote_server_connection.cpp b/library/cpp/messagebus/remote_server_connection.cpp index 9af7fb2185..74be34ded9 100644 --- a/library/cpp/messagebus/remote_server_connection.cpp +++ b/library/cpp/messagebus/remote_server_connection.cpp @@ -1,73 +1,73 @@ -#include "remote_server_connection.h" - +#include "remote_server_connection.h" + #include "mb_lwtrace.h" -#include "remote_server_session.h" - +#include "remote_server_session.h" + #include <util/generic/cast.h> - -LWTRACE_USING(LWTRACE_MESSAGEBUS_PROVIDER) - -using namespace NBus; -using namespace NBus::NPrivate; - -TRemoteServerConnection::TRemoteServerConnection(TRemoteServerSessionPtr session, ui64 id, TNetAddr addr) - : TRemoteConnection(session.Get(), id, addr) -{ -} - + +LWTRACE_USING(LWTRACE_MESSAGEBUS_PROVIDER) + +using namespace NBus; +using namespace NBus::NPrivate; + +TRemoteServerConnection::TRemoteServerConnection(TRemoteServerSessionPtr session, ui64 id, TNetAddr addr) + : TRemoteConnection(session.Get(), id, addr) +{ +} + void TRemoteServerConnection::Init(SOCKET socket, TInstant now) { - WriterData.Status.ConnectTime = now; - WriterData.Status.Connected = true; - + WriterData.Status.ConnectTime = now; + WriterData.Status.Connected = true; + Y_VERIFY(socket != INVALID_SOCKET, "must be a valid socket"); - - TSocket readSocket(socket); - TSocket writeSocket = readSocket; - - // this must not be done in constructor, because if event loop is stopped, - // this is deleted - WriterData.SetChannel(Session->WriteEventLoop.Register(writeSocket, this, WriteCookie)); - WriterData.SocketVersion = 1; - - ReaderGetSocketQueue()->EnqueueAndSchedule(TWriterToReaderSocketMessage(readSocket, WriterData.SocketVersion)); -} - -TRemoteServerSession* TRemoteServerConnection::GetSession() { - return CheckedCast<TRemoteServerSession*>(Session.Get()); -} - -void TRemoteServerConnection::HandleEvent(SOCKET socket, void* cookie) { + + TSocket readSocket(socket); + TSocket writeSocket = readSocket; + + // this must not be done in constructor, because if event loop is stopped, + // this is deleted + WriterData.SetChannel(Session->WriteEventLoop.Register(writeSocket, this, WriteCookie)); + WriterData.SocketVersion = 1; + + ReaderGetSocketQueue()->EnqueueAndSchedule(TWriterToReaderSocketMessage(readSocket, WriterData.SocketVersion)); +} + +TRemoteServerSession* TRemoteServerConnection::GetSession() { + return CheckedCast<TRemoteServerSession*>(Session.Get()); +} + +void TRemoteServerConnection::HandleEvent(SOCKET socket, void* cookie) { Y_UNUSED(socket); Y_ASSERT(cookie == ReadCookie || cookie == WriteCookie); - if (cookie == ReadCookie) { - GetSession()->ServerOwnedMessages.Wait(); - ScheduleRead(); - } else { - ScheduleWrite(); - } -} - -bool TRemoteServerConnection::NeedInterruptRead() { - return !GetSession()->ServerOwnedMessages.TryWait(); -} - + if (cookie == ReadCookie) { + GetSession()->ServerOwnedMessages.Wait(); + ScheduleRead(); + } else { + ScheduleWrite(); + } +} + +bool TRemoteServerConnection::NeedInterruptRead() { + return !GetSession()->ServerOwnedMessages.TryWait(); +} + void TRemoteServerConnection::MessageSent(TArrayRef<TBusMessagePtrAndHeader> messages) { - TInstant now = TInstant::Now(); - - GetSession()->ReleaseInWorkResponses(messages); + TInstant now = TInstant::Now(); + + GetSession()->ReleaseInWorkResponses(messages); for (auto& message : messages) { TInstant recvTime = message.MessagePtr->RecvTime; GetSession()->ServerHandler->OnSent(message.MessagePtr.Release()); - TDuration d = now - recvTime; - WriterData.Status.DurationCounter.AddDuration(d); - WriterData.Status.Incremental.ProcessDurationHistogram.AddTime(d); - } -} - + TDuration d = now - recvTime; + WriterData.Status.DurationCounter.AddDuration(d); + WriterData.Status.Incremental.ProcessDurationHistogram.AddTime(d); + } +} + void TRemoteServerConnection::ReaderProcessMessageUnknownVersion(TArrayRef<const char> dataRef) { - TBusHeader header(dataRef); - // TODO: full version hex - LWPROBE(ServerUnknownVersion, ToString(PeerAddr), header.GetVersionInternal()); - WrongVersionRequests.Enqueue(header); - GetWriterActor()->Schedule(); -} + TBusHeader header(dataRef); + // TODO: full version hex + LWPROBE(ServerUnknownVersion, ToString(PeerAddr), header.GetVersionInternal()); + WrongVersionRequests.Enqueue(header); + GetWriterActor()->Schedule(); +} diff --git a/library/cpp/messagebus/remote_server_connection.h b/library/cpp/messagebus/remote_server_connection.h index d91e62e8a6..63d7f20646 100644 --- a/library/cpp/messagebus/remote_server_connection.h +++ b/library/cpp/messagebus/remote_server_connection.h @@ -1,32 +1,32 @@ -#pragma once - +#pragma once + #include "session_impl.h" #include <util/generic/object_counter.h> - + namespace NBus { namespace NPrivate { class TRemoteServerConnection: public TRemoteConnection { friend struct TBusSessionImpl; friend class TRemoteServerSession; - + TObjectCounter<TRemoteServerConnection> ObjectCounter; - + public: TRemoteServerConnection(TRemoteServerSessionPtr session, ui64 id, TNetAddr addr); - + void Init(SOCKET socket, TInstant now); - + inline TRemoteServerSession* GetSession(); - + void HandleEvent(SOCKET socket, void* cookie) override; - + bool NeedInterruptRead() override; - + void MessageSent(TArrayRef<TBusMessagePtrAndHeader> messages) override; - + void ReaderProcessMessageUnknownVersion(TArrayRef<const char> dataRef) override; }; - + } } diff --git a/library/cpp/messagebus/remote_server_session.cpp b/library/cpp/messagebus/remote_server_session.cpp index c43207cf8a..6abbf88a60 100644 --- a/library/cpp/messagebus/remote_server_session.cpp +++ b/library/cpp/messagebus/remote_server_session.cpp @@ -1,26 +1,26 @@ #include "remote_server_session.h" - + #include "remote_connection.h" #include "remote_server_connection.h" #include <library/cpp/messagebus/actor/temp_tls_vector.h> #include <util/generic/cast.h> -#include <util/stream/output.h> -#include <util/system/yassert.h> - +#include <util/stream/output.h> +#include <util/system/yassert.h> + #include <typeinfo> - -using namespace NActor; -using namespace NBus; -using namespace NBus::NPrivate; - -TRemoteServerSession::TRemoteServerSession(TBusMessageQueue* queue, + +using namespace NActor; +using namespace NBus; +using namespace NBus::NPrivate; + +TRemoteServerSession::TRemoteServerSession(TBusMessageQueue* queue, TBusProtocol* proto, IBusServerHandler* handler, const TBusServerSessionConfig& config, const TString& name) - : TBusSessionImpl(false, queue, proto, handler, config, name) - , ServerOwnedMessages(config.MaxInFlight, config.MaxInFlightBySize, "ServerOwnedMessages") - , ServerHandler(handler) + : TBusSessionImpl(false, queue, proto, handler, config, name) + , ServerOwnedMessages(config.MaxInFlight, config.MaxInFlightBySize, "ServerOwnedMessages") + , ServerHandler(handler) { if (config.PerConnectionMaxInFlightBySize > 0) { if (config.PerConnectionMaxInFlightBySize < config.MaxMessageSize) @@ -36,17 +36,17 @@ namespace NBus { TRemoteServerSession* RemoteServerSession; TBusMessagePtrAndHeader Request; TIntrusivePtr<TRemoteServerConnection> Connection; - + public: TInvokeOnMessage(TRemoteServerSession* session, TBusMessagePtrAndHeader& request, TIntrusivePtr<TRemoteServerConnection>& connection) : RemoteServerSession(session) { Y_ASSERT(!!connection); Connection.Swap(connection); - + Request.Swap(request); } - + void DoWork() override { THolder<TInvokeOnMessage> holder(this); RemoteServerSession->InvokeOnMessage(Request, Connection); @@ -54,153 +54,153 @@ namespace NBus { RemoteServerSession->JobCount.Decrement(); } }; - + } } - -void TRemoteServerSession::OnMessageReceived(TRemoteConnection* c, TVectorSwaps<TBusMessagePtrAndHeader>& messages) { - AcquireInWorkRequests(messages); - - bool executeInPool = Config.ExecuteOnMessageInWorkerPool; - - TTempTlsVector< ::IWorkItem*> workQueueTemp; - - if (executeInPool) { - workQueueTemp.GetVector()->reserve(messages.size()); - } - + +void TRemoteServerSession::OnMessageReceived(TRemoteConnection* c, TVectorSwaps<TBusMessagePtrAndHeader>& messages) { + AcquireInWorkRequests(messages); + + bool executeInPool = Config.ExecuteOnMessageInWorkerPool; + + TTempTlsVector< ::IWorkItem*> workQueueTemp; + + if (executeInPool) { + workQueueTemp.GetVector()->reserve(messages.size()); + } + for (auto& message : messages) { - // TODO: incref once - TIntrusivePtr<TRemoteServerConnection> connection(CheckedCast<TRemoteServerConnection*>(c)); - if (executeInPool) { + // TODO: incref once + TIntrusivePtr<TRemoteServerConnection> connection(CheckedCast<TRemoteServerConnection*>(c)); + if (executeInPool) { workQueueTemp.GetVector()->push_back(new TInvokeOnMessage(this, message, connection)); - } else { + } else { InvokeOnMessage(message, connection); - } - } - - if (executeInPool) { - JobCount.Add(workQueueTemp.GetVector()->size()); - Queue->EnqueueWork(*workQueueTemp.GetVector()); - } -} - -void TRemoteServerSession::InvokeOnMessage(TBusMessagePtrAndHeader& request, TIntrusivePtr<TRemoteServerConnection>& conn) { + } + } + + if (executeInPool) { + JobCount.Add(workQueueTemp.GetVector()->size()); + Queue->EnqueueWork(*workQueueTemp.GetVector()); + } +} + +void TRemoteServerSession::InvokeOnMessage(TBusMessagePtrAndHeader& request, TIntrusivePtr<TRemoteServerConnection>& conn) { if (Y_UNLIKELY(AtomicGet(Down))) { ReleaseInWorkRequests(*conn.Get(), request.MessagePtr.Get()); - InvokeOnError(request.MessagePtr.Release(), MESSAGE_SHUTDOWN); - } else { - TWhatThreadDoesPushPop pp("OnMessage"); - - TBusIdentity ident; - - ident.Connection.Swap(conn); - request.MessagePtr->GetIdentity(ident); - + InvokeOnError(request.MessagePtr.Release(), MESSAGE_SHUTDOWN); + } else { + TWhatThreadDoesPushPop pp("OnMessage"); + + TBusIdentity ident; + + ident.Connection.Swap(conn); + request.MessagePtr->GetIdentity(ident); + Y_ASSERT(request.MessagePtr->LocalFlags & MESSAGE_IN_WORK); - DoSwap(request.MessagePtr->LocalFlags, ident.LocalFlags); - - ident.RecvTime = request.MessagePtr->RecvTime; - -#ifndef NDEBUG + DoSwap(request.MessagePtr->LocalFlags, ident.LocalFlags); + + ident.RecvTime = request.MessagePtr->RecvTime; + +#ifndef NDEBUG auto& message = *request.MessagePtr; ident.SetMessageType(typeid(message)); -#endif - - TOnMessageContext context(request.MessagePtr.Release(), ident, this); - ServerHandler->OnMessage(context); - } -} - -EMessageStatus TRemoteServerSession::ForgetRequest(const TBusIdentity& ident) { - ReleaseInWork(const_cast<TBusIdentity&>(ident)); - - return MESSAGE_OK; -} - -EMessageStatus TRemoteServerSession::SendReply(const TBusIdentity& ident, TBusMessage* reply) { - reply->CheckClean(); - - ConvertInWork(const_cast<TBusIdentity&>(ident), reply); - - reply->RecvTime = ident.RecvTime; - - ident.Connection->Send(reply); - - return MESSAGE_OK; -} - +#endif + + TOnMessageContext context(request.MessagePtr.Release(), ident, this); + ServerHandler->OnMessage(context); + } +} + +EMessageStatus TRemoteServerSession::ForgetRequest(const TBusIdentity& ident) { + ReleaseInWork(const_cast<TBusIdentity&>(ident)); + + return MESSAGE_OK; +} + +EMessageStatus TRemoteServerSession::SendReply(const TBusIdentity& ident, TBusMessage* reply) { + reply->CheckClean(); + + ConvertInWork(const_cast<TBusIdentity&>(ident), reply); + + reply->RecvTime = ident.RecvTime; + + ident.Connection->Send(reply); + + return MESSAGE_OK; +} + int TRemoteServerSession::GetInFlight() const noexcept { - return ServerOwnedMessages.GetCurrentCount(); -} - -void TRemoteServerSession::FillStatus() { - TBusSessionImpl::FillStatus(); - - // TODO: weird - StatusData.Status.InFlightCount = ServerOwnedMessages.GetCurrentCount(); - StatusData.Status.InFlightSize = ServerOwnedMessages.GetCurrentSize(); - StatusData.Status.InputPaused = ServerOwnedMessages.IsLocked(); -} - + return ServerOwnedMessages.GetCurrentCount(); +} + +void TRemoteServerSession::FillStatus() { + TBusSessionImpl::FillStatus(); + + // TODO: weird + StatusData.Status.InFlightCount = ServerOwnedMessages.GetCurrentCount(); + StatusData.Status.InFlightSize = ServerOwnedMessages.GetCurrentSize(); + StatusData.Status.InputPaused = ServerOwnedMessages.IsLocked(); +} + void TRemoteServerSession::AcquireInWorkRequests(TArrayRef<const TBusMessagePtrAndHeader> messages) { - TAtomicBase size = 0; + TAtomicBase size = 0; for (auto message = messages.begin(); message != messages.end(); ++message) { Y_ASSERT(!(message->MessagePtr->LocalFlags & MESSAGE_IN_WORK)); - message->MessagePtr->LocalFlags |= MESSAGE_IN_WORK; - size += message->MessagePtr->GetHeader()->Size; - } - - ServerOwnedMessages.IncrementMultiple(messages.size(), size); -} - + message->MessagePtr->LocalFlags |= MESSAGE_IN_WORK; + size += message->MessagePtr->GetHeader()->Size; + } + + ServerOwnedMessages.IncrementMultiple(messages.size(), size); +} + void TRemoteServerSession::ReleaseInWorkResponses(TArrayRef<const TBusMessagePtrAndHeader> responses) { - TAtomicBase size = 0; + TAtomicBase size = 0; for (auto response = responses.begin(); response != responses.end(); ++response) { Y_ASSERT((response->MessagePtr->LocalFlags & MESSAGE_REPLY_IS_BEGING_SENT)); - response->MessagePtr->LocalFlags &= ~MESSAGE_REPLY_IS_BEGING_SENT; - size += response->MessagePtr->RequestSize; - } - - ServerOwnedMessages.ReleaseMultiple(responses.size(), size); -} - + response->MessagePtr->LocalFlags &= ~MESSAGE_REPLY_IS_BEGING_SENT; + size += response->MessagePtr->RequestSize; + } + + ServerOwnedMessages.ReleaseMultiple(responses.size(), size); +} + void TRemoteServerSession::ReleaseInWorkRequests(TRemoteConnection& con, TBusMessage* request) { Y_ASSERT((request->LocalFlags & MESSAGE_IN_WORK)); request->LocalFlags &= ~MESSAGE_IN_WORK; - + const size_t size = request->GetHeader()->Size; con.QuotaReturnAside(1, size); ServerOwnedMessages.ReleaseMultiple(1, size); -} - +} + void TRemoteServerSession::ReleaseInWork(TBusIdentity& ident) { ident.SetInWork(false); ident.Connection->QuotaReturnAside(1, ident.Size); - + ServerOwnedMessages.ReleaseMultiple(1, ident.Size); -} - -void TRemoteServerSession::ConvertInWork(TBusIdentity& req, TBusMessage* reply) { - reply->SetIdentity(req); - - req.SetInWork(false); +} + +void TRemoteServerSession::ConvertInWork(TBusIdentity& req, TBusMessage* reply) { + reply->SetIdentity(req); + + req.SetInWork(false); Y_ASSERT(!(reply->LocalFlags & MESSAGE_REPLY_IS_BEGING_SENT)); - reply->LocalFlags |= MESSAGE_REPLY_IS_BEGING_SENT; - reply->RequestSize = req.Size; -} - -void TRemoteServerSession::Shutdown() { - ServerOwnedMessages.Stop(); - TBusSessionImpl::Shutdown(); -} - -void TRemoteServerSession::PauseInput(bool pause) { - ServerOwnedMessages.PauseByUsed(pause); -} - -unsigned TRemoteServerSession::GetActualListenPort() { + reply->LocalFlags |= MESSAGE_REPLY_IS_BEGING_SENT; + reply->RequestSize = req.Size; +} + +void TRemoteServerSession::Shutdown() { + ServerOwnedMessages.Stop(); + TBusSessionImpl::Shutdown(); +} + +void TRemoteServerSession::PauseInput(bool pause) { + ServerOwnedMessages.PauseByUsed(pause); +} + +unsigned TRemoteServerSession::GetActualListenPort() { Y_VERIFY(Config.ListenPort > 0, "state check"); - return Config.ListenPort; -} + return Config.ListenPort; +} diff --git a/library/cpp/messagebus/remote_server_session.h b/library/cpp/messagebus/remote_server_session.h index a0fdf3e2e3..f5c266a7f7 100644 --- a/library/cpp/messagebus/remote_server_session.h +++ b/library/cpp/messagebus/remote_server_session.h @@ -1,13 +1,13 @@ #pragma once -#include "remote_server_session_semaphore.h" -#include "session_impl.h" +#include "remote_server_session_semaphore.h" +#include "session_impl.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4250) // 'NBus::NPrivate::TRemoteClientSession' : inherits 'NBus::NPrivate::TBusSessionImpl::NBus::NPrivate::TBusSessionImpl::GetConfig' via dominance #endif - + namespace NBus { namespace NPrivate { class TRemoteServerSession: public TBusServerSession, public TBusSessionImpl { @@ -15,37 +15,37 @@ namespace NBus { private: TObjectCounter<TRemoteServerSession> ObjectCounter; - + TRemoteServerSessionSemaphore ServerOwnedMessages; IBusServerHandler* const ServerHandler; - + public: TRemoteServerSession(TBusMessageQueue* queue, TBusProtocol* proto, IBusServerHandler* handler, const TBusSessionConfig& config, const TString& name); - + void OnMessageReceived(TRemoteConnection* c, TVectorSwaps<TBusMessagePtrAndHeader>& newMsg) override; void InvokeOnMessage(TBusMessagePtrAndHeader& request, TIntrusivePtr<TRemoteServerConnection>& conn); - + EMessageStatus SendReply(const TBusIdentity& ident, TBusMessage* pRep) override; - + EMessageStatus ForgetRequest(const TBusIdentity& ident) override; - + int GetInFlight() const noexcept override; void FillStatus() override; - + void Shutdown() override; - + void PauseInput(bool pause) override; unsigned GetActualListenPort() override; - + void AcquireInWorkRequests(TArrayRef<const TBusMessagePtrAndHeader> requests); void ReleaseInWorkResponses(TArrayRef<const TBusMessagePtrAndHeader> responses); void ReleaseInWorkRequests(TRemoteConnection&, TBusMessage*); void ReleaseInWork(TBusIdentity&); void ConvertInWork(TBusIdentity& req, TBusMessage* reply); }; - + #ifdef _MSC_VER #pragma warning(pop) #endif diff --git a/library/cpp/messagebus/remote_server_session_semaphore.cpp b/library/cpp/messagebus/remote_server_session_semaphore.cpp index 1db0a4e41d..6094a3586e 100644 --- a/library/cpp/messagebus/remote_server_session_semaphore.cpp +++ b/library/cpp/messagebus/remote_server_session_semaphore.cpp @@ -1,59 +1,59 @@ #include "remote_server_session_semaphore.h" #include <util/stream/output.h> -#include <util/system/yassert.h> - -using namespace NBus; -using namespace NBus::NPrivate; - -TRemoteServerSessionSemaphore::TRemoteServerSessionSemaphore( +#include <util/system/yassert.h> + +using namespace NBus; +using namespace NBus::NPrivate; + +TRemoteServerSessionSemaphore::TRemoteServerSessionSemaphore( TAtomicBase limitCount, TAtomicBase limitSize, const char* name) - : Name(name) - , LimitCount(limitCount) - , LimitSize(limitSize) - , CurrentCount(0) - , CurrentSize(0) - , PausedByUser(0) - , StopSignal(0) -{ + : Name(name) + , LimitCount(limitCount) + , LimitSize(limitSize) + , CurrentCount(0) + , CurrentSize(0) + , PausedByUser(0) + , StopSignal(0) +{ Y_VERIFY(limitCount > 0, "limit must be > 0"); Y_UNUSED(Name); -} - +} + TRemoteServerSessionSemaphore::~TRemoteServerSessionSemaphore() { Y_VERIFY(AtomicGet(CurrentCount) == 0); - // TODO: fix spider and enable + // TODO: fix spider and enable //Y_VERIFY(AtomicGet(CurrentSize) == 0); -} - -bool TRemoteServerSessionSemaphore::TryWait() { +} + +bool TRemoteServerSessionSemaphore::TryWait() { if (Y_UNLIKELY(AtomicGet(StopSignal))) - return true; - if (AtomicGet(PausedByUser)) - return false; - if (AtomicGet(CurrentCount) < LimitCount && (LimitSize < 0 || AtomicGet(CurrentSize) < LimitSize)) - return true; - return false; -} - -void TRemoteServerSessionSemaphore::IncrementMultiple(TAtomicBase count, TAtomicBase size) { - AtomicAdd(CurrentCount, count); - AtomicAdd(CurrentSize, size); - Updated(); -} - -void TRemoteServerSessionSemaphore::ReleaseMultiple(TAtomicBase count, TAtomicBase size) { - AtomicSub(CurrentCount, count); - AtomicSub(CurrentSize, size); - Updated(); -} - -void TRemoteServerSessionSemaphore::Stop() { - AtomicSet(StopSignal, 1); - Updated(); -} - -void TRemoteServerSessionSemaphore::PauseByUsed(bool pause) { - AtomicSet(PausedByUser, pause); - Updated(); -} + return true; + if (AtomicGet(PausedByUser)) + return false; + if (AtomicGet(CurrentCount) < LimitCount && (LimitSize < 0 || AtomicGet(CurrentSize) < LimitSize)) + return true; + return false; +} + +void TRemoteServerSessionSemaphore::IncrementMultiple(TAtomicBase count, TAtomicBase size) { + AtomicAdd(CurrentCount, count); + AtomicAdd(CurrentSize, size); + Updated(); +} + +void TRemoteServerSessionSemaphore::ReleaseMultiple(TAtomicBase count, TAtomicBase size) { + AtomicSub(CurrentCount, count); + AtomicSub(CurrentSize, size); + Updated(); +} + +void TRemoteServerSessionSemaphore::Stop() { + AtomicSet(StopSignal, 1); + Updated(); +} + +void TRemoteServerSessionSemaphore::PauseByUsed(bool pause) { + AtomicSet(PausedByUser, pause); + Updated(); +} diff --git a/library/cpp/messagebus/remote_server_session_semaphore.h b/library/cpp/messagebus/remote_server_session_semaphore.h index 453dd96d57..de714fd342 100644 --- a/library/cpp/messagebus/remote_server_session_semaphore.h +++ b/library/cpp/messagebus/remote_server_session_semaphore.h @@ -1,42 +1,42 @@ -#pragma once - +#pragma once + #include "cc_semaphore.h" -#include <util/generic/noncopyable.h> - +#include <util/generic/noncopyable.h> + namespace NBus { namespace NPrivate { class TRemoteServerSessionSemaphore: public TComplexConditionSemaphore<TRemoteServerSessionSemaphore> { private: const char* const Name; - + TAtomicBase const LimitCount; TAtomicBase const LimitSize; TAtomic CurrentCount; TAtomic CurrentSize; TAtomic PausedByUser; TAtomic StopSignal; - + public: TRemoteServerSessionSemaphore(TAtomicBase limitCount, TAtomicBase limitSize, const char* name = "unnamed"); ~TRemoteServerSessionSemaphore(); - + TAtomicBase GetCurrentCount() const { return AtomicGet(CurrentCount); } TAtomicBase GetCurrentSize() const { return AtomicGet(CurrentSize); } - + void IncrementMultiple(TAtomicBase count, TAtomicBase size); bool TryWait(); void ReleaseMultiple(TAtomicBase count, TAtomicBase size); void Stop(); void PauseByUsed(bool pause); - + private: void CheckNeedToUnlock(); }; - + } } diff --git a/library/cpp/messagebus/scheduler/scheduler.cpp b/library/cpp/messagebus/scheduler/scheduler.cpp index 8c966da86d..5a5fe52894 100644 --- a/library/cpp/messagebus/scheduler/scheduler.cpp +++ b/library/cpp/messagebus/scheduler/scheduler.cpp @@ -5,19 +5,19 @@ #include <util/generic/yexception.h> //#include "dummy_debugger.h" - -using namespace NBus; -using namespace NBus::NPrivate; + +using namespace NBus; +using namespace NBus::NPrivate; class TScheduleDeadlineCompare { public: bool operator()(const IScheduleItemAutoPtr& i1, const IScheduleItemAutoPtr& i2) const noexcept { - return i1->GetScheduleTime() > i2->GetScheduleTime(); + return i1->GetScheduleTime() > i2->GetScheduleTime(); } }; TScheduler::TScheduler() - : StopThread(false) + : StopThread(false) , Thread([&] { this->SchedulerThread(); }) { } @@ -32,13 +32,13 @@ size_t TScheduler::Size() const { } void TScheduler::Stop() { - { - TGuard<TLock> guard(Lock); + { + TGuard<TLock> guard(Lock); Y_VERIFY(!StopThread, "Scheduler already stopped"); - StopThread = true; - CondVar.Signal(); - } - Thread.Get(); + StopThread = true; + CondVar.Signal(); + } + Thread.Get(); if (!!NextItem) { NextItem.Destroy(); @@ -50,70 +50,70 @@ void TScheduler::Stop() { } void TScheduler::Schedule(TAutoPtr<IScheduleItem> i) { - TGuard<TLock> lock(Lock); - if (StopThread) + TGuard<TLock> lock(Lock); + if (StopThread) return; - - if (!!NextItem) { - if (i->GetScheduleTime() < NextItem->GetScheduleTime()) { - DoSwap(i, NextItem); - } + + if (!!NextItem) { + if (i->GetScheduleTime() < NextItem->GetScheduleTime()) { + DoSwap(i, NextItem); + } } - + Items.push_back(i); - PushHeap(Items.begin(), Items.end(), TScheduleDeadlineCompare()); - - FillNextItem(); - - CondVar.Signal(); + PushHeap(Items.begin(), Items.end(), TScheduleDeadlineCompare()); + + FillNextItem(); + + CondVar.Signal(); +} + +void TScheduler::FillNextItem() { + if (!NextItem && !Items.empty()) { + PopHeap(Items.begin(), Items.end(), TScheduleDeadlineCompare()); + NextItem = Items.back(); + Items.erase(Items.end() - 1); + } } -void TScheduler::FillNextItem() { - if (!NextItem && !Items.empty()) { - PopHeap(Items.begin(), Items.end(), TScheduleDeadlineCompare()); - NextItem = Items.back(); - Items.erase(Items.end() - 1); - } -} - void TScheduler::SchedulerThread() { - for (;;) { - IScheduleItemAutoPtr current; - + for (;;) { + IScheduleItemAutoPtr current; + { - TGuard<TLock> guard(Lock); - - if (StopThread) { - break; + TGuard<TLock> guard(Lock); + + if (StopThread) { + break; + } + + if (!!NextItem) { + CondVar.WaitD(Lock, NextItem->GetScheduleTime()); + } else { + CondVar.WaitI(Lock); } - - if (!!NextItem) { - CondVar.WaitD(Lock, NextItem->GetScheduleTime()); - } else { - CondVar.WaitI(Lock); + + if (StopThread) { + break; } - - if (StopThread) { - break; - } - - // signal comes if either scheduler is to be stopped of there's work to do + + // signal comes if either scheduler is to be stopped of there's work to do Y_VERIFY(!!NextItem, "state check"); - - if (TInstant::Now() < NextItem->GetScheduleTime()) { - // NextItem is updated since WaitD - continue; - } - + + if (TInstant::Now() < NextItem->GetScheduleTime()) { + // NextItem is updated since WaitD + continue; + } + current = NextItem.Release(); } - - current->Do(); - current.Destroy(); - - { - TGuard<TLock> guard(Lock); - FillNextItem(); - } + + current->Do(); + current.Destroy(); + + { + TGuard<TLock> guard(Lock); + FillNextItem(); + } } } diff --git a/library/cpp/messagebus/scheduler/scheduler.h b/library/cpp/messagebus/scheduler/scheduler.h index 6114c3cc88..afcc0de55d 100644 --- a/library/cpp/messagebus/scheduler/scheduler.h +++ b/library/cpp/messagebus/scheduler/scheduler.h @@ -8,7 +8,7 @@ #include <util/generic/vector.h> #include <util/system/atomic.h> #include <util/system/condvar.h> -#include <util/system/mutex.h> +#include <util/system/mutex.h> #include <util/system/thread.h> namespace NBus { @@ -18,10 +18,10 @@ namespace NBus { inline IScheduleItem(TInstant scheduleTime) noexcept; virtual ~IScheduleItem() { } - + virtual void Do() = 0; inline TInstant GetScheduleTime() const noexcept; - + private: TInstant ScheduleTime; }; @@ -50,16 +50,16 @@ namespace NBus { TCondVar CondVar; TObjectCounter<TScheduler> ObjectCounter; - + bool StopThread; NThreading::TLegacyFuture<> Thread; }; - + inline IScheduleItem::IScheduleItem(TInstant scheduleTime) noexcept : ScheduleTime(scheduleTime) { } - + inline TInstant IScheduleItem::GetScheduleTime() const noexcept { return ScheduleTime; } diff --git a/library/cpp/messagebus/scheduler/scheduler_ut.cpp b/library/cpp/messagebus/scheduler/scheduler_ut.cpp index 35fcccdd29..a5ea641c10 100644 --- a/library/cpp/messagebus/scheduler/scheduler_ut.cpp +++ b/library/cpp/messagebus/scheduler/scheduler_ut.cpp @@ -1,36 +1,36 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "scheduler.h" - + +#include "scheduler.h" + #include <library/cpp/messagebus/misc/test_sync.h> - -using namespace NBus; -using namespace NBus::NPrivate; - + +using namespace NBus; +using namespace NBus::NPrivate; + Y_UNIT_TEST_SUITE(TSchedulerTests) { - struct TSimpleScheduleItem: public IScheduleItem { - TTestSync* const TestSync; - - TSimpleScheduleItem(TTestSync* testSync) - : IScheduleItem((TInstant::Now() + TDuration::MilliSeconds(1))) - , TestSync(testSync) + struct TSimpleScheduleItem: public IScheduleItem { + TTestSync* const TestSync; + + TSimpleScheduleItem(TTestSync* testSync) + : IScheduleItem((TInstant::Now() + TDuration::MilliSeconds(1))) + , TestSync(testSync) { } - + void Do() override { - TestSync->WaitForAndIncrement(0); - } - }; - + TestSync->WaitForAndIncrement(0); + } + }; + Y_UNIT_TEST(Simple) { - TTestSync testSync; - - TScheduler scheduler; - - scheduler.Schedule(new TSimpleScheduleItem(&testSync)); - - testSync.WaitForAndIncrement(1); - - scheduler.Stop(); - } -} + TTestSync testSync; + + TScheduler scheduler; + + scheduler.Schedule(new TSimpleScheduleItem(&testSync)); + + testSync.WaitForAndIncrement(1); + + scheduler.Stop(); + } +} diff --git a/library/cpp/messagebus/scheduler/ya.make b/library/cpp/messagebus/scheduler/ya.make index 382804c408..dcb7408a20 100644 --- a/library/cpp/messagebus/scheduler/ya.make +++ b/library/cpp/messagebus/scheduler/ya.make @@ -1,13 +1,13 @@ -LIBRARY() - +LIBRARY() + OWNER(g:messagebus) - + PEERDIR( library/cpp/threading/future ) -SRCS( - scheduler.cpp -) - -END() +SRCS( + scheduler.cpp +) + +END() diff --git a/library/cpp/messagebus/scheduler_actor.h b/library/cpp/messagebus/scheduler_actor.h index ba9595249b..d0c23c94c4 100644 --- a/library/cpp/messagebus/scheduler_actor.h +++ b/library/cpp/messagebus/scheduler_actor.h @@ -1,51 +1,51 @@ -#pragma once - -#include "local_tasks.h" - +#pragma once + +#include "local_tasks.h" + #include <library/cpp/messagebus/actor/actor.h> #include <library/cpp/messagebus/actor/what_thread_does_guard.h> #include <library/cpp/messagebus/scheduler/scheduler.h> - + #include <util/system/mutex.h> - + namespace NBus { namespace NPrivate { template <typename TThis, typename TTag = NActor::TDefaultTag> class TScheduleActor { typedef NActor::TActor<TThis, TTag> TActorForMe; - + private: TScheduler* const Scheduler; - + TMutex Mutex; - + TInstant ScheduleTime; - + public: TLocalTasks Alarm; - + private: struct TScheduleItemImpl: public IScheduleItem { TIntrusivePtr<TThis> Thiz; - + TScheduleItemImpl(TIntrusivePtr<TThis> thiz, TInstant when) : IScheduleItem(when) , Thiz(thiz) { } - + void Do() override { { TWhatThreadDoesAcquireGuard<TMutex> guard(Thiz->Mutex, "scheduler actor: acquiring lock for Do"); - + if (Thiz->ScheduleTime == TInstant::Max()) { // was already fired return; } - + Thiz->ScheduleTime = TInstant::Max(); } - + Thiz->Alarm.AddTask(); Thiz->GetActorForMe()->Schedule(); } @@ -55,31 +55,31 @@ namespace NBus { TScheduleActor(TScheduler* scheduler) : Scheduler(scheduler) , ScheduleTime(TInstant::Max()) - { + { } - + /// call Act(TTag) at specified time, unless it is already scheduled at earlier time. void ScheduleAt(TInstant when) { TWhatThreadDoesAcquireGuard<TMutex> guard(Mutex, "scheduler: acquiring lock for ScheduleAt"); if (when > ScheduleTime) { // already scheduled - return; - } - + return; + } + ScheduleTime = when; Scheduler->Schedule(new TScheduleItemImpl(GetThis(), when)); - } - + } + private: TThis* GetThis() { return static_cast<TThis*>(this); } - + TActorForMe* GetActorForMe() { return static_cast<TActorForMe*>(GetThis()); } }; - - } + + } } diff --git a/library/cpp/messagebus/scheduler_actor_ut.cpp b/library/cpp/messagebus/scheduler_actor_ut.cpp index 63e4d58782..e81ffd3186 100644 --- a/library/cpp/messagebus/scheduler_actor_ut.cpp +++ b/library/cpp/messagebus/scheduler_actor_ut.cpp @@ -1,48 +1,48 @@ #include <library/cpp/testing/unittest/registar.h> - + #include "scheduler_actor.h" -#include "misc/test_sync.h" - -using namespace NBus; -using namespace NBus::NPrivate; -using namespace NActor; - +#include "misc/test_sync.h" + +using namespace NBus; +using namespace NBus::NPrivate; +using namespace NActor; + Y_UNIT_TEST_SUITE(TSchedulerActorTests) { struct TMyActor: public TAtomicRefCount<TMyActor>, public TActor<TMyActor>, public TScheduleActor<TMyActor> { - TTestSync TestSync; - - TMyActor(TExecutor* executor, TScheduler* scheduler) - : TActor<TMyActor>(executor) - , TScheduleActor<TMyActor>(scheduler) - , Iteration(0) + TTestSync TestSync; + + TMyActor(TExecutor* executor, TScheduler* scheduler) + : TActor<TMyActor>(executor) + , TScheduleActor<TMyActor>(scheduler) + , Iteration(0) { } - - unsigned Iteration; - - void Act(TDefaultTag) { - if (!Alarm.FetchTask()) { + + unsigned Iteration; + + void Act(TDefaultTag) { + if (!Alarm.FetchTask()) { Y_FAIL("must not have no spurious wakeups in test"); - } - - TestSync.WaitForAndIncrement(Iteration++); - if (Iteration <= 5) { - ScheduleAt(TInstant::Now() + TDuration::MilliSeconds(Iteration)); - } - } - }; - + } + + TestSync.WaitForAndIncrement(Iteration++); + if (Iteration <= 5) { + ScheduleAt(TInstant::Now() + TDuration::MilliSeconds(Iteration)); + } + } + }; + Y_UNIT_TEST(Simple) { - TExecutor executor(1); - TScheduler scheduler; - - TIntrusivePtr<TMyActor> actor(new TMyActor(&executor, &scheduler)); - - actor->ScheduleAt(TInstant::Now() + TDuration::MilliSeconds(1)); - - actor->TestSync.WaitForAndIncrement(6); - - // TODO: stop in destructor - scheduler.Stop(); - } -} + TExecutor executor(1); + TScheduler scheduler; + + TIntrusivePtr<TMyActor> actor(new TMyActor(&executor, &scheduler)); + + actor->ScheduleAt(TInstant::Now() + TDuration::MilliSeconds(1)); + + actor->TestSync.WaitForAndIncrement(6); + + // TODO: stop in destructor + scheduler.Stop(); + } +} diff --git a/library/cpp/messagebus/session.cpp b/library/cpp/messagebus/session.cpp index 57d7ead401..46a7ece6a8 100644 --- a/library/cpp/messagebus/session.cpp +++ b/library/cpp/messagebus/session.cpp @@ -1,16 +1,16 @@ #include "ybus.h" -#include <util/generic/cast.h> - -using namespace NBus; - +#include <util/generic/cast.h> + +using namespace NBus; + namespace NBus { TBusSession::TBusSession() { } //////////////////////////////////////////////////////////////////// /// \brief Adds peer of connection into connection list - + int CompareByHost(const IRemoteAddr& l, const IRemoteAddr& r) noexcept { if (l.Addr()->sa_family != r.Addr()->sa_family) { return l.Addr()->sa_family < r.Addr()->sa_family ? -1 : +1; @@ -50,7 +50,7 @@ namespace NBus { bool SplitHost(const TString& host, TString* hostName, TString* portNum) { hostName->clear(); portNum->clear(); - + // Simple check that we have to deal with ipv6 address specification or // just host name or ipv4 address. if (!host.empty() && (host[0] == '[')) { @@ -97,7 +97,7 @@ namespace NBus { if (!SplitHost(host, &hostName, &port)) { hostName = host; } - + if (port.empty()) { portNum = GetProto()->GetPort(); } else { @@ -118,12 +118,12 @@ namespace NBus { } TBusClientSessionPtr TBusClientSession::Create(TBusProtocol* proto, IBusClientHandler* handler, const TBusClientSessionConfig& config, TBusMessageQueuePtr queue) { - return queue->CreateSource(proto, handler, config); -} - + return queue->CreateSource(proto, handler, config); +} + TBusServerSessionPtr TBusServerSession::Create(TBusProtocol* proto, IBusServerHandler* handler, const TBusServerSessionConfig& config, TBusMessageQueuePtr queue) { - return queue->CreateDestination(proto, handler, config); -} + return queue->CreateDestination(proto, handler, config); +} TBusServerSessionPtr TBusServerSession::Create(TBusProtocol* proto, IBusServerHandler* handler, const TBusServerSessionConfig& config, TBusMessageQueuePtr queue, const TVector<TBindResult>& bindTo) { return queue->CreateDestination(proto, handler, config, bindTo); diff --git a/library/cpp/messagebus/session.h b/library/cpp/messagebus/session.h index 5a1a01d808..fb12ab7c22 100644 --- a/library/cpp/messagebus/session.h +++ b/library/cpp/messagebus/session.h @@ -1,41 +1,41 @@ -#pragma once - +#pragma once + #include "connection.h" -#include "defs.h" +#include "defs.h" #include "handler.h" -#include "message.h" -#include "netaddr.h" +#include "message.h" +#include "netaddr.h" #include "network.h" -#include "session_config.h" +#include "session_config.h" #include "misc/weak_ptr.h" - + #include <library/cpp/messagebus/monitoring/mon_proto.pb.h> - + #include <util/generic/array_ref.h> #include <util/generic/ptr.h> -namespace NBus { +namespace NBus { template <typename TBusSessionSubclass> class TBusSessionPtr; using TBusClientSessionPtr = TBusSessionPtr<TBusClientSession>; using TBusServerSessionPtr = TBusSessionPtr<TBusServerSession>; - + /////////////////////////////////////////////////////////////////// /// \brief Interface of session object. - + /// Each client and server /// should instantiate session object to be able to communicate via bus /// client: sess = queue->CreateSource(protocol, handler); /// server: sess = queue->CreateDestination(protocol, handler); - + class TBusSession: public TWeakRefCounted<TBusSession> { public: size_t GetInFlight(const TNetAddr& addr) const; size_t GetConnectSyscallsNumForTest(const TNetAddr& addr) const; - + virtual void GetInFlightBulk(TArrayRef<const TNetAddr> addrs, TArrayRef<size_t> results) const = 0; virtual void GetConnectSyscallsNumBulkForTest(TArrayRef<const TNetAddr> addrs, TArrayRef<size_t> results) const = 0; - + virtual int GetInFlight() const noexcept = 0; /// monitoring status of current session and it's connections virtual TString GetStatus(ui16 flags = YBUS_STATUS_CONNS) = 0; @@ -47,42 +47,42 @@ namespace NBus { /// return session protocol virtual const TBusProtocol* GetProto() const noexcept = 0; virtual TBusMessageQueue* GetQueue() const noexcept = 0; - + /// registers external session on host:port with locator service int RegisterService(const char* hostname, TBusKey start = YBUS_KEYMIN, TBusKey end = YBUS_KEYMAX, EIpVersion ipVersion = EIP_VERSION_4); - + protected: TBusSession(); - + public: virtual TString GetNameInternal() = 0; - + virtual void Shutdown() = 0; - + virtual ~TBusSession(); }; - + struct TBusClientSession: public virtual TBusSession { typedef ::NBus::NPrivate::TRemoteClientSession TImpl; - + static TBusClientSessionPtr Create( TBusProtocol* proto, IBusClientHandler* handler, - const TBusClientSessionConfig& config, - TBusMessageQueuePtr queue); - + const TBusClientSessionConfig& config, + TBusMessageQueuePtr queue); + virtual TBusClientConnectionPtr GetConnection(const TNetAddr&) = 0; - + /// if you want to open connection early virtual void OpenConnection(const TNetAddr&) = 0; - + /// Send message to the destination /// If addr is set then use it as destination. /// Takes ownership of addr (see ClearState method). virtual EMessageStatus SendMessage(TBusMessage* pMes, const TNetAddr* addr = nullptr, bool wait = false) = 0; - + virtual EMessageStatus SendMessageOneWay(TBusMessage* pMes, const TNetAddr* addr = nullptr, bool wait = false) = 0; - + /// Like SendMessage but cares about message template <typename T /* <: TBusMessage */> EMessageStatus SendMessageAutoPtr(const TAutoPtr<T>& mes, const TNetAddr* addr = nullptr, bool wait = false) { @@ -91,7 +91,7 @@ namespace NBus { Y_UNUSED(mes.Release()); return status; } - + /// Like SendMessageOneWay but cares about message template <typename T /* <: TBusMessage */> EMessageStatus SendMessageOneWayAutoPtr(const TAutoPtr<T>& mes, const TNetAddr* addr = nullptr, bool wait = false) { @@ -100,27 +100,27 @@ namespace NBus { Y_UNUSED(mes.Release()); return status; } - + EMessageStatus SendMessageMove(TBusMessageAutoPtr message, const TNetAddr* addr = nullptr, bool wait = false) { return SendMessageAutoPtr(message, addr, wait); } - + EMessageStatus SendMessageOneWayMove(TBusMessageAutoPtr message, const TNetAddr* addr = nullptr, bool wait = false) { return SendMessageOneWayAutoPtr(message, addr, wait); } - + // TODO: implement similar one-way methods }; - + struct TBusServerSession: public virtual TBusSession { typedef ::NBus::NPrivate::TRemoteServerSession TImpl; - + static TBusServerSessionPtr Create( TBusProtocol* proto, IBusServerHandler* handler, - const TBusServerSessionConfig& config, - TBusMessageQueuePtr queue); - + const TBusServerSessionConfig& config, + TBusMessageQueuePtr queue); + static TBusServerSessionPtr Create( TBusProtocol* proto, IBusServerHandler* handler, @@ -130,10 +130,10 @@ namespace NBus { // TODO: make parameter non-const virtual EMessageStatus SendReply(const TBusIdentity& ident, TBusMessage* pRep) = 0; - + // TODO: make parameter non-const virtual EMessageStatus ForgetRequest(const TBusIdentity& ident) = 0; - + template <typename U /* <: TBusMessage */> EMessageStatus SendReplyAutoPtr(TBusIdentity& ident, TAutoPtr<U>& resp) { EMessageStatus status = SendReply(const_cast<const TBusIdentity&>(ident), resp.Get()); @@ -141,49 +141,49 @@ namespace NBus { Y_UNUSED(resp.Release()); } return status; - } - + } + EMessageStatus SendReplyMove(TBusIdentity& ident, TBusMessageAutoPtr resp) { return SendReplyAutoPtr(ident, resp); } - + /// Pause input from the network. /// It is valid to call this method in parallel. /// TODO: pull this method up to TBusSession. virtual void PauseInput(bool pause) = 0; virtual unsigned GetActualListenPort() = 0; }; - + namespace NPrivate { template <typename TBusSessionSubclass> class TBusOwnerSessionPtr: public TAtomicRefCount<TBusOwnerSessionPtr<TBusSessionSubclass>> { private: TIntrusivePtr<TBusSessionSubclass> Ptr; - + public: TBusOwnerSessionPtr(TBusSessionSubclass* session) : Ptr(session) { Y_ASSERT(!!Ptr); } - + ~TBusOwnerSessionPtr() { Ptr->Shutdown(); } - + TBusSessionSubclass* Get() const { return reinterpret_cast<TBusSessionSubclass*>(Ptr.Get()); } }; - - } - + + } + template <typename TBusSessionSubclass> class TBusSessionPtr { private: TIntrusivePtr<NPrivate::TBusOwnerSessionPtr<TBusSessionSubclass>> SmartPtr; TBusSessionSubclass* Ptr; - + public: TBusSessionPtr() : Ptr() @@ -194,7 +194,7 @@ namespace NBus { , Ptr(session) { } - + TBusSessionSubclass* Get() const { return Ptr; } @@ -207,19 +207,19 @@ namespace NBus { TBusSessionSubclass* operator->() const { return Get(); } - + bool operator!() const { return !Ptr; } - + void Swap(TBusSessionPtr& t) noexcept { DoSwap(SmartPtr, t.SmartPtr); DoSwap(Ptr, t.Ptr); } - + void Drop() { TBusSessionPtr().Swap(*this); } }; - -} + +} diff --git a/library/cpp/messagebus/session_config.h b/library/cpp/messagebus/session_config.h index ac0dce4291..37df97e986 100644 --- a/library/cpp/messagebus/session_config.h +++ b/library/cpp/messagebus/session_config.h @@ -1,4 +1,4 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/config/session_config.h> - + diff --git a/library/cpp/messagebus/session_impl.cpp b/library/cpp/messagebus/session_impl.cpp index fd123f7dd5..ddf9f360c4 100644 --- a/library/cpp/messagebus/session_impl.cpp +++ b/library/cpp/messagebus/session_impl.cpp @@ -1,216 +1,216 @@ #include "session_impl.h" - + #include "acceptor.h" -#include "network.h" +#include "network.h" #include "remote_client_connection.h" -#include "remote_client_session.h" -#include "remote_server_connection.h" +#include "remote_client_session.h" +#include "remote_server_connection.h" #include "remote_server_session.h" #include "misc/weak_ptr.h" - + #include <util/generic/cast.h> -using namespace NActor; -using namespace NBus; -using namespace NBus::NPrivate; -using namespace NEventLoop; - -namespace { - class TScheduleSession: public IScheduleItem { - public: - TScheduleSession(TBusSessionImpl* session, TInstant deadline) - : IScheduleItem(deadline) - , Session(session) - , SessionImpl(session) - { - } - +using namespace NActor; +using namespace NBus; +using namespace NBus::NPrivate; +using namespace NEventLoop; + +namespace { + class TScheduleSession: public IScheduleItem { + public: + TScheduleSession(TBusSessionImpl* session, TInstant deadline) + : IScheduleItem(deadline) + , Session(session) + , SessionImpl(session) + { + } + void Do() override { - TIntrusivePtr<TBusSession> session = Session.Get(); - if (!!session) { - SessionImpl->Cron(); - } - } - - private: - TWeakPtr<TBusSession> Session; - // Work around TWeakPtr limitation - TBusSessionImpl* SessionImpl; - }; -} - -TConnectionsAcceptorsSnapshot::TConnectionsAcceptorsSnapshot() + TIntrusivePtr<TBusSession> session = Session.Get(); + if (!!session) { + SessionImpl->Cron(); + } + } + + private: + TWeakPtr<TBusSession> Session; + // Work around TWeakPtr limitation + TBusSessionImpl* SessionImpl; + }; +} + +TConnectionsAcceptorsSnapshot::TConnectionsAcceptorsSnapshot() : LastConnectionId(0) , LastAcceptorId(0) { } - -struct TBusSessionImpl::TImpl { - TRemoteConnectionWriterIncrementalStatus DeadConnectionWriterStatusSummary; - TRemoteConnectionReaderIncrementalStatus DeadConnectionReaderStatusSummary; - TAcceptorStatus DeadAcceptorStatusSummary; -}; - -namespace { + +struct TBusSessionImpl::TImpl { + TRemoteConnectionWriterIncrementalStatus DeadConnectionWriterStatusSummary; + TRemoteConnectionReaderIncrementalStatus DeadConnectionReaderStatusSummary; + TAcceptorStatus DeadAcceptorStatusSummary; +}; + +namespace { TBusSessionConfig SessionConfigFillDefaults(const TBusSessionConfig& config, const TString& name) { - TBusSessionConfig copy = config; - if (copy.TotalTimeout == 0 && copy.SendTimeout == 0) { - copy.TotalTimeout = TDuration::Seconds(60).MilliSeconds(); - copy.SendTimeout = TDuration::Seconds(15).MilliSeconds(); - } else if (copy.TotalTimeout == 0) { + TBusSessionConfig copy = config; + if (copy.TotalTimeout == 0 && copy.SendTimeout == 0) { + copy.TotalTimeout = TDuration::Seconds(60).MilliSeconds(); + copy.SendTimeout = TDuration::Seconds(15).MilliSeconds(); + } else if (copy.TotalTimeout == 0) { Y_ASSERT(copy.SendTimeout != 0); - copy.TotalTimeout = config.SendTimeout + TDuration::MilliSeconds(10).MilliSeconds(); - } else if (copy.SendTimeout == 0) { + copy.TotalTimeout = config.SendTimeout + TDuration::MilliSeconds(10).MilliSeconds(); + } else if (copy.SendTimeout == 0) { Y_ASSERT(copy.TotalTimeout != 0); if ((ui64)copy.TotalTimeout > (ui64)TDuration::MilliSeconds(10).MilliSeconds()) { - copy.SendTimeout = copy.TotalTimeout - TDuration::MilliSeconds(10).MilliSeconds(); - } else { - copy.SendTimeout = copy.TotalTimeout; - } - } else { + copy.SendTimeout = copy.TotalTimeout - TDuration::MilliSeconds(10).MilliSeconds(); + } else { + copy.SendTimeout = copy.TotalTimeout; + } + } else { Y_ASSERT(copy.TotalTimeout != 0); Y_ASSERT(copy.SendTimeout != 0); - } - - if (copy.ConnectTimeout == 0) { - copy.ConnectTimeout = copy.SendTimeout; - } - + } + + if (copy.ConnectTimeout == 0) { + copy.ConnectTimeout = copy.SendTimeout; + } + Y_VERIFY(copy.SendTimeout > 0, "SendTimeout must be > 0"); Y_VERIFY(copy.TotalTimeout > 0, "TotalTimeout must be > 0"); Y_VERIFY(copy.ConnectTimeout > 0, "ConnectTimeout must be > 0"); Y_VERIFY(copy.TotalTimeout >= copy.SendTimeout, "TotalTimeout must be >= SendTimeout"); - - if (!copy.Name) { - copy.Name = name; - } - - return copy; - } -} - -TBusSessionImpl::TBusSessionImpl(bool isSource, TBusMessageQueue* queue, TBusProtocol* proto, + + if (!copy.Name) { + copy.Name = name; + } + + return copy; + } +} + +TBusSessionImpl::TBusSessionImpl(bool isSource, TBusMessageQueue* queue, TBusProtocol* proto, IBusErrorHandler* handler, const TBusSessionConfig& config, const TString& name) - : TActor<TBusSessionImpl, TStatusTag>(queue->WorkQueue.Get()) - , TActor<TBusSessionImpl, TConnectionTag>(queue->WorkQueue.Get()) - , Impl(new TImpl) + : TActor<TBusSessionImpl, TStatusTag>(queue->WorkQueue.Get()) + , TActor<TBusSessionImpl, TConnectionTag>(queue->WorkQueue.Get()) + , Impl(new TImpl) , IsSource_(isSource) - , Queue(queue) - , Proto(proto) - , ProtoName(Proto->GetService()) - , ErrorHandler(handler) - , HandlerUseCountHolder(&handler->UseCountChecker) - , Config(SessionConfigFillDefaults(config, name)) - , WriteEventLoop("wr-el") - , ReadEventLoop("rd-el") - , LastAcceptorId(0) - , LastConnectionId(0) + , Queue(queue) + , Proto(proto) + , ProtoName(Proto->GetService()) + , ErrorHandler(handler) + , HandlerUseCountHolder(&handler->UseCountChecker) + , Config(SessionConfigFillDefaults(config, name)) + , WriteEventLoop("wr-el") + , ReadEventLoop("rd-el") + , LastAcceptorId(0) + , LastConnectionId(0) , Down(0) { - Impl->DeadAcceptorStatusSummary.Summary = true; - + Impl->DeadAcceptorStatusSummary.Summary = true; + ReadEventLoopThread.Reset(new NThreading::TLegacyFuture<void, false>(std::bind(&TEventLoop::Run, std::ref(ReadEventLoop)))); WriteEventLoopThread.Reset(new NThreading::TLegacyFuture<void, false>(std::bind(&TEventLoop::Run, std::ref(WriteEventLoop)))); - - Queue->Schedule(IScheduleItemAutoPtr(new TScheduleSession(this, TInstant::Now() + Config.Secret.TimeoutPeriod))); + + Queue->Schedule(IScheduleItemAutoPtr(new TScheduleSession(this, TInstant::Now() + Config.Secret.TimeoutPeriod))); } -TBusSessionImpl::~TBusSessionImpl() { +TBusSessionImpl::~TBusSessionImpl() { Y_VERIFY(Down); Y_VERIFY(ShutdownCompleteEvent.WaitT(TDuration::Zero())); Y_VERIFY(!WriteEventLoop.IsRunning()); Y_VERIFY(!ReadEventLoop.IsRunning()); -} - -TBusSessionStatus::TBusSessionStatus() - : InFlightCount(0) - , InFlightSize(0) - , InputPaused(false) +} + +TBusSessionStatus::TBusSessionStatus() + : InFlightCount(0) + , InFlightSize(0) + , InputPaused(false) { } - -void TBusSessionImpl::Shutdown() { - if (!AtomicCas(&Down, 1, 0)) { - ShutdownCompleteEvent.WaitI(); - return; - } - + +void TBusSessionImpl::Shutdown() { + if (!AtomicCas(&Down, 1, 0)) { + ShutdownCompleteEvent.WaitI(); + return; + } + Y_VERIFY(Queue->IsRunning(), "Session must be shut down prior to queue shutdown"); - - TUseAfterFreeCheckerGuard handlerAliveCheckedGuard(ErrorHandler->UseAfterFreeChecker); - - // For legacy clients that don't use smart pointers - TIntrusivePtr<TBusSessionImpl> thiz(this); - - Queue->Remove(this); - - // shutdown event loops first, so they won't send more events - // to acceptors and connections - ReadEventLoop.Stop(); - WriteEventLoop.Stop(); - ReadEventLoopThread->Get(); - WriteEventLoopThread->Get(); - - // shutdown acceptors before connections - // so they won't create more connections + + TUseAfterFreeCheckerGuard handlerAliveCheckedGuard(ErrorHandler->UseAfterFreeChecker); + + // For legacy clients that don't use smart pointers + TIntrusivePtr<TBusSessionImpl> thiz(this); + + Queue->Remove(this); + + // shutdown event loops first, so they won't send more events + // to acceptors and connections + ReadEventLoop.Stop(); + WriteEventLoop.Stop(); + ReadEventLoopThread->Get(); + WriteEventLoopThread->Get(); + + // shutdown acceptors before connections + // so they won't create more connections TVector<TAcceptorPtr> acceptors; - GetAcceptors(&acceptors); - { - TGuard<TMutex> guard(ConnectionsLock); - Acceptors.clear(); - } + GetAcceptors(&acceptors); + { + TGuard<TMutex> guard(ConnectionsLock); + Acceptors.clear(); + } for (auto& acceptor : acceptors) { acceptor->Shutdown(); } - // shutdown connections + // shutdown connections TVector<TRemoteConnectionPtr> cs; - GetConnections(&cs); - + GetConnections(&cs); + for (auto& c : cs) { c->Shutdown(MESSAGE_SHUTDOWN); - } - - // shutdown connections actor - // must shutdown after connections destroyed - ConnectionsData.ShutdownState.ShutdownCommand(); - GetConnectionsActor()->Schedule(); - ConnectionsData.ShutdownState.ShutdownComplete.WaitI(); - - // finally shutdown status actor - StatusData.ShutdownState.ShutdownCommand(); - GetStatusActor()->Schedule(); - StatusData.ShutdownState.ShutdownComplete.WaitI(); - - // Make sure no one references IMessageHandler after Shutdown() - JobCount.WaitForZero(); - HandlerUseCountHolder.Reset(); - - ShutdownCompleteEvent.Signal(); -} - -bool TBusSessionImpl::IsDown() { + } + + // shutdown connections actor + // must shutdown after connections destroyed + ConnectionsData.ShutdownState.ShutdownCommand(); + GetConnectionsActor()->Schedule(); + ConnectionsData.ShutdownState.ShutdownComplete.WaitI(); + + // finally shutdown status actor + StatusData.ShutdownState.ShutdownCommand(); + GetStatusActor()->Schedule(); + StatusData.ShutdownState.ShutdownComplete.WaitI(); + + // Make sure no one references IMessageHandler after Shutdown() + JobCount.WaitForZero(); + HandlerUseCountHolder.Reset(); + + ShutdownCompleteEvent.Signal(); +} + +bool TBusSessionImpl::IsDown() { return static_cast<bool>(AtomicGet(Down)); } -size_t TBusSessionImpl::GetInFlightImpl(const TNetAddr& addr) const { - TRemoteConnectionPtr conn = const_cast<TBusSessionImpl*>(this)->GetConnection(addr, false); - if (!!conn) { - return conn->GetInFlight(); - } else { - return 0; - } +size_t TBusSessionImpl::GetInFlightImpl(const TNetAddr& addr) const { + TRemoteConnectionPtr conn = const_cast<TBusSessionImpl*>(this)->GetConnection(addr, false); + if (!!conn) { + return conn->GetInFlight(); + } else { + return 0; + } } void TBusSessionImpl::GetInFlightBulk(TArrayRef<const TNetAddr> addrs, TArrayRef<size_t> results) const { Y_VERIFY(addrs.size() == results.size(), "input.size != output.size"); - for (size_t i = 0; i < addrs.size(); ++i) { - results[i] = GetInFlightImpl(addrs[i]); - } -} - + for (size_t i = 0; i < addrs.size(); ++i) { + results[i] = GetInFlightImpl(addrs[i]); + } +} + size_t TBusSessionImpl::GetConnectSyscallsNumForTestImpl(const TNetAddr& addr) const { TRemoteConnectionPtr conn = const_cast<TBusSessionImpl*>(this)->GetConnection(addr, false); if (!!conn) { @@ -227,26 +227,26 @@ void TBusSessionImpl::GetConnectSyscallsNumBulkForTest(TArrayRef<const TNetAddr> } } -void TBusSessionImpl::FillStatus() { -} - -TSessionDumpStatus TBusSessionImpl::GetStatusRecordInternal() { - // Probably useless, because it returns cached info now +void TBusSessionImpl::FillStatus() { +} + +TSessionDumpStatus TBusSessionImpl::GetStatusRecordInternal() { + // Probably useless, because it returns cached info now Y_VERIFY(!Queue->GetExecutor()->IsInExecutorThread(), "GetStatus must not be called from executor thread"); - - TGuard<TMutex> guard(StatusData.StatusDumpCachedMutex); - // TODO: returns zeros for a second after start - // (until first cron) - return StatusData.StatusDumpCached; -} - + + TGuard<TMutex> guard(StatusData.StatusDumpCachedMutex); + // TODO: returns zeros for a second after start + // (until first cron) + return StatusData.StatusDumpCached; +} + TString TBusSessionImpl::GetStatus(ui16 flags) { Y_UNUSED(flags); - - return GetStatusRecordInternal().PrintToString(); -} - + + return GetStatusRecordInternal().PrintToString(); +} + TConnectionStatusMonRecord TBusSessionImpl::GetStatusProtobuf() { Y_VERIFY(!Queue->GetExecutor()->IsInExecutorThread(), "GetStatus must not be called from executor thread"); @@ -257,233 +257,233 @@ TConnectionStatusMonRecord TBusSessionImpl::GetStatusProtobuf() { } TString TBusSessionImpl::GetStatusSingleLine() { - TSessionDumpStatus status = GetStatusRecordInternal(); - - TStringStream ss; - ss << "in-flight: " << status.Status.InFlightCount; - if (IsSource_) { - ss << " ack: " << status.ConnectionStatusSummary.WriterStatus.AckMessagesSize; - } - ss << " send-q: " << status.ConnectionStatusSummary.WriterStatus.SendQueueSize; - return ss.Str(); -} - -void TBusSessionImpl::ProcessItem(TStatusTag, TDeadConnectionTag, const TRemoteConnectionWriterIncrementalStatus& connectionStatus) { - Impl->DeadConnectionWriterStatusSummary += connectionStatus; -} - -void TBusSessionImpl::ProcessItem(TStatusTag, TDeadConnectionTag, const TRemoteConnectionReaderIncrementalStatus& connectionStatus) { - Impl->DeadConnectionReaderStatusSummary += connectionStatus; -} - -void TBusSessionImpl::ProcessItem(TStatusTag, TDeadConnectionTag, const TAcceptorStatus& acceptorStatus) { - Impl->DeadAcceptorStatusSummary += acceptorStatus; -} - -void TBusSessionImpl::ProcessItem(TConnectionTag, ::NActor::TDefaultTag, const TOnAccept& onAccept) { - TSocketHolder socket(onAccept.s); - - if (AtomicGet(Down)) { - // do not create connections after shutdown initiated - return; - } - - //if (Connections.find(addr) != Connections.end()) { + TSessionDumpStatus status = GetStatusRecordInternal(); + + TStringStream ss; + ss << "in-flight: " << status.Status.InFlightCount; + if (IsSource_) { + ss << " ack: " << status.ConnectionStatusSummary.WriterStatus.AckMessagesSize; + } + ss << " send-q: " << status.ConnectionStatusSummary.WriterStatus.SendQueueSize; + return ss.Str(); +} + +void TBusSessionImpl::ProcessItem(TStatusTag, TDeadConnectionTag, const TRemoteConnectionWriterIncrementalStatus& connectionStatus) { + Impl->DeadConnectionWriterStatusSummary += connectionStatus; +} + +void TBusSessionImpl::ProcessItem(TStatusTag, TDeadConnectionTag, const TRemoteConnectionReaderIncrementalStatus& connectionStatus) { + Impl->DeadConnectionReaderStatusSummary += connectionStatus; +} + +void TBusSessionImpl::ProcessItem(TStatusTag, TDeadConnectionTag, const TAcceptorStatus& acceptorStatus) { + Impl->DeadAcceptorStatusSummary += acceptorStatus; +} + +void TBusSessionImpl::ProcessItem(TConnectionTag, ::NActor::TDefaultTag, const TOnAccept& onAccept) { + TSocketHolder socket(onAccept.s); + + if (AtomicGet(Down)) { + // do not create connections after shutdown initiated + return; + } + + //if (Connections.find(addr) != Connections.end()) { // TODO: it is possible // won't be a problem after socket address replaced with id - //} - - TRemoteConnectionPtr c(new TRemoteServerConnection(VerifyDynamicCast<TRemoteServerSession*>(this), ++LastConnectionId, onAccept.addr)); - - VerifyDynamicCast<TRemoteServerConnection*>(c.Get())->Init(socket.Release(), onAccept.now); - - InsertConnectionLockAcquired(c.Get()); -} - -void TBusSessionImpl::ProcessItem(TConnectionTag, TRemoveTag, TRemoteConnectionPtr c) { - TAddrRemoteConnections::iterator it1 = Connections.find(c->PeerAddrSocketAddr); - if (it1 != Connections.end()) { - if (it1->second.Get() == c.Get()) { - Connections.erase(it1); - } - } - + //} + + TRemoteConnectionPtr c(new TRemoteServerConnection(VerifyDynamicCast<TRemoteServerSession*>(this), ++LastConnectionId, onAccept.addr)); + + VerifyDynamicCast<TRemoteServerConnection*>(c.Get())->Init(socket.Release(), onAccept.now); + + InsertConnectionLockAcquired(c.Get()); +} + +void TBusSessionImpl::ProcessItem(TConnectionTag, TRemoveTag, TRemoteConnectionPtr c) { + TAddrRemoteConnections::iterator it1 = Connections.find(c->PeerAddrSocketAddr); + if (it1 != Connections.end()) { + if (it1->second.Get() == c.Get()) { + Connections.erase(it1); + } + } + THashMap<ui64, TRemoteConnectionPtr>::iterator it2 = ConnectionsById.find(c->ConnectionId); - if (it2 != ConnectionsById.end()) { - ConnectionsById.erase(it2); - } - - SendSnapshotToStatusActor(); -} - + if (it2 != ConnectionsById.end()) { + ConnectionsById.erase(it2); + } + + SendSnapshotToStatusActor(); +} + void TBusSessionImpl::ProcessConnectionsAcceptorsShapshotQueueItem(TAtomicSharedPtr<TConnectionsAcceptorsSnapshot> snapshot) { for (TVector<TRemoteConnectionPtr>::const_iterator connection = snapshot->Connections.begin(); connection != snapshot->Connections.end(); ++connection) { Y_ASSERT((*connection)->ConnectionId <= snapshot->LastConnectionId); - } - + } + for (TVector<TAcceptorPtr>::const_iterator acceptor = snapshot->Acceptors.begin(); acceptor != snapshot->Acceptors.end(); ++acceptor) { Y_ASSERT((*acceptor)->AcceptorId <= snapshot->LastAcceptorId); - } - - StatusData.ConnectionsAcceptorsSnapshot = snapshot; -} - -void TBusSessionImpl::StatusUpdateCachedDumpIfNecessary(TInstant now) { - if (now - StatusData.StatusDumpCachedLastUpdate > Config.Secret.StatusFlushPeriod) { - StatusUpdateCachedDump(); - StatusData.StatusDumpCachedLastUpdate = now; - } -} - -void TBusSessionImpl::StatusUpdateCachedDump() { - TSessionDumpStatus r; - - if (AtomicGet(Down)) { - r.Shutdown = true; - TGuard<TMutex> guard(StatusData.StatusDumpCachedMutex); - StatusData.StatusDumpCached = r; - return; - } - - // TODO: make thread-safe - FillStatus(); - - r.Status = StatusData.Status; - - { - TStringStream ss; - + } + + StatusData.ConnectionsAcceptorsSnapshot = snapshot; +} + +void TBusSessionImpl::StatusUpdateCachedDumpIfNecessary(TInstant now) { + if (now - StatusData.StatusDumpCachedLastUpdate > Config.Secret.StatusFlushPeriod) { + StatusUpdateCachedDump(); + StatusData.StatusDumpCachedLastUpdate = now; + } +} + +void TBusSessionImpl::StatusUpdateCachedDump() { + TSessionDumpStatus r; + + if (AtomicGet(Down)) { + r.Shutdown = true; + TGuard<TMutex> guard(StatusData.StatusDumpCachedMutex); + StatusData.StatusDumpCached = r; + return; + } + + // TODO: make thread-safe + FillStatus(); + + r.Status = StatusData.Status; + + { + TStringStream ss; + TString name = Config.Name; - if (!name) { - name = "unnamed"; - } - - ss << (IsSource_ ? "client" : "server") << " session " << name << ", proto " << Proto->GetService() << Endl; - ss << "in flight: " << r.Status.InFlightCount; - if (!IsSource_) { - ss << ", " << r.Status.InFlightSize << "b"; - } - if (r.Status.InputPaused) { - ss << " (input paused)"; - } - ss << "\n"; - - r.Head = ss.Str(); - } - + if (!name) { + name = "unnamed"; + } + + ss << (IsSource_ ? "client" : "server") << " session " << name << ", proto " << Proto->GetService() << Endl; + ss << "in flight: " << r.Status.InFlightCount; + if (!IsSource_) { + ss << ", " << r.Status.InFlightSize << "b"; + } + if (r.Status.InputPaused) { + ss << " (input paused)"; + } + ss << "\n"; + + r.Head = ss.Str(); + } + TVector<TRemoteConnectionPtr>& connections = StatusData.ConnectionsAcceptorsSnapshot->Connections; TVector<TAcceptorPtr>& acceptors = StatusData.ConnectionsAcceptorsSnapshot->Acceptors; - - r.ConnectionStatusSummary = TRemoteConnectionStatus(); - r.ConnectionStatusSummary.Summary = true; - r.ConnectionStatusSummary.Server = !IsSource_; - r.ConnectionStatusSummary.WriterStatus.Incremental = Impl->DeadConnectionWriterStatusSummary; - r.ConnectionStatusSummary.ReaderStatus.Incremental = Impl->DeadConnectionReaderStatusSummary; - - TAcceptorStatus acceptorStatusSummary = Impl->DeadAcceptorStatusSummary; - - { - TStringStream ss; - + + r.ConnectionStatusSummary = TRemoteConnectionStatus(); + r.ConnectionStatusSummary.Summary = true; + r.ConnectionStatusSummary.Server = !IsSource_; + r.ConnectionStatusSummary.WriterStatus.Incremental = Impl->DeadConnectionWriterStatusSummary; + r.ConnectionStatusSummary.ReaderStatus.Incremental = Impl->DeadConnectionReaderStatusSummary; + + TAcceptorStatus acceptorStatusSummary = Impl->DeadAcceptorStatusSummary; + + { + TStringStream ss; + for (TVector<TAcceptorPtr>::const_iterator acceptor = acceptors.begin(); acceptor != acceptors.end(); ++acceptor) { const TAcceptorStatus status = (*acceptor)->GranStatus.Listen.Get(); acceptorStatusSummary += status; - if (acceptor != acceptors.begin()) { - ss << "\n"; - } + if (acceptor != acceptors.begin()) { + ss << "\n"; + } ss << status.PrintToString(); - } - - r.Acceptors = ss.Str(); - } - - { - TStringStream ss; - + } + + r.Acceptors = ss.Str(); + } + + { + TStringStream ss; + for (TVector<TRemoteConnectionPtr>::const_iterator connection = connections.begin(); connection != connections.end(); ++connection) { - if (connection != connections.begin()) { - ss << "\n"; - } + if (connection != connections.begin()) { + ss << "\n"; + } - TRemoteConnectionStatus status; - status.Server = !IsSource_; + TRemoteConnectionStatus status; + status.Server = !IsSource_; status.ReaderStatus = (*connection)->GranStatus.Reader.Get(); status.WriterStatus = (*connection)->GranStatus.Writer.Get(); - ss << status.PrintToString(); + ss << status.PrintToString(); r.ConnectionStatusSummary.ReaderStatus += status.ReaderStatus; r.ConnectionStatusSummary.WriterStatus += status.WriterStatus; - } - + } + r.ConnectionsSummary = r.ConnectionStatusSummary.PrintToString(); - r.Connections = ss.Str(); - } - - r.Config = Config; - - TGuard<TMutex> guard(StatusData.StatusDumpCachedMutex); - StatusData.StatusDumpCached = r; -} - -TBusSessionImpl::TStatusData::TStatusData() - : ConnectionsAcceptorsSnapshot(new TConnectionsAcceptorsSnapshot) + r.Connections = ss.Str(); + } + + r.Config = Config; + + TGuard<TMutex> guard(StatusData.StatusDumpCachedMutex); + StatusData.StatusDumpCached = r; +} + +TBusSessionImpl::TStatusData::TStatusData() + : ConnectionsAcceptorsSnapshot(new TConnectionsAcceptorsSnapshot) { } - -void TBusSessionImpl::Act(TStatusTag) { - TInstant now = TInstant::Now(); - - EShutdownState shutdownState = StatusData.ShutdownState.State.Get(); - + +void TBusSessionImpl::Act(TStatusTag) { + TInstant now = TInstant::Now(); + + EShutdownState shutdownState = StatusData.ShutdownState.State.Get(); + StatusData.ConnectionsAcceptorsSnapshotsQueue.DequeueAllLikelyEmpty(std::bind(&TBusSessionImpl::ProcessConnectionsAcceptorsShapshotQueueItem, this, std::placeholders::_1)); - - GetDeadConnectionWriterStatusQueue()->DequeueAllLikelyEmpty(); - GetDeadConnectionReaderStatusQueue()->DequeueAllLikelyEmpty(); - GetDeadAcceptorStatusQueue()->DequeueAllLikelyEmpty(); - - // TODO: check queues are empty if already stopped - - if (shutdownState != SS_RUNNING) { - // important to beak cyclic link session -> connection -> session - StatusData.ConnectionsAcceptorsSnapshot->Connections.clear(); - StatusData.ConnectionsAcceptorsSnapshot->Acceptors.clear(); - } - - if (shutdownState == SS_SHUTDOWN_COMMAND) { - StatusData.ShutdownState.CompleteShutdown(); - } - - StatusUpdateCachedDumpIfNecessary(now); -} - + + GetDeadConnectionWriterStatusQueue()->DequeueAllLikelyEmpty(); + GetDeadConnectionReaderStatusQueue()->DequeueAllLikelyEmpty(); + GetDeadAcceptorStatusQueue()->DequeueAllLikelyEmpty(); + + // TODO: check queues are empty if already stopped + + if (shutdownState != SS_RUNNING) { + // important to beak cyclic link session -> connection -> session + StatusData.ConnectionsAcceptorsSnapshot->Connections.clear(); + StatusData.ConnectionsAcceptorsSnapshot->Acceptors.clear(); + } + + if (shutdownState == SS_SHUTDOWN_COMMAND) { + StatusData.ShutdownState.CompleteShutdown(); + } + + StatusUpdateCachedDumpIfNecessary(now); +} + TBusSessionImpl::TConnectionsData::TConnectionsData() { } - -void TBusSessionImpl::Act(TConnectionTag) { - TConnectionsGuard guard(ConnectionsLock); - - EShutdownState shutdownState = ConnectionsData.ShutdownState.State.Get(); - if (shutdownState == SS_SHUTDOWN_COMPLETE) { + +void TBusSessionImpl::Act(TConnectionTag) { + TConnectionsGuard guard(ConnectionsLock); + + EShutdownState shutdownState = ConnectionsData.ShutdownState.State.Get(); + if (shutdownState == SS_SHUTDOWN_COMPLETE) { Y_VERIFY(GetRemoveConnectionQueue()->IsEmpty()); Y_VERIFY(GetOnAcceptQueue()->IsEmpty()); - } - - GetRemoveConnectionQueue()->DequeueAllLikelyEmpty(); - GetOnAcceptQueue()->DequeueAllLikelyEmpty(); - - if (shutdownState == SS_SHUTDOWN_COMMAND) { - ConnectionsData.ShutdownState.CompleteShutdown(); - } -} - -void TBusSessionImpl::Listen(int port, TBusMessageQueue* q) { + } + + GetRemoveConnectionQueue()->DequeueAllLikelyEmpty(); + GetOnAcceptQueue()->DequeueAllLikelyEmpty(); + + if (shutdownState == SS_SHUTDOWN_COMMAND) { + ConnectionsData.ShutdownState.CompleteShutdown(); + } +} + +void TBusSessionImpl::Listen(int port, TBusMessageQueue* q) { Listen(BindOnPort(port, Config.ReusePort).second, q); } @@ -494,116 +494,116 @@ void TBusSessionImpl::Listen(const TVector<TBindResult>& bindTo, TBusMessageQueu for (const TBindResult& br : bindTo) { if (actualPort == -1) { actualPort = br.Addr.GetPort(); - } else { + } else { Y_VERIFY(actualPort == br.Addr.GetPort(), "state check"); - } + } if (Config.SocketToS >= 0) { SetSocketToS(*br.Socket, &(br.Addr), Config.SocketToS); } - + TAcceptorPtr acceptor(new TAcceptor(this, ++LastAcceptorId, br.Socket->Release(), br.Addr)); - TConnectionsGuard guard(ConnectionsLock); - InsertAcceptorLockAcquired(acceptor.Get()); + TConnectionsGuard guard(ConnectionsLock); + InsertAcceptorLockAcquired(acceptor.Get()); } - - Config.ListenPort = actualPort; + + Config.ListenPort = actualPort; } -void TBusSessionImpl::SendSnapshotToStatusActor() { +void TBusSessionImpl::SendSnapshotToStatusActor() { //Y_ASSERT(ConnectionsLock.IsLocked()); - + TAtomicSharedPtr<TConnectionsAcceptorsSnapshot> snapshot(new TConnectionsAcceptorsSnapshot); - GetAcceptorsLockAquired(&snapshot->Acceptors); - GetConnectionsLockAquired(&snapshot->Connections); - snapshot->LastAcceptorId = LastAcceptorId; - snapshot->LastConnectionId = LastConnectionId; - StatusData.ConnectionsAcceptorsSnapshotsQueue.Enqueue(snapshot); - GetStatusActor()->Schedule(); -} - -void TBusSessionImpl::InsertConnectionLockAcquired(TRemoteConnection* connection) { + GetAcceptorsLockAquired(&snapshot->Acceptors); + GetConnectionsLockAquired(&snapshot->Connections); + snapshot->LastAcceptorId = LastAcceptorId; + snapshot->LastConnectionId = LastConnectionId; + StatusData.ConnectionsAcceptorsSnapshotsQueue.Enqueue(snapshot); + GetStatusActor()->Schedule(); +} + +void TBusSessionImpl::InsertConnectionLockAcquired(TRemoteConnection* connection) { //Y_ASSERT(ConnectionsLock.IsLocked()); - + Connections.insert(std::make_pair(connection->PeerAddrSocketAddr, connection)); - // connection for given adds may already exist at this point - // (so we overwrite old connection) - // after reconnect, if previous connections wasn't shutdown yet - + // connection for given adds may already exist at this point + // (so we overwrite old connection) + // after reconnect, if previous connections wasn't shutdown yet + bool inserted2 = ConnectionsById.insert(std::make_pair(connection->ConnectionId, connection)).second; Y_VERIFY(inserted2, "state check: must be inserted (2)"); - - SendSnapshotToStatusActor(); -} - -void TBusSessionImpl::InsertAcceptorLockAcquired(TAcceptor* acceptor) { + + SendSnapshotToStatusActor(); +} + +void TBusSessionImpl::InsertAcceptorLockAcquired(TAcceptor* acceptor) { //Y_ASSERT(ConnectionsLock.IsLocked()); - - Acceptors.push_back(acceptor); - - SendSnapshotToStatusActor(); -} - + + Acceptors.push_back(acceptor); + + SendSnapshotToStatusActor(); +} + void TBusSessionImpl::GetConnections(TVector<TRemoteConnectionPtr>* r) { - TConnectionsGuard guard(ConnectionsLock); - GetConnectionsLockAquired(r); -} - + TConnectionsGuard guard(ConnectionsLock); + GetConnectionsLockAquired(r); +} + void TBusSessionImpl::GetAcceptors(TVector<TAcceptorPtr>* r) { - TConnectionsGuard guard(ConnectionsLock); - GetAcceptorsLockAquired(r); -} - + TConnectionsGuard guard(ConnectionsLock); + GetAcceptorsLockAquired(r); +} + void TBusSessionImpl::GetConnectionsLockAquired(TVector<TRemoteConnectionPtr>* r) { //Y_ASSERT(ConnectionsLock.IsLocked()); - - r->reserve(Connections.size()); - + + r->reserve(Connections.size()); + for (auto& connection : Connections) { r->push_back(connection.second); - } -} - + } +} + void TBusSessionImpl::GetAcceptorsLockAquired(TVector<TAcceptorPtr>* r) { //Y_ASSERT(ConnectionsLock.IsLocked()); - - r->reserve(Acceptors.size()); - + + r->reserve(Acceptors.size()); + for (auto& acceptor : Acceptors) { r->push_back(acceptor); - } -} - -TRemoteConnectionPtr TBusSessionImpl::GetConnectionById(ui64 id) { - TConnectionsGuard guard(ConnectionsLock); - + } +} + +TRemoteConnectionPtr TBusSessionImpl::GetConnectionById(ui64 id) { + TConnectionsGuard guard(ConnectionsLock); + THashMap<ui64, TRemoteConnectionPtr>::const_iterator it = ConnectionsById.find(id); - if (it == ConnectionsById.end()) { + if (it == ConnectionsById.end()) { return nullptr; - } else { - return it->second; - } -} - -TAcceptorPtr TBusSessionImpl::GetAcceptorById(ui64 id) { - TGuard<TMutex> guard(ConnectionsLock); - + } else { + return it->second; + } +} + +TAcceptorPtr TBusSessionImpl::GetAcceptorById(ui64 id) { + TGuard<TMutex> guard(ConnectionsLock); + for (const auto& Acceptor : Acceptors) { if (Acceptor->AcceptorId == id) { return Acceptor; - } - } - + } + } + return nullptr; -} - -void TBusSessionImpl::InvokeOnError(TNonDestroyingAutoPtr<TBusMessage> message, EMessageStatus status) { - message->CheckClean(); - ErrorHandler->OnError(message, status); -} - -TRemoteConnectionPtr TBusSessionImpl::GetConnection(const TBusSocketAddr& addr, bool create) { - TConnectionsGuard guard(ConnectionsLock); +} + +void TBusSessionImpl::InvokeOnError(TNonDestroyingAutoPtr<TBusMessage> message, EMessageStatus status) { + message->CheckClean(); + ErrorHandler->OnError(message, status); +} + +TRemoteConnectionPtr TBusSessionImpl::GetConnection(const TBusSocketAddr& addr, bool create) { + TConnectionsGuard guard(ConnectionsLock); TAddrRemoteConnections::const_iterator it = Connections.find(addr); if (it != Connections.end()) { @@ -615,36 +615,36 @@ TRemoteConnectionPtr TBusSessionImpl::GetConnection(const TBusSocketAddr& addr, } Y_VERIFY(IsSource_, "must be source"); - - TRemoteConnectionPtr c(new TRemoteClientConnection(VerifyDynamicCast<TRemoteClientSession*>(this), ++LastConnectionId, addr.ToNetAddr())); - InsertConnectionLockAcquired(c.Get()); + + TRemoteConnectionPtr c(new TRemoteClientConnection(VerifyDynamicCast<TRemoteClientSession*>(this), ++LastConnectionId, addr.ToNetAddr())); + InsertConnectionLockAcquired(c.Get()); return c; } -void TBusSessionImpl::Cron() { +void TBusSessionImpl::Cron() { TVector<TRemoteConnectionPtr> connections; - GetConnections(&connections); - + GetConnections(&connections); + for (const auto& it : connections) { TRemoteConnection* connection = it.Get(); - if (IsSource_) { - VerifyDynamicCast<TRemoteClientConnection*>(connection)->ScheduleTimeoutMessages(); - } else { - VerifyDynamicCast<TRemoteServerConnection*>(connection)->WriterData.TimeToRotateCounters.AddTask(); - // no schedule: do not rotate if there's no traffic - } - } - - // status updates are sent without scheduling - GetStatusActor()->Schedule(); - - Queue->Schedule(IScheduleItemAutoPtr(new TScheduleSession(this, TInstant::Now() + Config.Secret.TimeoutPeriod))); -} - + if (IsSource_) { + VerifyDynamicCast<TRemoteClientConnection*>(connection)->ScheduleTimeoutMessages(); + } else { + VerifyDynamicCast<TRemoteServerConnection*>(connection)->WriterData.TimeToRotateCounters.AddTask(); + // no schedule: do not rotate if there's no traffic + } + } + + // status updates are sent without scheduling + GetStatusActor()->Schedule(); + + Queue->Schedule(IScheduleItemAutoPtr(new TScheduleSession(this, TInstant::Now() + Config.Secret.TimeoutPeriod))); +} + TString TBusSessionImpl::GetNameInternal() { - if (!!Config.Name) { - return Config.Name; - } - return ProtoName; -} + if (!!Config.Name) { + return Config.Name; + } + return ProtoName; +} diff --git a/library/cpp/messagebus/session_impl.h b/library/cpp/messagebus/session_impl.h index 0c6fec1af4..90ef246ff8 100644 --- a/library/cpp/messagebus/session_impl.h +++ b/library/cpp/messagebus/session_impl.h @@ -3,17 +3,17 @@ #include "acceptor_status.h" #include "async_result.h" #include "event_loop.h" -#include "netaddr.h" +#include "netaddr.h" #include "remote_connection.h" -#include "remote_connection_status.h" -#include "session_job_count.h" -#include "shutdown_state.h" +#include "remote_connection_status.h" +#include "session_job_count.h" +#include "shutdown_state.h" #include "ybus.h" #include <library/cpp/messagebus/actor/actor.h> #include <library/cpp/messagebus/actor/queue_in_actor.h> #include <library/cpp/messagebus/monitoring/mon_proto.pb.h> - + #include <library/cpp/threading/future/legacy_future.h> #include <util/generic/array_ref.h> @@ -23,12 +23,12 @@ namespace NBus { namespace NPrivate { typedef TIntrusivePtr<TRemoteClientConnection> TRemoteClientConnectionPtr; typedef TIntrusivePtr<TRemoteServerConnection> TRemoteServerConnectionPtr; - + typedef TIntrusivePtr<TRemoteServerSession> TRemoteServerSessionPtr; typedef TIntrusivePtr<TAcceptor> TAcceptorPtr; typedef TVector<TAcceptorPtr> TAcceptorsPtrs; - + struct TConnectionsAcceptorsSnapshot { TVector<TRemoteConnectionPtr> Connections; TVector<TAcceptorPtr> Acceptors; @@ -37,31 +37,31 @@ namespace NBus { TConnectionsAcceptorsSnapshot(); }; - + typedef TAtomicSharedPtr<TConnectionsAcceptorsSnapshot> TConnectionsAcceptorsSnapshotPtr; - + struct TOnAccept { SOCKET s; TNetAddr addr; TInstant now; }; - + struct TStatusTag {}; struct TConnectionTag {}; - + struct TDeadConnectionTag {}; struct TRemoveTag {}; - + struct TBusSessionImpl : public virtual TBusSession, private ::NActor::TActor<TBusSessionImpl, TStatusTag>, private ::NActor::TActor<TBusSessionImpl, TConnectionTag> - + , private ::NActor::TQueueInActor<TBusSessionImpl, TRemoteConnectionWriterIncrementalStatus, TStatusTag, TDeadConnectionTag>, private ::NActor::TQueueInActor<TBusSessionImpl, TRemoteConnectionReaderIncrementalStatus, TStatusTag, TDeadConnectionTag>, private ::NActor::TQueueInActor<TBusSessionImpl, TAcceptorStatus, TStatusTag, TDeadConnectionTag> - + , private ::NActor::TQueueInActor<TBusSessionImpl, TOnAccept, TConnectionTag>, private ::NActor::TQueueInActor<TBusSessionImpl, TRemoteConnectionPtr, TConnectionTag, TRemoveTag> { @@ -75,43 +75,43 @@ namespace NBus { friend class ::NActor::TQueueInActor<TBusSessionImpl, TAcceptorStatus, TStatusTag, TDeadConnectionTag>; friend class ::NActor::TQueueInActor<TBusSessionImpl, TOnAccept, TConnectionTag>; friend class ::NActor::TQueueInActor<TBusSessionImpl, TRemoteConnectionPtr, TConnectionTag, TRemoveTag>; - + public: ::NActor::TQueueInActor<TBusSessionImpl, TOnAccept, TConnectionTag>* GetOnAcceptQueue() { return this; } - + ::NActor::TQueueInActor<TBusSessionImpl, TRemoteConnectionPtr, TConnectionTag, TRemoveTag>* GetRemoveConnectionQueue() { return this; } - + ::NActor::TActor<TBusSessionImpl, TConnectionTag>* GetConnectionActor() { return this; } - + typedef TGuard<TMutex> TConnectionsGuard; - + TBusSessionImpl(bool isSource, TBusMessageQueue* queue, TBusProtocol* proto, IBusErrorHandler* handler, const TBusSessionConfig& config, const TString& name); - + ~TBusSessionImpl() override; void Shutdown() override; bool IsDown(); - + size_t GetInFlightImpl(const TNetAddr& addr) const; size_t GetConnectSyscallsNumForTestImpl(const TNetAddr& addr) const; void GetInFlightBulk(TArrayRef<const TNetAddr> addrs, TArrayRef<size_t> results) const override; void GetConnectSyscallsNumBulkForTest(TArrayRef<const TNetAddr> addrs, TArrayRef<size_t> results) const override; - + virtual void FillStatus(); TSessionDumpStatus GetStatusRecordInternal() override; TString GetStatus(ui16 flags = YBUS_STATUS_CONNS) override; TConnectionStatusMonRecord GetStatusProtobuf() override; TString GetStatusSingleLine() override; - + void ProcessItem(TStatusTag, TDeadConnectionTag, const TRemoteConnectionWriterIncrementalStatus&); void ProcessItem(TStatusTag, TDeadConnectionTag, const TRemoteConnectionReaderIncrementalStatus&); void ProcessItem(TStatusTag, TDeadConnectionTag, const TAcceptorStatus&); @@ -128,7 +128,7 @@ namespace NBus { const TBusSessionConfig* GetConfig() const noexcept override; TBusMessageQueue* GetQueue() const noexcept override; TString GetNameInternal() override; - + virtual void OnMessageReceived(TRemoteConnection* c, TVectorSwaps<TBusMessagePtrAndHeader>& newMsg) = 0; void Listen(int port, TBusMessageQueue* q); @@ -143,106 +143,106 @@ namespace NBus { } typedef THashMap<TBusSocketAddr, TRemoteConnectionPtr> TAddrRemoteConnections; - + void SendSnapshotToStatusActor(); void InsertConnectionLockAcquired(TRemoteConnection* connection); void InsertAcceptorLockAcquired(TAcceptor* acceptor); - + void GetConnections(TVector<TRemoteConnectionPtr>*); void GetAcceptors(TVector<TAcceptorPtr>*); void GetConnectionsLockAquired(TVector<TRemoteConnectionPtr>*); void GetAcceptorsLockAquired(TVector<TAcceptorPtr>*); - + TRemoteConnectionPtr GetConnection(const TBusSocketAddr& addr, bool create); TRemoteConnectionPtr GetConnectionById(ui64 id); TAcceptorPtr GetAcceptorById(ui64 id); - + void InvokeOnError(TNonDestroyingAutoPtr<TBusMessage>, EMessageStatus); void Cron(); - + TBusSessionJobCount JobCount; - + // TODO: replace with actor TMutex ConnectionsLock; - + struct TImpl; THolder<TImpl> Impl; - + const bool IsSource_; - + TBusMessageQueue* const Queue; TBusProtocol* const Proto; // copied to be available after Proto dies const TString ProtoName; - + IBusErrorHandler* const ErrorHandler; TUseCountHolder HandlerUseCountHolder; TBusSessionConfig Config; // TODO: make const - + NEventLoop::TEventLoop WriteEventLoop; NEventLoop::TEventLoop ReadEventLoop; THolder<NThreading::TLegacyFuture<void, false>> ReadEventLoopThread; THolder<NThreading::TLegacyFuture<void, false>> WriteEventLoopThread; - + THashMap<ui64, TRemoteConnectionPtr> ConnectionsById; TAddrRemoteConnections Connections; TAcceptorsPtrs Acceptors; - + struct TStatusData { TAtomicSharedPtr<TConnectionsAcceptorsSnapshot> ConnectionsAcceptorsSnapshot; ::NActor::TQueueForActor<TAtomicSharedPtr<TConnectionsAcceptorsSnapshot>> ConnectionsAcceptorsSnapshotsQueue; TAtomicShutdownState ShutdownState; - + TBusSessionStatus Status; - + TSessionDumpStatus StatusDumpCached; TMutex StatusDumpCachedMutex; TInstant StatusDumpCachedLastUpdate; - + TStatusData(); }; TStatusData StatusData; - + struct TConnectionsData { TAtomicShutdownState ShutdownState; - + TConnectionsData(); }; TConnectionsData ConnectionsData; - + ::NActor::TQueueInActor<TBusSessionImpl, TRemoteConnectionWriterIncrementalStatus, TStatusTag, TDeadConnectionTag>* GetDeadConnectionWriterStatusQueue() { return this; } - + ::NActor::TQueueInActor<TBusSessionImpl, TRemoteConnectionReaderIncrementalStatus, TStatusTag, TDeadConnectionTag>* GetDeadConnectionReaderStatusQueue() { return this; } - + ::NActor::TQueueInActor<TBusSessionImpl, TAcceptorStatus, TStatusTag, TDeadConnectionTag>* GetDeadAcceptorStatusQueue() { return this; } - + template <typename TItem> ::NActor::IQueueInActor<TItem>* GetQueue() { return this; } - + ui64 LastAcceptorId; ui64 LastConnectionId; - + TAtomic Down; TSystemEvent ShutdownCompleteEvent; }; - + inline TBusProtocol* TBusSessionImpl::GetProto() const noexcept { return Proto; } diff --git a/library/cpp/messagebus/session_job_count.cpp b/library/cpp/messagebus/session_job_count.cpp index 768a3f5803..33322b1910 100644 --- a/library/cpp/messagebus/session_job_count.cpp +++ b/library/cpp/messagebus/session_job_count.cpp @@ -1,22 +1,22 @@ #include "session_job_count.h" -#include <util/system/yassert.h> - -using namespace NBus; -using namespace NBus::NPrivate; - -TBusSessionJobCount::TBusSessionJobCount() - : JobCount(0) +#include <util/system/yassert.h> + +using namespace NBus; +using namespace NBus::NPrivate; + +TBusSessionJobCount::TBusSessionJobCount() + : JobCount(0) { } - -TBusSessionJobCount::~TBusSessionJobCount() { + +TBusSessionJobCount::~TBusSessionJobCount() { Y_VERIFY(JobCount == 0, "must be 0 job count to destroy job"); -} - -void TBusSessionJobCount::WaitForZero() { - TGuard<TMutex> guard(Mutex); - while (AtomicGet(JobCount) > 0) { - CondVar.WaitI(Mutex); - } -} +} + +void TBusSessionJobCount::WaitForZero() { + TGuard<TMutex> guard(Mutex); + while (AtomicGet(JobCount) > 0) { + CondVar.WaitI(Mutex); + } +} diff --git a/library/cpp/messagebus/session_job_count.h b/library/cpp/messagebus/session_job_count.h index 4bdec4048f..23aca618b1 100644 --- a/library/cpp/messagebus/session_job_count.h +++ b/library/cpp/messagebus/session_job_count.h @@ -1,39 +1,39 @@ -#pragma once - -#include <util/system/atomic.h> +#pragma once + +#include <util/system/atomic.h> #include <util/system/condvar.h> -#include <util/system/mutex.h> - +#include <util/system/mutex.h> + namespace NBus { namespace NPrivate { class TBusSessionJobCount { private: TAtomic JobCount; - + TMutex Mutex; TCondVar CondVar; - + public: TBusSessionJobCount(); ~TBusSessionJobCount(); - + void Add(unsigned delta) { AtomicAdd(JobCount, delta); } - + void Increment() { Add(1); } - + void Decrement() { if (AtomicDecrement(JobCount) == 0) { TGuard<TMutex> guard(Mutex); CondVar.BroadCast(); } } - + void WaitForZero(); }; - - } + + } } diff --git a/library/cpp/messagebus/shutdown_state.cpp b/library/cpp/messagebus/shutdown_state.cpp index f99b62a6c9..a4e2bfa8b2 100644 --- a/library/cpp/messagebus/shutdown_state.cpp +++ b/library/cpp/messagebus/shutdown_state.cpp @@ -1,20 +1,20 @@ #include "shutdown_state.h" -#include <util/system/yassert.h> - +#include <util/system/yassert.h> + void TAtomicShutdownState::ShutdownCommand() { Y_VERIFY(State.CompareAndSet(SS_RUNNING, SS_SHUTDOWN_COMMAND)); -} - +} + void TAtomicShutdownState::CompleteShutdown() { Y_VERIFY(State.CompareAndSet(SS_SHUTDOWN_COMMAND, SS_SHUTDOWN_COMPLETE)); - ShutdownComplete.Signal(); -} - + ShutdownComplete.Signal(); +} + bool TAtomicShutdownState::IsRunning() { - return State.Get() == SS_RUNNING; -} - + return State.Get() == SS_RUNNING; +} + TAtomicShutdownState::~TAtomicShutdownState() { Y_VERIFY(SS_SHUTDOWN_COMPLETE == State.Get()); -} +} diff --git a/library/cpp/messagebus/shutdown_state.h b/library/cpp/messagebus/shutdown_state.h index 350c87d45d..86bd7110ae 100644 --- a/library/cpp/messagebus/shutdown_state.h +++ b/library/cpp/messagebus/shutdown_state.h @@ -1,22 +1,22 @@ -#pragma once - +#pragma once + #include "misc/atomic_box.h" -#include <util/system/event.h> - -enum EShutdownState { - SS_RUNNING, - SS_SHUTDOWN_COMMAND, - SS_SHUTDOWN_COMPLETE, -}; - -struct TAtomicShutdownState { - TAtomicBox<EShutdownState> State; +#include <util/system/event.h> + +enum EShutdownState { + SS_RUNNING, + SS_SHUTDOWN_COMMAND, + SS_SHUTDOWN_COMPLETE, +}; + +struct TAtomicShutdownState { + TAtomicBox<EShutdownState> State; TSystemEvent ShutdownComplete; - - void ShutdownCommand(); - void CompleteShutdown(); - bool IsRunning(); - - ~TAtomicShutdownState(); -}; + + void ShutdownCommand(); + void CompleteShutdown(); + bool IsRunning(); + + ~TAtomicShutdownState(); +}; diff --git a/library/cpp/messagebus/socket_addr.cpp b/library/cpp/messagebus/socket_addr.cpp index ef54da6603..c1b3a28fbe 100644 --- a/library/cpp/messagebus/socket_addr.cpp +++ b/library/cpp/messagebus/socket_addr.cpp @@ -1,23 +1,23 @@ #include "socket_addr.h" - -#include "netaddr.h" - + +#include "netaddr.h" + #include <util/network/address.h> #include <util/network/init.h> #include <util/system/yassert.h> - -using namespace NAddr; - -using namespace NBus; -using namespace NBus::NPrivate; - + +using namespace NAddr; + +using namespace NBus; +using namespace NBus::NPrivate; + static_assert(ADDR_UNSPEC == 0, "expect ADDR_UNSPEC == 0"); - -NBus::NPrivate::TBusSocketAddr::TBusSocketAddr(const NAddr::IRemoteAddr* addr) + +NBus::NPrivate::TBusSocketAddr::TBusSocketAddr(const NAddr::IRemoteAddr* addr) : IPv6ScopeID(0) -{ - const sockaddr* sa = addr->Addr(); - +{ + const sockaddr* sa = addr->Addr(); + switch ((EAddrFamily)sa->sa_family) { case AF_UNSPEC: { IpAddr.Clear(); @@ -37,24 +37,24 @@ NBus::NPrivate::TBusSocketAddr::TBusSocketAddr(const NAddr::IRemoteAddr* addr) } default: Y_FAIL("unknown address family"); - } -} - + } +} + NBus::NPrivate::TBusSocketAddr::TBusSocketAddr(TStringBuf host, unsigned port) { - *this = TNetAddr(host, port); -} - + *this = TNetAddr(host, port); +} + NBus::NPrivate::TBusSocketAddr::TBusSocketAddr(const TNetAddr& addr) { - *this = TBusSocketAddr(&addr); -} - + *this = TBusSocketAddr(&addr); +} + TNetAddr NBus::NPrivate::TBusSocketAddr::ToNetAddr() const { - sockaddr_storage storage; - Zero(storage); - + sockaddr_storage storage; + Zero(storage); + storage.ss_family = (ui16)IpAddr.GetAddrFamily(); - - switch (IpAddr.GetAddrFamily()) { + + switch (IpAddr.GetAddrFamily()) { case ADDR_UNSPEC: return TNetAddr(); case ADDR_IPV4: { @@ -68,12 +68,12 @@ TNetAddr NBus::NPrivate::TBusSocketAddr::ToNetAddr() const { ((sockaddr_in6*)&storage)->sin6_scope_id = HostToInet(IPv6ScopeID); break; } - } - + } + return TNetAddr(new TOpaqueAddr((sockaddr*)&storage)); -} - -template <> +} + +template <> void Out<TBusSocketAddr>(IOutputStream& out, const TBusSocketAddr& addr) { - out << addr.ToNetAddr(); -} + out << addr.ToNetAddr(); +} diff --git a/library/cpp/messagebus/socket_addr.h b/library/cpp/messagebus/socket_addr.h index 7e3df5afbe..959eafe689 100644 --- a/library/cpp/messagebus/socket_addr.h +++ b/library/cpp/messagebus/socket_addr.h @@ -1,18 +1,18 @@ -#pragma once - +#pragma once + #include "hash.h" - + #include <util/generic/hash.h> #include <util/generic/utility.h> -#include <util/network/address.h> +#include <util/network/address.h> #include <util/network/init.h> - + #include <string.h> - -namespace NBus { - class TNetAddr; -} - + +namespace NBus { + class TNetAddr; +} + namespace NBus { namespace NPrivate { enum EAddrFamily { @@ -20,94 +20,94 @@ namespace NBus { ADDR_IPV4 = AF_INET, ADDR_IPV6 = AF_INET6, }; - + class TBusIpAddr { private: EAddrFamily Af; - + union { in_addr In4; in6_addr In6; }; - + public: TBusIpAddr() { Clear(); } - + EAddrFamily GetAddrFamily() const { return Af; } - + void Clear() { Zero(*this); } - + in_addr GetInAddr() const { Y_ASSERT(Af == ADDR_IPV4); return In4; } - + void SetInAddr(const in_addr& in4) { Clear(); Af = ADDR_IPV4; In4 = in4; } - + in6_addr GetIn6Addr() const { Y_ASSERT(Af == ADDR_IPV6); return In6; } - + void SetIn6Addr(const in6_addr& in6) { Clear(); Af = ADDR_IPV6; In6 = in6; } - + bool operator==(const TBusIpAddr& that) const { return memcmp(this, &that, sizeof(that)) == 0; } }; - + class TBusSocketAddr { public: TBusIpAddr IpAddr; ui16 Port; - + //Only makes sense for IPv6 link-local addresses ui32 IPv6ScopeID; - + TBusSocketAddr() : Port(0) , IPv6ScopeID(0) { } - + TBusSocketAddr(const NAddr::IRemoteAddr*); TBusSocketAddr(const TNetAddr&); TBusSocketAddr(TStringBuf host, unsigned port); TNetAddr ToNetAddr() const; - + bool operator==(const TBusSocketAddr& that) const { return IpAddr == that.IpAddr && Port == that.Port; } }; - + } } - -template <> -struct THash<NBus::NPrivate::TBusIpAddr> { - inline size_t operator()(const NBus::NPrivate::TBusIpAddr& a) const { + +template <> +struct THash<NBus::NPrivate::TBusIpAddr> { + inline size_t operator()(const NBus::NPrivate::TBusIpAddr& a) const { return ComputeHash(TStringBuf((const char*)&a, sizeof(a))); - } -}; - -template <> -struct THash<NBus::NPrivate::TBusSocketAddr> { - inline size_t operator()(const NBus::NPrivate::TBusSocketAddr& a) const { - return HashValues(a.IpAddr, a.Port); - } -}; + } +}; + +template <> +struct THash<NBus::NPrivate::TBusSocketAddr> { + inline size_t operator()(const NBus::NPrivate::TBusSocketAddr& a) const { + return HashValues(a.IpAddr, a.Port); + } +}; diff --git a/library/cpp/messagebus/socket_addr_ut.cpp b/library/cpp/messagebus/socket_addr_ut.cpp index a8e4fea47f..783bb62a86 100644 --- a/library/cpp/messagebus/socket_addr_ut.cpp +++ b/library/cpp/messagebus/socket_addr_ut.cpp @@ -1,15 +1,15 @@ #include <library/cpp/testing/unittest/registar.h> - + #include "netaddr.h" -#include "socket_addr.h" - +#include "socket_addr.h" + #include <util/string/cast.h> -using namespace NBus; -using namespace NBus::NPrivate; - +using namespace NBus; +using namespace NBus::NPrivate; + Y_UNIT_TEST_SUITE(TBusSocketAddr) { Y_UNIT_TEST(Simple) { UNIT_ASSERT_VALUES_EQUAL(TString("127.0.0.1:80"), ToString(TBusSocketAddr("127.0.0.1", 80))); - } -} + } +} diff --git a/library/cpp/messagebus/storage.cpp b/library/cpp/messagebus/storage.cpp index f201a4335d..efefc87340 100644 --- a/library/cpp/messagebus/storage.cpp +++ b/library/cpp/messagebus/storage.cpp @@ -1,7 +1,7 @@ #include "storage.h" -#include <typeinfo> - +#include <typeinfo> + namespace NBus { namespace NPrivate { TTimedMessages::TTimedMessages() { @@ -10,13 +10,13 @@ namespace NBus { TTimedMessages::~TTimedMessages() { Y_VERIFY(Items.empty()); } - + void TTimedMessages::PushBack(TNonDestroyingAutoPtr<TBusMessage> m) { TItem i; i.Message.Reset(m.Release()); Items.push_back(i); } - + TNonDestroyingAutoPtr<TBusMessage> TTimedMessages::PopFront() { TBusMessage* r = nullptr; if (!Items.empty()) { @@ -25,11 +25,11 @@ namespace NBus { } return r; } - + bool TTimedMessages::Empty() const { return Items.empty(); } - + size_t TTimedMessages::Size() const { return Items.size(); } @@ -62,7 +62,7 @@ namespace NBus { KeyToMessage.set_empty_key(0); KeyToMessage.set_deleted_key(1); } - + TSyncAckMessages::~TSyncAckMessages() { Y_VERIFY(KeyToMessage.empty()); Y_VERIFY(TimedItems.empty()); @@ -75,14 +75,14 @@ namespace NBus { } TValue value = {m.MessagePtr.Release()}; - + std::pair<TKeyToMessage::iterator, bool> p = KeyToMessage.insert(TKeyToMessage::value_type(m.Header.Id, value)); Y_VERIFY(p.second, "non-unique id; %s", value.Message->Describe().data()); - + TTimedItem item = {m.Header.Id, m.Header.SendTime}; TimedItems.push_back(item); } - + TBusMessage* TSyncAckMessages::Pop(TBusKey id) { TKeyToMessage::iterator it = KeyToMessage.find(id); if (it == KeyToMessage.end()) { @@ -90,9 +90,9 @@ namespace NBus { } TValue v = it->second; KeyToMessage.erase(it); - + // `TimedMessages` still contain record about this message - + return v.Message; } @@ -102,9 +102,9 @@ namespace NBus { Clear(r); return; } - + Y_ASSERT(r->empty()); - + while (!TimedItems.empty()) { TTimedItem i = TimedItems.front(); if (TInstant::MilliSeconds(i.SendTime) > before) { @@ -112,25 +112,25 @@ namespace NBus { } TKeyToMessage::iterator itMessage = KeyToMessage.find(i.Key); - + if (itMessage != KeyToMessage.end()) { r->push_back(itMessage->second.Message); KeyToMessage.erase(itMessage); } - + TimedItems.pop_front(); } - } - + } + void TSyncAckMessages::Clear(TMessagesPtrs* r) { for (TKeyToMessage::const_iterator i = KeyToMessage.begin(); i != KeyToMessage.end(); ++i) { r->push_back(i->second.Message); } - + KeyToMessage.clear(); TimedItems.clear(); - } - + } + void TSyncAckMessages::Gc() { TDeque<TTimedItem> tmp; @@ -140,7 +140,7 @@ namespace NBus { } tmp.push_back(timedItem); } - + TimedItems.swap(tmp); } @@ -151,11 +151,11 @@ namespace NBus { KeyToMessage.erase(it); } } - + void TSyncAckMessages::DumpState() { Cerr << TimedItems.size() << Endl; Cerr << KeyToMessage.size() << Endl; - } - - } + } + + } } diff --git a/library/cpp/messagebus/storage.h b/library/cpp/messagebus/storage.h index f69b2ae857..7d168844ed 100644 --- a/library/cpp/messagebus/storage.h +++ b/library/cpp/messagebus/storage.h @@ -7,13 +7,13 @@ #include <contrib/libs/sparsehash/src/sparsehash/dense_hash_map> #include <util/generic/deque.h> -#include <util/generic/noncopyable.h> -#include <util/generic/utility.h> - +#include <util/generic/noncopyable.h> +#include <util/generic/utility.h> + namespace NBus { namespace NPrivate { typedef TVector<TBusMessage*> TMessagesPtrs; - + class TTimedMessages { public: TTimedMessages(); @@ -21,19 +21,19 @@ namespace NBus { struct TItem { THolder<TBusMessage> Message; - + void Swap(TItem& that) { DoSwap(Message, that.Message); } }; - + typedef TDeque<TMoved<TItem>> TItems; - + void PushBack(TNonDestroyingAutoPtr<TBusMessage> m); TNonDestroyingAutoPtr<TBusMessage> PopFront(); bool Empty() const; size_t Size() const; - + void Timeout(TInstant before, TMessagesPtrs* r); void Clear(TMessagesPtrs* r); @@ -48,9 +48,9 @@ namespace NBus { void Push(TBusMessagePtrAndHeader& m); TBusMessage* Pop(TBusKey id); - + void Timeout(TInstant before, TMessagesPtrs* r); - + void Clear(TMessagesPtrs* r); size_t Size() const { @@ -62,33 +62,33 @@ namespace NBus { void Gc(); void DumpState(); - + private: struct TTimedItem { TBusKey Key; TBusInstant SendTime; }; - + typedef TDeque<TTimedItem> TTimedItems; typedef TDeque<TTimedItem>::iterator TTimedIterator; - + TTimedItems TimedItems; - + struct TValue { TBusMessage* Message; }; - + // keys are already random, no need to hash them further struct TIdHash { size_t operator()(TBusKey value) const { return value; } }; - + typedef google::dense_hash_map<TBusKey, TValue, TIdHash> TKeyToMessage; - + TKeyToMessage KeyToMessage; - }; - + }; + } } diff --git a/library/cpp/messagebus/synchandler.cpp b/library/cpp/messagebus/synchandler.cpp index 4ea4eb1ee0..8e891d66b3 100644 --- a/library/cpp/messagebus/synchandler.cpp +++ b/library/cpp/messagebus/synchandler.cpp @@ -1,10 +1,10 @@ -#include "remote_client_session.h" -#include "remote_connection.h" +#include "remote_client_session.h" +#include "remote_connection.h" #include "ybus.h" -using namespace NBus; -using namespace NBus::NPrivate; - +using namespace NBus; +using namespace NBus::NPrivate; + ///////////////////////////////////////////////////////////////// /// Object that encapsulates all messgae data required for sending /// a message synchronously and receiving a reply. It includes: @@ -27,8 +27,8 @@ struct TBusSyncMessageData { class TSyncHandler: public IBusClientHandler { public: - TSyncHandler(bool expectReply = true) - : ExpectReply(expectReply) + TSyncHandler(bool expectReply = true) + : ExpectReply(expectReply) , Session(nullptr) { } @@ -36,57 +36,57 @@ public: } void OnReply(TAutoPtr<TBusMessage> pMessage0, TAutoPtr<TBusMessage> pReply0) override { - TBusMessage* pMessage = pMessage0.Release(); - TBusMessage* pReply = pReply0.Release(); - + TBusMessage* pMessage = pMessage0.Release(); + TBusMessage* pReply = pReply0.Release(); + if (!ExpectReply) { // Maybe need VERIFY, but it will be better to support backward compatibility here. - return; - } - + return; + } + TBusSyncMessageData* data = static_cast<TBusSyncMessageData*>(pMessage->Data); - SignalResult(data, pReply, MESSAGE_OK); + SignalResult(data, pReply, MESSAGE_OK); } void OnError(TAutoPtr<TBusMessage> pMessage0, EMessageStatus status) override { - TBusMessage* pMessage = pMessage0.Release(); + TBusMessage* pMessage = pMessage0.Release(); TBusSyncMessageData* data = static_cast<TBusSyncMessageData*>(pMessage->Data); if (!data) { return; } SignalResult(data, /*pReply=*/nullptr, status); - } - + } + void OnMessageSent(TBusMessage* pMessage) override { Y_UNUSED(pMessage); Y_ASSERT(ExpectReply); - } - + } + void OnMessageSentOneWay(TAutoPtr<TBusMessage> pMessage) override { Y_ASSERT(!ExpectReply); TBusSyncMessageData* data = static_cast<TBusSyncMessageData*>(pMessage.Release()->Data); SignalResult(data, /*pReply=*/nullptr, MESSAGE_OK); - } - - void SetSession(TRemoteClientSession* session) { - if (!ExpectReply) { - Session = session; - } - } - -private: + } + + void SetSession(TRemoteClientSession* session) { + if (!ExpectReply) { + Session = session; + } + } + +private: void SignalResult(TBusSyncMessageData* data, TBusMessage* pReply, EMessageStatus status) const { Y_VERIFY(data, "Message data is set to NULL."); TGuard<TMutex> G(data->ReplyLock); - data->Reply = pReply; + data->Reply = pReply; data->ReplyStatus = status; data->ReplyEvent.Signal(); } - -private: - // This is weird, because in regular client one-way-ness is selected per call, not per session. - bool ExpectReply; - TRemoteClientSession* Session; + +private: + // This is weird, because in regular client one-way-ness is selected per call, not per session. + bool ExpectReply; + TRemoteClientSession* Session; }; namespace NBus { @@ -104,7 +104,7 @@ namespace NBus { public TRemoteClientSession { private: bool NeedReply; - + public: TBusSyncSourceSessionImpl(TBusMessageQueue* queue, TBusProtocol* proto, const TBusClientSessionConfig& config, bool needReply, const TString& name) : TSyncHandler(needReply) @@ -113,16 +113,16 @@ namespace NBus { { SetSession(this); } - + TBusMessage* SendSyncMessage(TBusMessage* pMessage, EMessageStatus& status, const TNetAddr* addr = nullptr) { Y_VERIFY(!Queue->GetExecutor()->IsInExecutorThread(), "SendSyncMessage must not be called from executor thread"); - + TBusMessage* reply = nullptr; THolder<TBusSyncMessageData> data(new TBusSyncMessageData()); - + pMessage->Data = data.Get(); - + { TGuard<TMutex> G(data->ReplyLock); if (NeedReply) { @@ -130,7 +130,7 @@ namespace NBus { } else { status = SendMessageOneWay(pMessage, addr); } - + if (status == MESSAGE_OK) { data->ReplyEvent.Wait(data->ReplyLock); TBusSyncMessageData* rdata = static_cast<TBusSyncMessageData*>(pMessage->Data); @@ -139,7 +139,7 @@ namespace NBus { status = rdata->ReplyStatus; } } - + // deletion of message and reply is a job of application. pMessage->Data = nullptr; @@ -153,46 +153,46 @@ namespace NBus { } } -TBusSyncSourceSession::TBusSyncSourceSession(TIntrusivePtr< ::NBus::NPrivate::TBusSyncSourceSessionImpl> session) - : Session(session) +TBusSyncSourceSession::TBusSyncSourceSession(TIntrusivePtr< ::NBus::NPrivate::TBusSyncSourceSessionImpl> session) + : Session(session) { } - + TBusSyncSourceSession::~TBusSyncSourceSession() { - Shutdown(); -} - -void TBusSyncSourceSession::Shutdown() { - Session->Shutdown(); -} - -TBusMessage* TBusSyncSourceSession::SendSyncMessage(TBusMessage* pMessage, EMessageStatus& status, const TNetAddr* addr) { - return Session->SendSyncMessage(pMessage, status, addr); + Shutdown(); +} + +void TBusSyncSourceSession::Shutdown() { + Session->Shutdown(); +} + +TBusMessage* TBusSyncSourceSession::SendSyncMessage(TBusMessage* pMessage, EMessageStatus& status, const TNetAddr* addr) { + return Session->SendSyncMessage(pMessage, status, addr); } int TBusSyncSourceSession::RegisterService(const char* hostname, TBusKey start, TBusKey end, EIpVersion ipVersion) { - return Session->RegisterService(hostname, start, end, ipVersion); -} + return Session->RegisterService(hostname, start, end, ipVersion); +} -int TBusSyncSourceSession::GetInFlight() { - return Session->GetInFlight(); -} +int TBusSyncSourceSession::GetInFlight() { + return Session->GetInFlight(); +} -const TBusProtocol* TBusSyncSourceSession::GetProto() const { - return Session->GetProto(); -} +const TBusProtocol* TBusSyncSourceSession::GetProto() const { + return Session->GetProto(); +} const TBusClientSession* TBusSyncSourceSession::GetBusClientSessionWorkaroundDoNotUse() const { return Session.Get(); } TBusSyncClientSessionPtr TBusMessageQueue::CreateSyncSource(TBusProtocol* proto, const TBusClientSessionConfig& config, bool needReply, const TString& name) { - TIntrusivePtr<TBusSyncSourceSessionImpl> session = new TBusSyncSourceSessionImpl(this, proto, config, needReply, name); - Add(session.Get()); - return new TBusSyncSourceSession(session); -} + TIntrusivePtr<TBusSyncSourceSessionImpl> session = new TBusSyncSourceSessionImpl(this, proto, config, needReply, name); + Add(session.Get()); + return new TBusSyncSourceSession(session); +} -void TBusMessageQueue::Destroy(TBusSyncClientSessionPtr session) { - Destroy(session->Session.Get()); +void TBusMessageQueue::Destroy(TBusSyncClientSessionPtr session) { + Destroy(session->Session.Get()); Y_UNUSED(session->Session.Release()); } diff --git a/library/cpp/messagebus/test/TestMessageBus.py b/library/cpp/messagebus/test/TestMessageBus.py index 4173c9866e..0bbaa0a313 100644 --- a/library/cpp/messagebus/test/TestMessageBus.py +++ b/library/cpp/messagebus/test/TestMessageBus.py @@ -3,6 +3,6 @@ from devtools.fleur.ytest.integration import UnitTestGroup @group @constraint('library.messagebus') -class TestMessageBus(UnitTestGroup): +class TestMessageBus(UnitTestGroup): def __init__(self, context): UnitTestGroup.__init__(self, context, 'MessageBus', 'library-messagebus-test-ut') diff --git a/library/cpp/messagebus/test/example/client/client.cpp b/library/cpp/messagebus/test/example/client/client.cpp index 3bd9a6f768..89b5f2c9be 100644 --- a/library/cpp/messagebus/test/example/client/client.cpp +++ b/library/cpp/messagebus/test/example/client/client.cpp @@ -1,81 +1,81 @@ #include <library/cpp/messagebus/test/example/common/proto.h> -#include <util/random/random.h> - -using namespace NBus; -using namespace NCalculator; - -namespace NCalculator { +#include <util/random/random.h> + +using namespace NBus; +using namespace NCalculator; + +namespace NCalculator { struct TCalculatorClient: public IBusClientHandler { - TCalculatorProtocol Proto; - TBusMessageQueuePtr MessageQueue; - TBusClientSessionPtr ClientSession; - - TCalculatorClient() { - MessageQueue = CreateMessageQueue(); - TBusClientSessionConfig config; - config.TotalTimeout = 2 * 1000; - ClientSession = TBusClientSession::Create(&Proto, this, config, MessageQueue); - } - + TCalculatorProtocol Proto; + TBusMessageQueuePtr MessageQueue; + TBusClientSessionPtr ClientSession; + + TCalculatorClient() { + MessageQueue = CreateMessageQueue(); + TBusClientSessionConfig config; + config.TotalTimeout = 2 * 1000; + ClientSession = TBusClientSession::Create(&Proto, this, config, MessageQueue); + } + ~TCalculatorClient() override { - MessageQueue->Stop(); - } - + MessageQueue->Stop(); + } + void OnReply(TAutoPtr<TBusMessage> request, TAutoPtr<TBusMessage> response0) override { Y_VERIFY(response0->GetHeader()->Type == TResponse::MessageType, "wrong response"); - TResponse* response = VerifyDynamicCast<TResponse*>(response0.Get()); - if (request->GetHeader()->Type == TRequestSum::MessageType) { - TRequestSum* requestSum = VerifyDynamicCast<TRequestSum*>(request.Get()); - int a = requestSum->Record.GetA(); - int b = requestSum->Record.GetB(); - Cerr << a << " + " << b << " = " << response->Record.GetResult() << "\n"; - } else if (request->GetHeader()->Type == TRequestMul::MessageType) { - TRequestMul* requestMul = VerifyDynamicCast<TRequestMul*>(request.Get()); - int a = requestMul->Record.GetA(); - int b = requestMul->Record.GetB(); - Cerr << a << " * " << b << " = " << response->Record.GetResult() << "\n"; - } else { + TResponse* response = VerifyDynamicCast<TResponse*>(response0.Get()); + if (request->GetHeader()->Type == TRequestSum::MessageType) { + TRequestSum* requestSum = VerifyDynamicCast<TRequestSum*>(request.Get()); + int a = requestSum->Record.GetA(); + int b = requestSum->Record.GetB(); + Cerr << a << " + " << b << " = " << response->Record.GetResult() << "\n"; + } else if (request->GetHeader()->Type == TRequestMul::MessageType) { + TRequestMul* requestMul = VerifyDynamicCast<TRequestMul*>(request.Get()); + int a = requestMul->Record.GetA(); + int b = requestMul->Record.GetB(); + Cerr << a << " * " << b << " = " << response->Record.GetResult() << "\n"; + } else { Y_FAIL("unknown request"); - } - } - + } + } + void OnError(TAutoPtr<TBusMessage>, EMessageStatus status) override { - Cerr << "got error " << status << "\n"; - } - }; - -} - -int main(int, char**) { - TCalculatorClient client; - - for (;;) { - TNetAddr addr(TNetAddr("127.0.0.1", TCalculatorProtocol().GetPort())); - - int a = RandomNumber<unsigned>(10); - int b = RandomNumber<unsigned>(10); - EMessageStatus ok; - if (RandomNumber<bool>()) { - TAutoPtr<TRequestSum> request(new TRequestSum); - request->Record.SetA(a); - request->Record.SetB(b); - Cerr << "sending " << a << " + " << b << "\n"; - ok = client.ClientSession->SendMessageAutoPtr(request, &addr); - } else { - TAutoPtr<TRequestMul> request(new TRequestMul); - request->Record.SetA(a); - request->Record.SetB(b); - Cerr << "sending " << a << " * " << b << "\n"; - ok = client.ClientSession->SendMessageAutoPtr(request, &addr); - } - - if (ok != MESSAGE_OK) { - Cerr << "failed to send message " << ok << "\n"; - } - - Sleep(TDuration::Seconds(1)); - } - - return 0; -} + Cerr << "got error " << status << "\n"; + } + }; + +} + +int main(int, char**) { + TCalculatorClient client; + + for (;;) { + TNetAddr addr(TNetAddr("127.0.0.1", TCalculatorProtocol().GetPort())); + + int a = RandomNumber<unsigned>(10); + int b = RandomNumber<unsigned>(10); + EMessageStatus ok; + if (RandomNumber<bool>()) { + TAutoPtr<TRequestSum> request(new TRequestSum); + request->Record.SetA(a); + request->Record.SetB(b); + Cerr << "sending " << a << " + " << b << "\n"; + ok = client.ClientSession->SendMessageAutoPtr(request, &addr); + } else { + TAutoPtr<TRequestMul> request(new TRequestMul); + request->Record.SetA(a); + request->Record.SetB(b); + Cerr << "sending " << a << " * " << b << "\n"; + ok = client.ClientSession->SendMessageAutoPtr(request, &addr); + } + + if (ok != MESSAGE_OK) { + Cerr << "failed to send message " << ok << "\n"; + } + + Sleep(TDuration::Seconds(1)); + } + + return 0; +} diff --git a/library/cpp/messagebus/test/example/client/ya.make b/library/cpp/messagebus/test/example/client/ya.make index 81713a5318..a660a01698 100644 --- a/library/cpp/messagebus/test/example/client/ya.make +++ b/library/cpp/messagebus/test/example/client/ya.make @@ -1,13 +1,13 @@ -PROGRAM(messagebus_example_client) - +PROGRAM(messagebus_example_client) + OWNER(g:messagebus) - -PEERDIR( + +PEERDIR( library/cpp/messagebus/test/example/common -) - -SRCS( - client.cpp -) - -END() +) + +SRCS( + client.cpp +) + +END() diff --git a/library/cpp/messagebus/test/example/common/messages.proto b/library/cpp/messagebus/test/example/common/messages.proto index 12cdf38fb5..16b858fc77 100644 --- a/library/cpp/messagebus/test/example/common/messages.proto +++ b/library/cpp/messagebus/test/example/common/messages.proto @@ -1,15 +1,15 @@ -package NCalculator; - -message TRequestSumRecord { - required int32 A = 1; - required int32 B = 2; -} - -message TRequestMulRecord { - required int32 A = 1; - required int32 B = 2; -} - -message TResponseRecord { - required int32 Result = 1; -} +package NCalculator; + +message TRequestSumRecord { + required int32 A = 1; + required int32 B = 2; +} + +message TRequestMulRecord { + required int32 A = 1; + required int32 B = 2; +} + +message TResponseRecord { + required int32 Result = 1; +} diff --git a/library/cpp/messagebus/test/example/common/proto.cpp b/library/cpp/messagebus/test/example/common/proto.cpp index 3531e3d06c..1d18aa77ea 100644 --- a/library/cpp/messagebus/test/example/common/proto.cpp +++ b/library/cpp/messagebus/test/example/common/proto.cpp @@ -1,12 +1,12 @@ -#include "proto.h" - -using namespace NCalculator; -using namespace NBus; - -TCalculatorProtocol::TCalculatorProtocol() - : TBusBufferProtocol("Calculator", 34567) -{ - RegisterType(new TRequestSum); - RegisterType(new TRequestMul); - RegisterType(new TResponse); -} +#include "proto.h" + +using namespace NCalculator; +using namespace NBus; + +TCalculatorProtocol::TCalculatorProtocol() + : TBusBufferProtocol("Calculator", 34567) +{ + RegisterType(new TRequestSum); + RegisterType(new TRequestMul); + RegisterType(new TResponse); +} diff --git a/library/cpp/messagebus/test/example/common/proto.h b/library/cpp/messagebus/test/example/common/proto.h index f9fbd5ce56..a151aac468 100644 --- a/library/cpp/messagebus/test/example/common/proto.h +++ b/library/cpp/messagebus/test/example/common/proto.h @@ -1,17 +1,17 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/test/example/common/messages.pb.h> - + #include <library/cpp/messagebus/ybus.h> #include <library/cpp/messagebus/protobuf/ybusbuf.h> -namespace NCalculator { - typedef ::NBus::TBusBufferMessage<TRequestSumRecord, 1> TRequestSum; - typedef ::NBus::TBusBufferMessage<TRequestMulRecord, 2> TRequestMul; - typedef ::NBus::TBusBufferMessage<TResponseRecord, 3> TResponse; - +namespace NCalculator { + typedef ::NBus::TBusBufferMessage<TRequestSumRecord, 1> TRequestSum; + typedef ::NBus::TBusBufferMessage<TRequestMulRecord, 2> TRequestMul; + typedef ::NBus::TBusBufferMessage<TResponseRecord, 3> TResponse; + struct TCalculatorProtocol: public ::NBus::TBusBufferProtocol { - TCalculatorProtocol(); - }; - -} + TCalculatorProtocol(); + }; + +} diff --git a/library/cpp/messagebus/test/example/common/ya.make b/library/cpp/messagebus/test/example/common/ya.make index 14f48ff6c0..4da16608fc 100644 --- a/library/cpp/messagebus/test/example/common/ya.make +++ b/library/cpp/messagebus/test/example/common/ya.make @@ -1,15 +1,15 @@ -LIBRARY(messagebus_test_example_common) - +LIBRARY(messagebus_test_example_common) + OWNER(g:messagebus) - -PEERDIR( + +PEERDIR( library/cpp/messagebus library/cpp/messagebus/protobuf -) - -SRCS( - proto.cpp - messages.proto -) - -END() +) + +SRCS( + proto.cpp + messages.proto +) + +END() diff --git a/library/cpp/messagebus/test/example/server/server.cpp b/library/cpp/messagebus/test/example/server/server.cpp index a080f3548b..13e52d75f5 100644 --- a/library/cpp/messagebus/test/example/server/server.cpp +++ b/library/cpp/messagebus/test/example/server/server.cpp @@ -1,58 +1,58 @@ #include <library/cpp/messagebus/test/example/common/proto.h> - -using namespace NBus; -using namespace NCalculator; - -namespace NCalculator { + +using namespace NBus; +using namespace NCalculator; + +namespace NCalculator { struct TCalculatorServer: public IBusServerHandler { - TCalculatorProtocol Proto; - TBusMessageQueuePtr MessageQueue; - TBusServerSessionPtr ServerSession; - - TCalculatorServer() { - MessageQueue = CreateMessageQueue(); - TBusServerSessionConfig config; - ServerSession = TBusServerSession::Create(&Proto, this, config, MessageQueue); - } - + TCalculatorProtocol Proto; + TBusMessageQueuePtr MessageQueue; + TBusServerSessionPtr ServerSession; + + TCalculatorServer() { + MessageQueue = CreateMessageQueue(); + TBusServerSessionConfig config; + ServerSession = TBusServerSession::Create(&Proto, this, config, MessageQueue); + } + ~TCalculatorServer() override { - MessageQueue->Stop(); - } - + MessageQueue->Stop(); + } + void OnMessage(TOnMessageContext& request) override { - if (request.GetMessage()->GetHeader()->Type == TRequestSum::MessageType) { - TRequestSum* requestSum = VerifyDynamicCast<TRequestSum*>(request.GetMessage()); - int a = requestSum->Record.GetA(); - int b = requestSum->Record.GetB(); - int result = a + b; - Cerr << "requested " << a << " + " << b << ", sending " << result << "\n"; - TAutoPtr<TResponse> response(new TResponse); - response->Record.SetResult(result); - request.SendReplyMove(response); - } else if (request.GetMessage()->GetHeader()->Type == TRequestMul::MessageType) { - TRequestMul* requestMul = VerifyDynamicCast<TRequestMul*>(request.GetMessage()); - int a = requestMul->Record.GetA(); - int b = requestMul->Record.GetB(); - int result = a * b; - Cerr << "requested " << a << " * " << b << ", sending " << result << "\n"; - TAutoPtr<TResponse> response(new TResponse); - response->Record.SetResult(result); - request.SendReplyMove(response); - } else { + if (request.GetMessage()->GetHeader()->Type == TRequestSum::MessageType) { + TRequestSum* requestSum = VerifyDynamicCast<TRequestSum*>(request.GetMessage()); + int a = requestSum->Record.GetA(); + int b = requestSum->Record.GetB(); + int result = a + b; + Cerr << "requested " << a << " + " << b << ", sending " << result << "\n"; + TAutoPtr<TResponse> response(new TResponse); + response->Record.SetResult(result); + request.SendReplyMove(response); + } else if (request.GetMessage()->GetHeader()->Type == TRequestMul::MessageType) { + TRequestMul* requestMul = VerifyDynamicCast<TRequestMul*>(request.GetMessage()); + int a = requestMul->Record.GetA(); + int b = requestMul->Record.GetB(); + int result = a * b; + Cerr << "requested " << a << " * " << b << ", sending " << result << "\n"; + TAutoPtr<TResponse> response(new TResponse); + response->Record.SetResult(result); + request.SendReplyMove(response); + } else { Y_FAIL("unknown request"); - } - } - }; + } + } + }; +} + +int main(int, char**) { + TCalculatorServer server; + + Cerr << "listening on port " << server.ServerSession->GetActualListenPort() << "\n"; + + for (;;) { + Sleep(TDuration::Seconds(1)); + } + + return 0; } - -int main(int, char**) { - TCalculatorServer server; - - Cerr << "listening on port " << server.ServerSession->GetActualListenPort() << "\n"; - - for (;;) { - Sleep(TDuration::Seconds(1)); - } - - return 0; -} diff --git a/library/cpp/messagebus/test/example/server/ya.make b/library/cpp/messagebus/test/example/server/ya.make index 3bf4c31853..8cdd97cb12 100644 --- a/library/cpp/messagebus/test/example/server/ya.make +++ b/library/cpp/messagebus/test/example/server/ya.make @@ -1,13 +1,13 @@ -PROGRAM(messagebus_example_server) - +PROGRAM(messagebus_example_server) + OWNER(g:messagebus) - -PEERDIR( + +PEERDIR( library/cpp/messagebus/test/example/common -) - -SRCS( - server.cpp -) - -END() +) + +SRCS( + server.cpp +) + +END() diff --git a/library/cpp/messagebus/test/example/ya.make b/library/cpp/messagebus/test/example/ya.make index 972458d255..f275351c29 100644 --- a/library/cpp/messagebus/test/example/ya.make +++ b/library/cpp/messagebus/test/example/ya.make @@ -1,7 +1,7 @@ OWNER(g:messagebus) - -RECURSE( + +RECURSE( client common server -) +) diff --git a/library/cpp/messagebus/test/helper/alloc_counter.h b/library/cpp/messagebus/test/helper/alloc_counter.h index 88db651e69..ec9041cb15 100644 --- a/library/cpp/messagebus/test/helper/alloc_counter.h +++ b/library/cpp/messagebus/test/helper/alloc_counter.h @@ -1,21 +1,21 @@ -#pragma once - -#include <util/generic/noncopyable.h> -#include <util/system/atomic.h> -#include <util/system/yassert.h> - +#pragma once + +#include <util/generic/noncopyable.h> +#include <util/system/atomic.h> +#include <util/system/yassert.h> + class TAllocCounter : TNonCopyable { -private: - TAtomic* CountPtr; +private: + TAtomic* CountPtr; -public: +public: TAllocCounter(TAtomic* countPtr) : CountPtr(countPtr) { - AtomicIncrement(*CountPtr); - } - - ~TAllocCounter() { + AtomicIncrement(*CountPtr); + } + + ~TAllocCounter() { Y_VERIFY(AtomicDecrement(*CountPtr) >= 0, "released too many"); - } -}; + } +}; diff --git a/library/cpp/messagebus/test/helper/example.cpp b/library/cpp/messagebus/test/helper/example.cpp index a1913b58c1..7c6d704042 100644 --- a/library/cpp/messagebus/test/helper/example.cpp +++ b/library/cpp/messagebus/test/helper/example.cpp @@ -1,281 +1,281 @@ #include <library/cpp/testing/unittest/registar.h> - + #include "example.h" -#include <util/generic/cast.h> - -using namespace NBus; -using namespace NBus::NTest; - +#include <util/generic/cast.h> + +using namespace NBus; +using namespace NBus::NTest; + static void FillWithJunk(TArrayRef<char> data) { TStringBuf junk = "01234567890123456789012345678901234567890123456789012345678901234567890123456789" "01234567890123456789012345678901234567890123456789012345678901234567890123456789" "01234567890123456789012345678901234567890123456789012345678901234567890123456789" "01234567890123456789012345678901234567890123456789012345678901234567890123456789"; - + for (size_t i = 0; i < data.size(); i += junk.size()) { memcpy(data.data() + i, junk.data(), Min(junk.size(), data.size() - i)); - } -} - + } +} + static TString JunkString(size_t len) { - TTempBuf temp(len); + TTempBuf temp(len); TArrayRef<char> tempArrayRef(temp.Data(), len); - FillWithJunk(tempArrayRef); - + FillWithJunk(tempArrayRef); + return TString(tempArrayRef.data(), tempArrayRef.size()); -} - -TExampleRequest::TExampleRequest(TAtomic* counterPtr, size_t payloadSize) - : TBusMessage(77) - , AllocCounter(counterPtr) - , Data(JunkString(payloadSize)) -{ -} - -TExampleRequest::TExampleRequest(ECreateUninitialized, TAtomic* counterPtr) - : TBusMessage(MESSAGE_CREATE_UNINITIALIZED) - , AllocCounter(counterPtr) +} + +TExampleRequest::TExampleRequest(TAtomic* counterPtr, size_t payloadSize) + : TBusMessage(77) + , AllocCounter(counterPtr) + , Data(JunkString(payloadSize)) { } - -TExampleResponse::TExampleResponse(TAtomic* counterPtr, size_t payloadSize) - : TBusMessage(79) - , AllocCounter(counterPtr) - , Data(JunkString(payloadSize)) -{ -} - -TExampleResponse::TExampleResponse(ECreateUninitialized, TAtomic* counterPtr) - : TBusMessage(MESSAGE_CREATE_UNINITIALIZED) - , AllocCounter(counterPtr) + +TExampleRequest::TExampleRequest(ECreateUninitialized, TAtomic* counterPtr) + : TBusMessage(MESSAGE_CREATE_UNINITIALIZED) + , AllocCounter(counterPtr) { } - -TExampleProtocol::TExampleProtocol(int port) - : TBusProtocol("Example", port) - , RequestCount(0) - , ResponseCount(0) - , RequestCountDeserialized(0) - , ResponseCountDeserialized(0) - , StartCount(0) + +TExampleResponse::TExampleResponse(TAtomic* counterPtr, size_t payloadSize) + : TBusMessage(79) + , AllocCounter(counterPtr) + , Data(JunkString(payloadSize)) { } - -TExampleProtocol::~TExampleProtocol() { - if (UncaughtException()) { - // so it could be reported in test - return; - } + +TExampleResponse::TExampleResponse(ECreateUninitialized, TAtomic* counterPtr) + : TBusMessage(MESSAGE_CREATE_UNINITIALIZED) + , AllocCounter(counterPtr) +{ +} + +TExampleProtocol::TExampleProtocol(int port) + : TBusProtocol("Example", port) + , RequestCount(0) + , ResponseCount(0) + , RequestCountDeserialized(0) + , ResponseCountDeserialized(0) + , StartCount(0) +{ +} + +TExampleProtocol::~TExampleProtocol() { + if (UncaughtException()) { + // so it could be reported in test + return; + } Y_VERIFY(0 == AtomicGet(RequestCount), "protocol %s: must be 0 requests allocated, actually %d", GetService(), int(RequestCount)); Y_VERIFY(0 == AtomicGet(ResponseCount), "protocol %s: must be 0 responses allocated, actually %d", GetService(), int(ResponseCount)); Y_VERIFY(0 == AtomicGet(RequestCountDeserialized), "protocol %s: must be 0 requests deserialized allocated, actually %d", GetService(), int(RequestCountDeserialized)); Y_VERIFY(0 == AtomicGet(ResponseCountDeserialized), "protocol %s: must be 0 responses deserialized allocated, actually %d", GetService(), int(ResponseCountDeserialized)); Y_VERIFY(0 == AtomicGet(StartCount), "protocol %s: must be 0 start objects allocated, actually %d", GetService(), int(StartCount)); -} - -void TExampleProtocol::Serialize(const TBusMessage* message, TBuffer& buffer) { - // Messages have no data, we recreate them from scratch - // instead of sending, so we don't need to serialize them. - if (const TExampleRequest* exampleMessage = dynamic_cast<const TExampleRequest*>(message)) { +} + +void TExampleProtocol::Serialize(const TBusMessage* message, TBuffer& buffer) { + // Messages have no data, we recreate them from scratch + // instead of sending, so we don't need to serialize them. + if (const TExampleRequest* exampleMessage = dynamic_cast<const TExampleRequest*>(message)) { buffer.Append(exampleMessage->Data.data(), exampleMessage->Data.size()); - } else if (const TExampleResponse* exampleReply = dynamic_cast<const TExampleResponse*>(message)) { + } else if (const TExampleResponse* exampleReply = dynamic_cast<const TExampleResponse*>(message)) { buffer.Append(exampleReply->Data.data(), exampleReply->Data.size()); - } else { + } else { Y_FAIL("unknown message type"); - } -} - + } +} + TAutoPtr<TBusMessage> TExampleProtocol::Deserialize(ui16 messageType, TArrayRef<const char> payload) { - // TODO: check data + // TODO: check data Y_UNUSED(payload); - - if (messageType == 77) { - TExampleRequest* exampleMessage = new TExampleRequest(MESSAGE_CREATE_UNINITIALIZED, &RequestCountDeserialized); - exampleMessage->Data.append(payload.data(), payload.size()); - return exampleMessage; - } else if (messageType == 79) { - TExampleResponse* exampleReply = new TExampleResponse(MESSAGE_CREATE_UNINITIALIZED, &ResponseCountDeserialized); - exampleReply->Data.append(payload.data(), payload.size()); - return exampleReply; - } else { + + if (messageType == 77) { + TExampleRequest* exampleMessage = new TExampleRequest(MESSAGE_CREATE_UNINITIALIZED, &RequestCountDeserialized); + exampleMessage->Data.append(payload.data(), payload.size()); + return exampleMessage; + } else if (messageType == 79) { + TExampleResponse* exampleReply = new TExampleResponse(MESSAGE_CREATE_UNINITIALIZED, &ResponseCountDeserialized); + exampleReply->Data.append(payload.data(), payload.size()); + return exampleReply; + } else { return nullptr; - } -} - -TExampleClient::TExampleClient(const TBusClientSessionConfig sessionConfig, int port) - : Proto(port) - , UseCompression(false) - , CrashOnError(false) - , DataSize(320) - , MessageCount(0) - , RepliesCount(0) - , Errors(0) - , LastError(MESSAGE_OK) -{ - Bus = CreateMessageQueue("TExampleClient"); - - Session = TBusClientSession::Create(&Proto, this, sessionConfig, Bus); - - Session->RegisterService("localhost"); -} - -TExampleClient::~TExampleClient() { -} - + } +} + +TExampleClient::TExampleClient(const TBusClientSessionConfig sessionConfig, int port) + : Proto(port) + , UseCompression(false) + , CrashOnError(false) + , DataSize(320) + , MessageCount(0) + , RepliesCount(0) + , Errors(0) + , LastError(MESSAGE_OK) +{ + Bus = CreateMessageQueue("TExampleClient"); + + Session = TBusClientSession::Create(&Proto, this, sessionConfig, Bus); + + Session->RegisterService("localhost"); +} + +TExampleClient::~TExampleClient() { +} + EMessageStatus TExampleClient::SendMessage(const TNetAddr* addr) { - TAutoPtr<TExampleRequest> message(new TExampleRequest(&Proto.RequestCount, DataSize)); - message->SetCompressed(UseCompression); - return Session->SendMessageAutoPtr(message, addr); -} - + TAutoPtr<TExampleRequest> message(new TExampleRequest(&Proto.RequestCount, DataSize)); + message->SetCompressed(UseCompression); + return Session->SendMessageAutoPtr(message, addr); +} + void TExampleClient::SendMessages(size_t count, const TNetAddr* addr) { - UNIT_ASSERT(MessageCount == 0); - UNIT_ASSERT(RepliesCount == 0); - UNIT_ASSERT(Errors == 0); - - WorkDone.Reset(); - MessageCount = count; - for (ssize_t i = 0; i < MessageCount; ++i) { - EMessageStatus s = SendMessage(addr); - UNIT_ASSERT_EQUAL_C(s, MESSAGE_OK, "expecting OK, got " << s); - } -} - -void TExampleClient::SendMessages(size_t count, const TNetAddr& addr) { - SendMessages(count, &addr); -} - -void TExampleClient::ResetCounters() { - MessageCount = 0; - RepliesCount = 0; - Errors = 0; - LastError = MESSAGE_OK; - - WorkDone.Reset(); -} - -void TExampleClient::WaitReplies() { - WorkDone.WaitT(TDuration::Seconds(60)); - - UNIT_ASSERT_VALUES_EQUAL(AtomicGet(RepliesCount), MessageCount); - UNIT_ASSERT_VALUES_EQUAL(AtomicGet(Errors), 0); - UNIT_ASSERT_VALUES_EQUAL(Session->GetInFlight(), 0); - - ResetCounters(); -} - + UNIT_ASSERT(MessageCount == 0); + UNIT_ASSERT(RepliesCount == 0); + UNIT_ASSERT(Errors == 0); + + WorkDone.Reset(); + MessageCount = count; + for (ssize_t i = 0; i < MessageCount; ++i) { + EMessageStatus s = SendMessage(addr); + UNIT_ASSERT_EQUAL_C(s, MESSAGE_OK, "expecting OK, got " << s); + } +} + +void TExampleClient::SendMessages(size_t count, const TNetAddr& addr) { + SendMessages(count, &addr); +} + +void TExampleClient::ResetCounters() { + MessageCount = 0; + RepliesCount = 0; + Errors = 0; + LastError = MESSAGE_OK; + + WorkDone.Reset(); +} + +void TExampleClient::WaitReplies() { + WorkDone.WaitT(TDuration::Seconds(60)); + + UNIT_ASSERT_VALUES_EQUAL(AtomicGet(RepliesCount), MessageCount); + UNIT_ASSERT_VALUES_EQUAL(AtomicGet(Errors), 0); + UNIT_ASSERT_VALUES_EQUAL(Session->GetInFlight(), 0); + + ResetCounters(); +} + EMessageStatus TExampleClient::WaitForError() { - WorkDone.WaitT(TDuration::Seconds(60)); - - UNIT_ASSERT_VALUES_EQUAL(1, MessageCount); - UNIT_ASSERT_VALUES_EQUAL(0, AtomicGet(RepliesCount)); - UNIT_ASSERT_VALUES_EQUAL(0, Session->GetInFlight()); - UNIT_ASSERT_VALUES_EQUAL(1, Errors); + WorkDone.WaitT(TDuration::Seconds(60)); + + UNIT_ASSERT_VALUES_EQUAL(1, MessageCount); + UNIT_ASSERT_VALUES_EQUAL(0, AtomicGet(RepliesCount)); + UNIT_ASSERT_VALUES_EQUAL(0, Session->GetInFlight()); + UNIT_ASSERT_VALUES_EQUAL(1, Errors); EMessageStatus result = LastError; - - ResetCounters(); + + ResetCounters(); return result; -} - +} + void TExampleClient::WaitForError(EMessageStatus status) { EMessageStatus error = WaitForError(); UNIT_ASSERT_VALUES_EQUAL(status, error); } void TExampleClient::SendMessagesWaitReplies(size_t count, const TNetAddr* addr) { - SendMessages(count, addr); - WaitReplies(); -} - -void TExampleClient::SendMessagesWaitReplies(size_t count, const TNetAddr& addr) { - SendMessagesWaitReplies(count, &addr); -} - -void TExampleClient::OnReply(TAutoPtr<TBusMessage> mess, TAutoPtr<TBusMessage> reply) { + SendMessages(count, addr); + WaitReplies(); +} + +void TExampleClient::SendMessagesWaitReplies(size_t count, const TNetAddr& addr) { + SendMessagesWaitReplies(count, &addr); +} + +void TExampleClient::OnReply(TAutoPtr<TBusMessage> mess, TAutoPtr<TBusMessage> reply) { Y_UNUSED(mess); Y_UNUSED(reply); - - if (AtomicIncrement(RepliesCount) == MessageCount) { - WorkDone.Signal(); - } -} - -void TExampleClient::OnError(TAutoPtr<TBusMessage> mess, EMessageStatus status) { - if (CrashOnError) { + + if (AtomicIncrement(RepliesCount) == MessageCount) { + WorkDone.Signal(); + } +} + +void TExampleClient::OnError(TAutoPtr<TBusMessage> mess, EMessageStatus status) { + if (CrashOnError) { Y_FAIL("client failed: %s", ToCString(status)); - } - + } + Y_UNUSED(mess); - - AtomicIncrement(Errors); - LastError = status; - WorkDone.Signal(); -} - -TExampleServer::TExampleServer( + + AtomicIncrement(Errors); + LastError = status; + WorkDone.Signal(); +} + +TExampleServer::TExampleServer( const char* name, const TBusServerSessionConfig& sessionConfig) - : UseCompression(false) - , AckMessageBeforeSendReply(false) - , ForgetRequest(false) -{ - Bus = CreateMessageQueue(name); - Session = TBusServerSession::Create(&Proto, this, sessionConfig, Bus); -} - -TExampleServer::TExampleServer(unsigned port, const char* name) - : UseCompression(false) - , AckMessageBeforeSendReply(false) - , ForgetRequest(false) -{ - Bus = CreateMessageQueue(name); - TBusServerSessionConfig sessionConfig; - sessionConfig.ListenPort = port; - Session = TBusServerSession::Create(&Proto, this, sessionConfig, Bus); -} - -TExampleServer::~TExampleServer() { -} - -size_t TExampleServer::GetInFlight() const { - return Session->GetInFlight(); -} - -unsigned TExampleServer::GetActualListenPort() const { - return Session->GetActualListenPort(); -} - -TNetAddr TExampleServer::GetActualListenAddr() const { - return TNetAddr("127.0.0.1", GetActualListenPort()); -} - -void TExampleServer::WaitForOnMessageCount(unsigned n) { - TestSync.WaitFor(n); -} - -void TExampleServer::OnMessage(TOnMessageContext& mess) { - TestSync.Inc(); - - TExampleRequest* request = VerifyDynamicCast<TExampleRequest*>(mess.GetMessage()); - - if (ForgetRequest) { - mess.ForgetRequest(); - return; - } - - TAutoPtr<TBusMessage> reply(new TExampleResponse(&Proto.ResponseCount, DataSize.GetOrElse(request->Data.size()))); - reply->SetCompressed(UseCompression); - - EMessageStatus status; - if (AckMessageBeforeSendReply) { - TBusIdentity ident; - mess.AckMessage(ident); - status = Session->SendReply(ident, reply.Release()); // TODO: leaks on error - } else { - status = mess.SendReplyMove(reply); - } - + : UseCompression(false) + , AckMessageBeforeSendReply(false) + , ForgetRequest(false) +{ + Bus = CreateMessageQueue(name); + Session = TBusServerSession::Create(&Proto, this, sessionConfig, Bus); +} + +TExampleServer::TExampleServer(unsigned port, const char* name) + : UseCompression(false) + , AckMessageBeforeSendReply(false) + , ForgetRequest(false) +{ + Bus = CreateMessageQueue(name); + TBusServerSessionConfig sessionConfig; + sessionConfig.ListenPort = port; + Session = TBusServerSession::Create(&Proto, this, sessionConfig, Bus); +} + +TExampleServer::~TExampleServer() { +} + +size_t TExampleServer::GetInFlight() const { + return Session->GetInFlight(); +} + +unsigned TExampleServer::GetActualListenPort() const { + return Session->GetActualListenPort(); +} + +TNetAddr TExampleServer::GetActualListenAddr() const { + return TNetAddr("127.0.0.1", GetActualListenPort()); +} + +void TExampleServer::WaitForOnMessageCount(unsigned n) { + TestSync.WaitFor(n); +} + +void TExampleServer::OnMessage(TOnMessageContext& mess) { + TestSync.Inc(); + + TExampleRequest* request = VerifyDynamicCast<TExampleRequest*>(mess.GetMessage()); + + if (ForgetRequest) { + mess.ForgetRequest(); + return; + } + + TAutoPtr<TBusMessage> reply(new TExampleResponse(&Proto.ResponseCount, DataSize.GetOrElse(request->Data.size()))); + reply->SetCompressed(UseCompression); + + EMessageStatus status; + if (AckMessageBeforeSendReply) { + TBusIdentity ident; + mess.AckMessage(ident); + status = Session->SendReply(ident, reply.Release()); // TODO: leaks on error + } else { + status = mess.SendReplyMove(reply); + } + Y_VERIFY(status == MESSAGE_OK, "failed to send reply: %s", ToString(status).data()); -} +} diff --git a/library/cpp/messagebus/test/helper/example.h b/library/cpp/messagebus/test/helper/example.h index 1ff7d16c1a..26b7475308 100644 --- a/library/cpp/messagebus/test/helper/example.h +++ b/library/cpp/messagebus/test/helper/example.h @@ -1,9 +1,9 @@ #pragma once #include <library/cpp/testing/unittest/registar.h> - -#include "alloc_counter.h" -#include "message_handler_error.h" + +#include "alloc_counter.h" +#include "message_handler_error.h" #include <library/cpp/messagebus/ybus.h> #include <library/cpp/messagebus/misc/test_sync.h> @@ -25,7 +25,7 @@ namespace NBus { TExampleRequest(TAtomic* counterPtr, size_t payloadSize = 320); TExampleRequest(ECreateUninitialized, TAtomic* counterPtr); }; - + class TExampleResponse: public TBusMessage { friend class TExampleProtocol; @@ -37,7 +37,7 @@ namespace NBus { TExampleResponse(TAtomic* counterPtr, size_t payloadSize = 320); TExampleResponse(ECreateUninitialized, TAtomic* counterPtr); }; - + class TExampleProtocol: public TBusProtocol { public: TAtomic RequestCount; @@ -45,7 +45,7 @@ namespace NBus { TAtomic RequestCountDeserialized; TAtomic ResponseCountDeserialized; TAtomic StartCount; - + TExampleProtocol(int port = 0); ~TExampleProtocol() override; @@ -54,28 +54,28 @@ namespace NBus { TAutoPtr<TBusMessage> Deserialize(ui16 messageType, TArrayRef<const char> payload) override; }; - + class TExampleClient: private TBusClientHandlerError { public: TExampleProtocol Proto; bool UseCompression; bool CrashOnError; size_t DataSize; - + ssize_t MessageCount; TAtomic RepliesCount; TAtomic Errors; EMessageStatus LastError; - + TSystemEvent WorkDone; - + TBusMessageQueuePtr Bus; TBusClientSessionPtr Session; - + public: TExampleClient(const TBusClientSessionConfig sessionConfig = TBusClientSessionConfig(), int port = 0); ~TExampleClient() override; - + EMessageStatus SendMessage(const TNetAddr* addr = nullptr); void SendMessages(size_t count, const TNetAddr* addr = nullptr); @@ -85,15 +85,15 @@ namespace NBus { void WaitReplies(); EMessageStatus WaitForError(); void WaitForError(EMessageStatus status); - + void SendMessagesWaitReplies(size_t count, const TNetAddr* addr = nullptr); void SendMessagesWaitReplies(size_t count, const TNetAddr& addr); - + void OnReply(TAutoPtr<TBusMessage> mess, TAutoPtr<TBusMessage> reply) override; void OnError(TAutoPtr<TBusMessage> mess, EMessageStatus) override; }; - + class TExampleServer: private TBusServerHandlerError { public: TExampleProtocol Proto; @@ -103,7 +103,7 @@ namespace NBus { bool ForgetRequest; TTestSync TestSync; - + TBusMessageQueuePtr Bus; TBusServerSessionPtr Session; @@ -111,7 +111,7 @@ namespace NBus { TExampleServer( const char* name = "TExampleServer", const TBusServerSessionConfig& sessionConfig = TBusServerSessionConfig()); - + TExampleServer(unsigned port, const char* name = "TExampleServer"); ~TExampleServer() override; @@ -121,9 +121,9 @@ namespace NBus { unsigned GetActualListenPort() const; // any of TNetAddr GetActualListenAddr() const; - + void WaitForOnMessageCount(unsigned n); - + protected: void OnMessage(TOnMessageContext& mess) override; }; diff --git a/library/cpp/messagebus/test/helper/example_module.cpp b/library/cpp/messagebus/test/helper/example_module.cpp index c907825924..65ecfcf73f 100644 --- a/library/cpp/messagebus/test/helper/example_module.cpp +++ b/library/cpp/messagebus/test/helper/example_module.cpp @@ -1,43 +1,43 @@ -#include "example_module.h" - -using namespace NBus; -using namespace NBus::NTest; - -TExampleModule::TExampleModule() - : TBusModule("TExampleModule") -{ - TBusQueueConfig queueConfig; - queueConfig.NumWorkers = 5; - Queue = CreateMessageQueue(queueConfig); -} - -void TExampleModule::StartModule() { - CreatePrivateSessions(Queue.Get()); - StartInput(); -} - -bool TExampleModule::Shutdown() { - TBusModule::Shutdown(); - return true; -} - -TBusServerSessionPtr TExampleModule::CreateExtSession(TBusMessageQueue&) { +#include "example_module.h" + +using namespace NBus; +using namespace NBus::NTest; + +TExampleModule::TExampleModule() + : TBusModule("TExampleModule") +{ + TBusQueueConfig queueConfig; + queueConfig.NumWorkers = 5; + Queue = CreateMessageQueue(queueConfig); +} + +void TExampleModule::StartModule() { + CreatePrivateSessions(Queue.Get()); + StartInput(); +} + +bool TExampleModule::Shutdown() { + TBusModule::Shutdown(); + return true; +} + +TBusServerSessionPtr TExampleModule::CreateExtSession(TBusMessageQueue&) { return nullptr; -} - -TBusServerSessionPtr TExampleServerModule::CreateExtSession(TBusMessageQueue& queue) { - TBusServerSessionPtr r = CreateDefaultDestination(queue, &Proto, TBusServerSessionConfig()); - ServerAddr = TNetAddr("localhost", r->GetActualListenPort()); - return r; -} - +} + +TBusServerSessionPtr TExampleServerModule::CreateExtSession(TBusMessageQueue& queue) { + TBusServerSessionPtr r = CreateDefaultDestination(queue, &Proto, TBusServerSessionConfig()); + ServerAddr = TNetAddr("localhost", r->GetActualListenPort()); + return r; +} + TExampleClientModule::TExampleClientModule() : Source() { } - -TBusServerSessionPtr TExampleClientModule::CreateExtSession(TBusMessageQueue& queue) { - Source = CreateDefaultSource(queue, &Proto, TBusServerSessionConfig()); - Source->RegisterService("localhost"); + +TBusServerSessionPtr TExampleClientModule::CreateExtSession(TBusMessageQueue& queue) { + Source = CreateDefaultSource(queue, &Proto, TBusServerSessionConfig()); + Source->RegisterService("localhost"); return nullptr; -} +} diff --git a/library/cpp/messagebus/test/helper/example_module.h b/library/cpp/messagebus/test/helper/example_module.h index b1b0a6dd14..a0b295f613 100644 --- a/library/cpp/messagebus/test/helper/example_module.h +++ b/library/cpp/messagebus/test/helper/example_module.h @@ -1,7 +1,7 @@ -#pragma once - -#include "example.h" - +#pragma once + +#include "example.h" + #include <library/cpp/messagebus/oldmodule/module.h> namespace NBus { @@ -9,29 +9,29 @@ namespace NBus { struct TExampleModule: public TBusModule { TExampleProtocol Proto; TBusMessageQueuePtr Queue; - + TExampleModule(); - + void StartModule(); - + bool Shutdown() override; - + // nop by default TBusServerSessionPtr CreateExtSession(TBusMessageQueue& queue) override; }; - + struct TExampleServerModule: public TExampleModule { TNetAddr ServerAddr; TBusServerSessionPtr CreateExtSession(TBusMessageQueue& queue) override; }; - + struct TExampleClientModule: public TExampleModule { TBusClientSessionPtr Source; - + TExampleClientModule(); - + TBusServerSessionPtr CreateExtSession(TBusMessageQueue& queue) override; }; - + } } diff --git a/library/cpp/messagebus/test/helper/fixed_port.cpp b/library/cpp/messagebus/test/helper/fixed_port.cpp index f83ce3161a..258da0d1a5 100644 --- a/library/cpp/messagebus/test/helper/fixed_port.cpp +++ b/library/cpp/messagebus/test/helper/fixed_port.cpp @@ -1,10 +1,10 @@ #include "fixed_port.h" #include <util/system/env.h> - + #include <stdlib.h> - + bool NBus::NTest::IsFixedPortTestAllowed() { - // TODO: report skipped tests to test + // TODO: report skipped tests to test return !GetEnv("MB_TESTS_SKIP_FIXED_PORT"); -} +} diff --git a/library/cpp/messagebus/test/helper/fixed_port.h b/library/cpp/messagebus/test/helper/fixed_port.h index 39c8da4dfa..a9c61ebc63 100644 --- a/library/cpp/messagebus/test/helper/fixed_port.h +++ b/library/cpp/messagebus/test/helper/fixed_port.h @@ -1,11 +1,11 @@ -#pragma once - +#pragma once + namespace NBus { namespace NTest { bool IsFixedPortTestAllowed(); - + // Must not be in range OS uses for bind on random port. const unsigned FixedPort = 4927; - + } } diff --git a/library/cpp/messagebus/test/helper/hanging_server.cpp b/library/cpp/messagebus/test/helper/hanging_server.cpp index 3911ff10ba..a35514b00d 100644 --- a/library/cpp/messagebus/test/helper/hanging_server.cpp +++ b/library/cpp/messagebus/test/helper/hanging_server.cpp @@ -1,13 +1,13 @@ #include "hanging_server.h" -#include <util/system/yassert.h> - -using namespace NBus; - +#include <util/system/yassert.h> + +using namespace NBus; + THangingServer::THangingServer(int port) { BindResult = BindOnPort(port, false); -} - -int THangingServer::GetPort() const { - return BindResult.first; -} +} + +int THangingServer::GetPort() const { + return BindResult.first; +} diff --git a/library/cpp/messagebus/test/helper/hanging_server.h b/library/cpp/messagebus/test/helper/hanging_server.h index 384f07d7cf..cc9fb274d8 100644 --- a/library/cpp/messagebus/test/helper/hanging_server.h +++ b/library/cpp/messagebus/test/helper/hanging_server.h @@ -1,16 +1,16 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/network.h> -#include <util/network/sock.h> - -class THangingServer { -private: +#include <util/network/sock.h> + +class THangingServer { +private: std::pair<unsigned, TVector<NBus::TBindResult>> BindResult; -public: - // listen on given port, and nothing else - THangingServer(int port = 0); - // actual port - int GetPort() const; -}; +public: + // listen on given port, and nothing else + THangingServer(int port = 0); + // actual port + int GetPort() const; +}; diff --git a/library/cpp/messagebus/test/helper/message_handler_error.cpp b/library/cpp/messagebus/test/helper/message_handler_error.cpp index 40997adec8..c09811ec67 100644 --- a/library/cpp/messagebus/test/helper/message_handler_error.cpp +++ b/library/cpp/messagebus/test/helper/message_handler_error.cpp @@ -1,26 +1,26 @@ #include "message_handler_error.h" -#include <util/system/yassert.h> - -using namespace NBus; -using namespace NBus::NTest; - -void TBusClientHandlerError::OnError(TAutoPtr<TBusMessage>, EMessageStatus status) { +#include <util/system/yassert.h> + +using namespace NBus; +using namespace NBus::NTest; + +void TBusClientHandlerError::OnError(TAutoPtr<TBusMessage>, EMessageStatus status) { Y_FAIL("must not be called, status: %s", ToString(status).data()); -} - -void TBusClientHandlerError::OnReply(TAutoPtr<TBusMessage>, TAutoPtr<TBusMessage>) { +} + +void TBusClientHandlerError::OnReply(TAutoPtr<TBusMessage>, TAutoPtr<TBusMessage>) { Y_FAIL("must not be called"); -} - -void TBusClientHandlerError::OnMessageSentOneWay(TAutoPtr<TBusMessage>) { +} + +void TBusClientHandlerError::OnMessageSentOneWay(TAutoPtr<TBusMessage>) { Y_FAIL("must not be called"); -} - -void TBusServerHandlerError::OnError(TAutoPtr<TBusMessage>, EMessageStatus status) { +} + +void TBusServerHandlerError::OnError(TAutoPtr<TBusMessage>, EMessageStatus status) { Y_FAIL("must not be called, status: %s", ToString(status).data()); -} - -void TBusServerHandlerError::OnMessage(TOnMessageContext&) { +} + +void TBusServerHandlerError::OnMessage(TOnMessageContext&) { Y_FAIL("must not be called"); -} +} diff --git a/library/cpp/messagebus/test/helper/message_handler_error.h b/library/cpp/messagebus/test/helper/message_handler_error.h index bba0007a44..a314b10761 100644 --- a/library/cpp/messagebus/test/helper/message_handler_error.h +++ b/library/cpp/messagebus/test/helper/message_handler_error.h @@ -1,7 +1,7 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/ybus.h> - + namespace NBus { namespace NTest { struct TBusClientHandlerError: public IBusClientHandler { @@ -9,11 +9,11 @@ namespace NBus { void OnMessageSentOneWay(TAutoPtr<TBusMessage> pMessage) override; void OnReply(TAutoPtr<TBusMessage> pMessage, TAutoPtr<TBusMessage> pReply) override; }; - + struct TBusServerHandlerError: public IBusServerHandler { void OnError(TAutoPtr<TBusMessage> pMessage, EMessageStatus status) override; void OnMessage(TOnMessageContext& pMessage) override; }; - + } } diff --git a/library/cpp/messagebus/test/helper/object_count_check.h b/library/cpp/messagebus/test/helper/object_count_check.h index d844469fb9..1c4756e58c 100644 --- a/library/cpp/messagebus/test/helper/object_count_check.h +++ b/library/cpp/messagebus/test/helper/object_count_check.h @@ -1,5 +1,5 @@ -#pragma once - +#pragma once + #include <library/cpp/testing/unittest/registar.h> #include <library/cpp/messagebus/remote_client_connection.h> @@ -9,66 +9,66 @@ #include <library/cpp/messagebus/ybus.h> #include <library/cpp/messagebus/oldmodule/module.h> #include <library/cpp/messagebus/scheduler/scheduler.h> - + #include <util/generic/object_counter.h> #include <util/system/type_name.h> #include <util/stream/output.h> - + #include <typeinfo> -struct TObjectCountCheck { - bool Enabled; - - template <typename T> - struct TReset { - TObjectCountCheck* const Thiz; - +struct TObjectCountCheck { + bool Enabled; + + template <typename T> + struct TReset { + TObjectCountCheck* const Thiz; + TReset(TObjectCountCheck* thiz) : Thiz(thiz) { } - + void operator()() { long oldValue = TObjectCounter<T>::ResetObjectCount(); - if (oldValue != 0) { + if (oldValue != 0) { Cerr << "warning: previous counter: " << oldValue << " for " << TypeName<T>() << Endl; - Cerr << "won't check in this test" << Endl; - Thiz->Enabled = false; - } - } - }; - - TObjectCountCheck() { - Enabled = true; - DoForAllCounters<TReset>(); - } - - template <typename T> - struct TCheckZero { + Cerr << "won't check in this test" << Endl; + Thiz->Enabled = false; + } + } + }; + + TObjectCountCheck() { + Enabled = true; + DoForAllCounters<TReset>(); + } + + template <typename T> + struct TCheckZero { TCheckZero(TObjectCountCheck*) { } - + void operator()() { UNIT_ASSERT_VALUES_EQUAL_C(0L, TObjectCounter<T>::ObjectCount(), TypeName<T>()); - } - }; - - ~TObjectCountCheck() { - if (Enabled) { - DoForAllCounters<TCheckZero>(); - } - } - - template <template <typename> class TOp> - void DoForAllCounters() { - TOp< ::NBus::NPrivate::TRemoteClientConnection>(this)(); - TOp< ::NBus::NPrivate::TRemoteServerConnection>(this)(); - TOp< ::NBus::NPrivate::TRemoteClientSession>(this)(); - TOp< ::NBus::NPrivate::TRemoteServerSession>(this)(); - TOp< ::NBus::NPrivate::TScheduler>(this)(); - TOp< ::NEventLoop::TEventLoop>(this)(); - TOp< ::NEventLoop::TChannel>(this)(); - TOp< ::NBus::TBusModule>(this)(); - TOp< ::NBus::TBusJob>(this)(); - } -}; + } + }; + + ~TObjectCountCheck() { + if (Enabled) { + DoForAllCounters<TCheckZero>(); + } + } + + template <template <typename> class TOp> + void DoForAllCounters() { + TOp< ::NBus::NPrivate::TRemoteClientConnection>(this)(); + TOp< ::NBus::NPrivate::TRemoteServerConnection>(this)(); + TOp< ::NBus::NPrivate::TRemoteClientSession>(this)(); + TOp< ::NBus::NPrivate::TRemoteServerSession>(this)(); + TOp< ::NBus::NPrivate::TScheduler>(this)(); + TOp< ::NEventLoop::TEventLoop>(this)(); + TOp< ::NEventLoop::TChannel>(this)(); + TOp< ::NBus::TBusModule>(this)(); + TOp< ::NBus::TBusJob>(this)(); + } +}; diff --git a/library/cpp/messagebus/test/helper/wait_for.h b/library/cpp/messagebus/test/helper/wait_for.h index ebd0bfd6e2..f09958d4c0 100644 --- a/library/cpp/messagebus/test/helper/wait_for.h +++ b/library/cpp/messagebus/test/helper/wait_for.h @@ -1,14 +1,14 @@ -#pragma once - -#include <util/datetime/base.h> -#include <util/system/yassert.h> - +#pragma once + +#include <util/datetime/base.h> +#include <util/system/yassert.h> + #define UNIT_WAIT_FOR(condition) \ do { \ - TInstant start(TInstant::Now()); \ - while (!(condition) && (TInstant::Now() - start < TDuration::Seconds(10))) { \ + TInstant start(TInstant::Now()); \ + while (!(condition) && (TInstant::Now() - start < TDuration::Seconds(10))) { \ Sleep(TDuration::MilliSeconds(1)); \ - } \ - /* TODO: use UNIT_ASSERT if in unittest thread */ \ + } \ + /* TODO: use UNIT_ASSERT if in unittest thread */ \ Y_VERIFY(condition, "condition failed after 10 seconds wait"); \ - } while (0) + } while (0) diff --git a/library/cpp/messagebus/test/helper/ya.make b/library/cpp/messagebus/test/helper/ya.make index 703f6b6953..97bd45f573 100644 --- a/library/cpp/messagebus/test/helper/ya.make +++ b/library/cpp/messagebus/test/helper/ya.make @@ -1,17 +1,17 @@ -LIBRARY(messagebus_test_helper) - +LIBRARY(messagebus_test_helper) + OWNER(g:messagebus) - -SRCS( - example.cpp - example_module.cpp - fixed_port.cpp - message_handler_error.cpp - hanging_server.cpp -) - -PEERDIR( + +SRCS( + example.cpp + example_module.cpp + fixed_port.cpp + message_handler_error.cpp + hanging_server.cpp +) + +PEERDIR( library/cpp/messagebus/oldmodule -) - -END() +) + +END() diff --git a/library/cpp/messagebus/test/perftest/messages.proto b/library/cpp/messagebus/test/perftest/messages.proto index a48bb2f480..8919034e7a 100644 --- a/library/cpp/messagebus/test/perftest/messages.proto +++ b/library/cpp/messagebus/test/perftest/messages.proto @@ -1,7 +1,7 @@ -message TPerftestRequestRecord { - required string Data = 1; -} - -message TPerftestResponseRecord { - required string Data = 1; -} +message TPerftestRequestRecord { + required string Data = 1; +} + +message TPerftestResponseRecord { + required string Data = 1; +} diff --git a/library/cpp/messagebus/test/perftest/perftest.cpp b/library/cpp/messagebus/test/perftest/perftest.cpp index 44fb4d837d..8489319278 100644 --- a/library/cpp/messagebus/test/perftest/perftest.cpp +++ b/library/cpp/messagebus/test/perftest/perftest.cpp @@ -15,10 +15,10 @@ #include <library/cpp/lwtrace/start.h> #include <library/cpp/sighandler/async_signals_handler.h> #include <library/cpp/threading/future/legacy_future.h> - + #include <util/generic/ptr.h> #include <util/generic/string.h> -#include <util/generic/vector.h> +#include <util/generic/vector.h> #include <util/generic/yexception.h> #include <util/random/random.h> #include <util/stream/file.h> @@ -29,18 +29,18 @@ #include <util/system/sysstat.h> #include <util/system/thread.h> #include <util/thread/lfqueue.h> - + #include <signal.h> #include <stdlib.h> - -using namespace NBus; - -/////////////////////////////////////////////////////// -/// \brief Configuration parameters of the test - -const int DEFAULT_PORT = 55666; - -struct TPerftestConfig { + +using namespace NBus; + +/////////////////////////////////////////////////////// +/// \brief Configuration parameters of the test + +const int DEFAULT_PORT = 55666; + +struct TPerftestConfig { TString Nodes; ///< node1:port1,node2:port2 int ClientCount; int MessageSize; ///< size of message to send @@ -53,144 +53,144 @@ struct TPerftestConfig { bool ExecuteOnReplyInWorkerPool; bool UseCompression; bool Profile; - unsigned WwwPort; - - TPerftestConfig(); - - void Print() { - fprintf(stderr, "ClientCount=%d\n", ClientCount); - fprintf(stderr, "ServerPort=%d\n", ServerPort); - fprintf(stderr, "Delay=%d usecs\n", Delay); + unsigned WwwPort; + + TPerftestConfig(); + + void Print() { + fprintf(stderr, "ClientCount=%d\n", ClientCount); + fprintf(stderr, "ServerPort=%d\n", ServerPort); + fprintf(stderr, "Delay=%d usecs\n", Delay); fprintf(stderr, "MessageSize=%d bytes\n", MessageSize); fprintf(stderr, "Failure=%.3f%%\n", Failure * 100.0); - fprintf(stderr, "Runtime=%d seconds\n", Run); - fprintf(stderr, "ServerUseModules=%s\n", ServerUseModules ? "true" : "false"); - fprintf(stderr, "ExecuteOnMessageInWorkerPool=%s\n", ExecuteOnMessageInWorkerPool ? "true" : "false"); - fprintf(stderr, "ExecuteOnReplyInWorkerPool=%s\n", ExecuteOnReplyInWorkerPool ? "true" : "false"); - fprintf(stderr, "UseCompression=%s\n", UseCompression ? "true" : "false"); - fprintf(stderr, "Profile=%s\n", Profile ? "true" : "false"); - fprintf(stderr, "WwwPort=%u\n", WwwPort); - } -}; - + fprintf(stderr, "Runtime=%d seconds\n", Run); + fprintf(stderr, "ServerUseModules=%s\n", ServerUseModules ? "true" : "false"); + fprintf(stderr, "ExecuteOnMessageInWorkerPool=%s\n", ExecuteOnMessageInWorkerPool ? "true" : "false"); + fprintf(stderr, "ExecuteOnReplyInWorkerPool=%s\n", ExecuteOnReplyInWorkerPool ? "true" : "false"); + fprintf(stderr, "UseCompression=%s\n", UseCompression ? "true" : "false"); + fprintf(stderr, "Profile=%s\n", Profile ? "true" : "false"); + fprintf(stderr, "WwwPort=%u\n", WwwPort); + } +}; + extern TPerftestConfig* TheConfig; -extern bool TheExit; - +extern bool TheExit; + TVector<TNetAddr> ServerAddresses; - -struct TConfig { - TBusQueueConfig ServerQueueConfig; - TBusQueueConfig ClientQueueConfig; - TBusServerSessionConfig ServerSessionConfig; - TBusClientSessionConfig ClientSessionConfig; - bool SimpleProtocol; - -private: - void ConfigureDefaults(TBusQueueConfig& config) { - config.NumWorkers = 4; - } - - void ConfigureDefaults(TBusSessionConfig& config) { - config.MaxInFlight = 10000; - config.SendTimeout = TDuration::Seconds(20).MilliSeconds(); - config.TotalTimeout = TDuration::Seconds(60).MilliSeconds(); - } - -public: - TConfig() - : SimpleProtocol(false) - { - ConfigureDefaults(ServerQueueConfig); - ConfigureDefaults(ClientQueueConfig); - ConfigureDefaults(ServerSessionConfig); - ConfigureDefaults(ClientSessionConfig); - } - - void Print() { - // TODO: do not print server if only client and vice verse - Cerr << "server queue config:\n"; - Cerr << IndentText(ServerQueueConfig.PrintToString()); - Cerr << "server session config:" << Endl; - Cerr << IndentText(ServerSessionConfig.PrintToString()); - Cerr << "client queue config:\n"; - Cerr << IndentText(ClientQueueConfig.PrintToString()); - Cerr << "client session config:" << Endl; - Cerr << IndentText(ClientSessionConfig.PrintToString()); - Cerr << "simple protocol: " << SimpleProtocol << "\n"; - } -}; - -TConfig Config; - -//////////////////////////////////////////////////////////////// -/// \brief Fast message - + +struct TConfig { + TBusQueueConfig ServerQueueConfig; + TBusQueueConfig ClientQueueConfig; + TBusServerSessionConfig ServerSessionConfig; + TBusClientSessionConfig ClientSessionConfig; + bool SimpleProtocol; + +private: + void ConfigureDefaults(TBusQueueConfig& config) { + config.NumWorkers = 4; + } + + void ConfigureDefaults(TBusSessionConfig& config) { + config.MaxInFlight = 10000; + config.SendTimeout = TDuration::Seconds(20).MilliSeconds(); + config.TotalTimeout = TDuration::Seconds(60).MilliSeconds(); + } + +public: + TConfig() + : SimpleProtocol(false) + { + ConfigureDefaults(ServerQueueConfig); + ConfigureDefaults(ClientQueueConfig); + ConfigureDefaults(ServerSessionConfig); + ConfigureDefaults(ClientSessionConfig); + } + + void Print() { + // TODO: do not print server if only client and vice verse + Cerr << "server queue config:\n"; + Cerr << IndentText(ServerQueueConfig.PrintToString()); + Cerr << "server session config:" << Endl; + Cerr << IndentText(ServerSessionConfig.PrintToString()); + Cerr << "client queue config:\n"; + Cerr << IndentText(ClientQueueConfig.PrintToString()); + Cerr << "client session config:" << Endl; + Cerr << IndentText(ClientSessionConfig.PrintToString()); + Cerr << "simple protocol: " << SimpleProtocol << "\n"; + } +}; + +TConfig Config; + +//////////////////////////////////////////////////////////////// +/// \brief Fast message + using TPerftestRequest = TBusBufferMessage<TPerftestRequestRecord, 77>; using TPerftestResponse = TBusBufferMessage<TPerftestResponseRecord, 79>; - -static size_t RequestSize() { - return RandomNumber<size_t>(TheConfig->MessageSize * 2 + 1); -} - -TAutoPtr<TBusMessage> NewRequest() { - if (Config.SimpleProtocol) { - TAutoPtr<TSimpleMessage> r(new TSimpleMessage); - r->SetCompressed(TheConfig->UseCompression); - r->Payload = 10; - return r.Release(); - } else { - TAutoPtr<TPerftestRequest> r(new TPerftestRequest); - r->SetCompressed(TheConfig->UseCompression); - // TODO: use random content for better compression test + +static size_t RequestSize() { + return RandomNumber<size_t>(TheConfig->MessageSize * 2 + 1); +} + +TAutoPtr<TBusMessage> NewRequest() { + if (Config.SimpleProtocol) { + TAutoPtr<TSimpleMessage> r(new TSimpleMessage); + r->SetCompressed(TheConfig->UseCompression); + r->Payload = 10; + return r.Release(); + } else { + TAutoPtr<TPerftestRequest> r(new TPerftestRequest); + r->SetCompressed(TheConfig->UseCompression); + // TODO: use random content for better compression test r->Record.SetData(TString(RequestSize(), '?')); - return r.Release(); - } -} - -void CheckRequest(TPerftestRequest* request) { + return r.Release(); + } +} + +void CheckRequest(TPerftestRequest* request) { const TString& data = request->Record.GetData(); - for (size_t i = 0; i != data.size(); ++i) { + for (size_t i = 0; i != data.size(); ++i) { Y_VERIFY(data.at(i) == '?', "must be question mark"); - } -} - -TAutoPtr<TPerftestResponse> NewResponse(TPerftestRequest* request) { - TAutoPtr<TPerftestResponse> r(new TPerftestResponse); - r->SetCompressed(TheConfig->UseCompression); + } +} + +TAutoPtr<TPerftestResponse> NewResponse(TPerftestRequest* request) { + TAutoPtr<TPerftestResponse> r(new TPerftestResponse); + r->SetCompressed(TheConfig->UseCompression); r->Record.SetData(TString(request->Record.GetData().size(), '.')); - return r; -} - -void CheckResponse(TPerftestResponse* response) { + return r; +} + +void CheckResponse(TPerftestResponse* response) { const TString& data = response->Record.GetData(); - for (size_t i = 0; i != data.size(); ++i) { + for (size_t i = 0; i != data.size(); ++i) { Y_VERIFY(data.at(i) == '.', "must be dot"); - } -} - -//////////////////////////////////////////////////////////////////// -/// \brief Fast protocol that common between client and server -class TPerftestProtocol: public TBusBufferProtocol { -public: - TPerftestProtocol() - : TBusBufferProtocol("TPerftestProtocol", TheConfig->ServerPort) - { - RegisterType(new TPerftestRequest); - RegisterType(new TPerftestResponse); - } -}; - -class TPerftestServer; -class TPerftestUsingModule; -class TPerftestClient; - -struct TTestStats { - TInstant Start; - - TAtomic Messages; - TAtomic Errors; - TAtomic Replies; - + } +} + +//////////////////////////////////////////////////////////////////// +/// \brief Fast protocol that common between client and server +class TPerftestProtocol: public TBusBufferProtocol { +public: + TPerftestProtocol() + : TBusBufferProtocol("TPerftestProtocol", TheConfig->ServerPort) + { + RegisterType(new TPerftestRequest); + RegisterType(new TPerftestResponse); + } +}; + +class TPerftestServer; +class TPerftestUsingModule; +class TPerftestClient; + +struct TTestStats { + TInstant Start; + + TAtomic Messages; + TAtomic Errors; + TAtomic Replies; + void IncMessage() { AtomicIncrement(Messages); } @@ -211,265 +211,265 @@ struct TTestStats { int NumReplies() { return AtomicGet(Replies); } - + double GetThroughput() { - return NumReplies() * 1000000.0 / (TInstant::Now() - Start).MicroSeconds(); - } - -public: - TTestStats() - : Start(TInstant::Now()) - , Messages(0) - , Errors(0) - , Replies(0) - { - } - - void PeriodicallyPrint(); -}; - -TTestStats Stats; - -//////////////////////////////////////////////////////////////////// -/// \brief Fast of the client session + return NumReplies() * 1000000.0 / (TInstant::Now() - Start).MicroSeconds(); + } + +public: + TTestStats() + : Start(TInstant::Now()) + , Messages(0) + , Errors(0) + , Replies(0) + { + } + + void PeriodicallyPrint(); +}; + +TTestStats Stats; + +//////////////////////////////////////////////////////////////////// +/// \brief Fast of the client session class TPerftestClient : IBusClientHandler { -public: - TBusClientSessionPtr Session; - THolder<TBusProtocol> Proto; - TBusMessageQueuePtr Bus; +public: + TBusClientSessionPtr Session; + THolder<TBusProtocol> Proto; + TBusMessageQueuePtr Bus; TVector<TBusClientConnectionPtr> Connections; - -public: - /// constructor creates instances of protocol and session - TPerftestClient() { - /// create or get instance of message queue, need one per application - Bus = CreateMessageQueue(Config.ClientQueueConfig, "client"); - - if (Config.SimpleProtocol) { - Proto.Reset(new TSimpleProtocol); - } else { - Proto.Reset(new TPerftestProtocol); - } - - Session = TBusClientSession::Create(Proto.Get(), this, Config.ClientSessionConfig, Bus); - - for (unsigned i = 0; i < ServerAddresses.size(); ++i) { - Connections.push_back(Session->GetConnection(ServerAddresses[i])); - } - } - - /// dispatch of requests is done here - void Work() { + +public: + /// constructor creates instances of protocol and session + TPerftestClient() { + /// create or get instance of message queue, need one per application + Bus = CreateMessageQueue(Config.ClientQueueConfig, "client"); + + if (Config.SimpleProtocol) { + Proto.Reset(new TSimpleProtocol); + } else { + Proto.Reset(new TPerftestProtocol); + } + + Session = TBusClientSession::Create(Proto.Get(), this, Config.ClientSessionConfig, Bus); + + for (unsigned i = 0; i < ServerAddresses.size(); ++i) { + Connections.push_back(Session->GetConnection(ServerAddresses[i])); + } + } + + /// dispatch of requests is done here + void Work() { SetCurrentThreadName("FastClient::Work"); - - while (!TheExit) { - TBusClientConnection* connection; - if (Connections.size() == 1) { - connection = Connections.front().Get(); - } else { - connection = Connections.at(RandomNumber<size_t>()).Get(); - } - + + while (!TheExit) { + TBusClientConnection* connection; + if (Connections.size() == 1) { + connection = Connections.front().Get(); + } else { + connection = Connections.at(RandomNumber<size_t>()).Get(); + } + TBusMessage* message = NewRequest().Release(); - int ret = connection->SendMessage(message, true); - - if (ret == MESSAGE_OK) { - Stats.IncMessage(); - } else if (ret == MESSAGE_BUSY) { - //delete message; - //Sleep(TDuration::MilliSeconds(1)); - //continue; + int ret = connection->SendMessage(message, true); + + if (ret == MESSAGE_OK) { + Stats.IncMessage(); + } else if (ret == MESSAGE_BUSY) { + //delete message; + //Sleep(TDuration::MilliSeconds(1)); + //continue; Y_FAIL("unreachable"); - } else if (ret == MESSAGE_SHUTDOWN) { - delete message; - } else { - delete message; - Stats.IncErrors(); - } - } - } - - void Stop() { - Session->Shutdown(); - } - - /// actual work is being done here + } else if (ret == MESSAGE_SHUTDOWN) { + delete message; + } else { + delete message; + Stats.IncErrors(); + } + } + } + + void Stop() { + Session->Shutdown(); + } + + /// actual work is being done here void OnReply(TAutoPtr<TBusMessage> mess, TAutoPtr<TBusMessage> reply) override { Y_UNUSED(mess); - - if (Config.SimpleProtocol) { - VerifyDynamicCast<TSimpleMessage*>(reply.Get()); - } else { - TPerftestResponse* typed = VerifyDynamicCast<TPerftestResponse*>(reply.Get()); - - CheckResponse(typed); - } - - Stats.IncReplies(); - } - - /// message that could not be delivered + + if (Config.SimpleProtocol) { + VerifyDynamicCast<TSimpleMessage*>(reply.Get()); + } else { + TPerftestResponse* typed = VerifyDynamicCast<TPerftestResponse*>(reply.Get()); + + CheckResponse(typed); + } + + Stats.IncReplies(); + } + + /// message that could not be delivered void OnError(TAutoPtr<TBusMessage> mess, EMessageStatus status) override { Y_UNUSED(mess); Y_UNUSED(status); - - if (TheExit) { - return; - } - - Stats.IncErrors(); - + + if (TheExit) { + return; + } + + Stats.IncErrors(); + // Y_ASSERT(TheConfig->Failure > 0.0); - } -}; - -class TPerftestServerCommon { -public: - THolder<TBusProtocol> Proto; - - TBusMessageQueuePtr Bus; - - TBusServerSessionPtr Session; - -protected: - TPerftestServerCommon(const char* name) - : Session() - { - if (Config.SimpleProtocol) { - Proto.Reset(new TSimpleProtocol); - } else { - Proto.Reset(new TPerftestProtocol); - } - - /// create or get instance of single message queue, need one for application - Bus = CreateMessageQueue(Config.ServerQueueConfig, name); - } - -public: - void Stop() { - Session->Shutdown(); - } -}; - -struct TAsyncRequest { - TBusMessage* Request; - TInstant ReceivedTime; -}; - -///////////////////////////////////////////////////////////////////// -/// \brief Fast of the server session -class TPerftestServer: public TPerftestServerCommon, public IBusServerHandler { -public: - TLockFreeQueue<TAsyncRequest> AsyncRequests; - -public: - TPerftestServer() - : TPerftestServerCommon("server") - { - /// register destination session - Session = TBusServerSession::Create(Proto.Get(), this, Config.ServerSessionConfig, Bus); + } +}; + +class TPerftestServerCommon { +public: + THolder<TBusProtocol> Proto; + + TBusMessageQueuePtr Bus; + + TBusServerSessionPtr Session; + +protected: + TPerftestServerCommon(const char* name) + : Session() + { + if (Config.SimpleProtocol) { + Proto.Reset(new TSimpleProtocol); + } else { + Proto.Reset(new TPerftestProtocol); + } + + /// create or get instance of single message queue, need one for application + Bus = CreateMessageQueue(Config.ServerQueueConfig, name); + } + +public: + void Stop() { + Session->Shutdown(); + } +}; + +struct TAsyncRequest { + TBusMessage* Request; + TInstant ReceivedTime; +}; + +///////////////////////////////////////////////////////////////////// +/// \brief Fast of the server session +class TPerftestServer: public TPerftestServerCommon, public IBusServerHandler { +public: + TLockFreeQueue<TAsyncRequest> AsyncRequests; + +public: + TPerftestServer() + : TPerftestServerCommon("server") + { + /// register destination session + Session = TBusServerSession::Create(Proto.Get(), this, Config.ServerSessionConfig, Bus); Y_ASSERT(Session && "probably somebody is listening on the same port"); - } - - /// when message comes, send reply + } + + /// when message comes, send reply void OnMessage(TOnMessageContext& mess) override { - if (Config.SimpleProtocol) { - TSimpleMessage* typed = VerifyDynamicCast<TSimpleMessage*>(mess.GetMessage()); - TAutoPtr<TSimpleMessage> response(new TSimpleMessage); - response->Payload = typed->Payload; - mess.SendReplyMove(response); - return; - } - - TPerftestRequest* typed = VerifyDynamicCast<TPerftestRequest*>(mess.GetMessage()); - - CheckRequest(typed); - - /// forget replies for few messages, see what happends + if (Config.SimpleProtocol) { + TSimpleMessage* typed = VerifyDynamicCast<TSimpleMessage*>(mess.GetMessage()); + TAutoPtr<TSimpleMessage> response(new TSimpleMessage); + response->Payload = typed->Payload; + mess.SendReplyMove(response); + return; + } + + TPerftestRequest* typed = VerifyDynamicCast<TPerftestRequest*>(mess.GetMessage()); + + CheckRequest(typed); + + /// forget replies for few messages, see what happends if (TheConfig->Failure > RandomNumber<double>()) { - return; - } - - /// sleep requested time - if (TheConfig->Delay) { - TAsyncRequest request; - request.Request = mess.ReleaseMessage(); - request.ReceivedTime = TInstant::Now(); - AsyncRequests.Enqueue(request); - return; - } - - TAutoPtr<TPerftestResponse> reply(NewResponse(typed)); - /// sent empty reply for each message - mess.SendReplyMove(reply); - // TODO: count results - } - - void Stop() { - TPerftestServerCommon::Stop(); - } -}; - -class TPerftestUsingModule: public TPerftestServerCommon, public TBusModule { -public: - TPerftestUsingModule() - : TPerftestServerCommon("server") - , TBusModule("fast") - { + return; + } + + /// sleep requested time + if (TheConfig->Delay) { + TAsyncRequest request; + request.Request = mess.ReleaseMessage(); + request.ReceivedTime = TInstant::Now(); + AsyncRequests.Enqueue(request); + return; + } + + TAutoPtr<TPerftestResponse> reply(NewResponse(typed)); + /// sent empty reply for each message + mess.SendReplyMove(reply); + // TODO: count results + } + + void Stop() { + TPerftestServerCommon::Stop(); + } +}; + +class TPerftestUsingModule: public TPerftestServerCommon, public TBusModule { +public: + TPerftestUsingModule() + : TPerftestServerCommon("server") + , TBusModule("fast") + { Y_VERIFY(CreatePrivateSessions(Bus.Get()), "failed to initialize dupdetect module"); Y_VERIFY(StartInput(), "failed to start input"); - } - + } + ~TPerftestUsingModule() override { - Shutdown(); - } - -private: + Shutdown(); + } + +private: TJobHandler Start(TBusJob* job, TBusMessage* mess) override { - TPerftestRequest* typed = VerifyDynamicCast<TPerftestRequest*>(mess); - CheckRequest(typed); - - /// sleep requested time - if (TheConfig->Delay) { - usleep(TheConfig->Delay); - } - - /// forget replies for few messages, see what happends + TPerftestRequest* typed = VerifyDynamicCast<TPerftestRequest*>(mess); + CheckRequest(typed); + + /// sleep requested time + if (TheConfig->Delay) { + usleep(TheConfig->Delay); + } + + /// forget replies for few messages, see what happends if (TheConfig->Failure > RandomNumber<double>()) { return nullptr; - } - - job->SendReply(NewResponse(typed).Release()); + } + + job->SendReply(NewResponse(typed).Release()); return nullptr; - } - + } + TBusServerSessionPtr CreateExtSession(TBusMessageQueue& queue) override { - return Session = CreateDefaultDestination(queue, Proto.Get(), Config.ServerSessionConfig); - } -}; - + return Session = CreateDefaultDestination(queue, Proto.Get(), Config.ServerSessionConfig); + } +}; + // ./perftest/perftest -s 11456 -c localhost:11456 -r 60 -n 4 -i 5000 using namespace std; using namespace NBus; -static TNetworkAddress ParseNetworkAddress(const char* string) { +static TNetworkAddress ParseNetworkAddress(const char* string) { TString Name; int Port; const char* port = strchr(string, ':'); if (port != nullptr) { - Name.append(string, port - string); + Name.append(string, port - string); Port = atoi(port + 1); } else { - Name.append(string); - Port = TheConfig->ServerPort != 0 ? TheConfig->ServerPort : DEFAULT_PORT; + Name.append(string); + Port = TheConfig->ServerPort != 0 ? TheConfig->ServerPort : DEFAULT_PORT; } - return TNetworkAddress(Name, Port); -} - + return TNetworkAddress(Name, Port); +} + TVector<TNetAddr> ParseNodes(const TString nodes) { TVector<TNetAddr> r; @@ -480,234 +480,234 @@ TVector<TNetAddr> ParseNodes(const TString nodes) { for (int i = 0; i < int(numh); i++) { const TNetworkAddress& networkAddress = ParseNetworkAddress(hosts[i].data()); Y_VERIFY(networkAddress.Begin() != networkAddress.End(), "no addresses"); - r.push_back(TNetAddr(networkAddress, &*networkAddress.Begin())); + r.push_back(TNetAddr(networkAddress, &*networkAddress.Begin())); } - return r; + return r; } -TPerftestConfig::TPerftestConfig() { - TBusSessionConfig defaultConfig; - - ServerPort = DEFAULT_PORT; +TPerftestConfig::TPerftestConfig() { + TBusSessionConfig defaultConfig; + + ServerPort = DEFAULT_PORT; Delay = 0; // artificial delay inside server OnMessage() MessageSize = 200; Failure = 0.00; Run = 60; // in seconds Nodes = "localhost"; - ServerUseModules = false; - ExecuteOnMessageInWorkerPool = defaultConfig.ExecuteOnMessageInWorkerPool; - ExecuteOnReplyInWorkerPool = defaultConfig.ExecuteOnReplyInWorkerPool; - UseCompression = false; - Profile = false; - WwwPort = 0; + ServerUseModules = false; + ExecuteOnMessageInWorkerPool = defaultConfig.ExecuteOnMessageInWorkerPool; + ExecuteOnReplyInWorkerPool = defaultConfig.ExecuteOnReplyInWorkerPool; + UseCompression = false; + Profile = false; + WwwPort = 0; } TPerftestConfig* TheConfig = new TPerftestConfig(); bool TheExit = false; - + TSystemEvent StopEvent; TSimpleSharedPtr<TPerftestServer> Server; TSimpleSharedPtr<TPerftestUsingModule> ServerUsingModule; - + TVector<TSimpleSharedPtr<TPerftestClient>> Clients; -TMutex ClientsLock; - +TMutex ClientsLock; + void stopsignal(int /*sig*/) { fprintf(stderr, "\n-------------------- exiting ------------------\n"); TheExit = true; - StopEvent.Signal(); + StopEvent.Signal(); } // -s <num> - start server on port <num> // -c <node:port,node:port> - start client -void TTestStats::PeriodicallyPrint() { +void TTestStats::PeriodicallyPrint() { SetCurrentThreadName("print-stats"); - - for (;;) { - StopEvent.WaitT(TDuration::Seconds(1)); - if (TheExit) - break; - + + for (;;) { + StopEvent.WaitT(TDuration::Seconds(1)); + if (TheExit) + break; + TVector<TSimpleSharedPtr<TPerftestClient>> clients; - { - TGuard<TMutex> guard(ClientsLock); - clients = Clients; - } - - fprintf(stderr, "replies=%d errors=%d throughput=%.3f mess/sec\n", + { + TGuard<TMutex> guard(ClientsLock); + clients = Clients; + } + + fprintf(stderr, "replies=%d errors=%d throughput=%.3f mess/sec\n", NumReplies(), NumErrors(), GetThroughput()); - if (!!Server) { - fprintf(stderr, "server: q: %u %s\n", + if (!!Server) { + fprintf(stderr, "server: q: %u %s\n", (unsigned)Server->Bus->GetExecutor()->GetWorkQueueSize(), Server->Session->GetStatusSingleLine().data()); - } - if (!!ServerUsingModule) { - fprintf(stderr, "server: q: %u %s\n", + } + if (!!ServerUsingModule) { + fprintf(stderr, "server: q: %u %s\n", (unsigned)ServerUsingModule->Bus->GetExecutor()->GetWorkQueueSize(), ServerUsingModule->Session->GetStatusSingleLine().data()); - } + } for (const auto& client : clients) { - fprintf(stderr, "client: q: %u %s\n", + fprintf(stderr, "client: q: %u %s\n", (unsigned)client->Bus->GetExecutor()->GetWorkQueueSize(), client->Session->GetStatusSingleLine().data()); - } - - TStringStream stats; - - bool first = true; - if (!!Server) { - if (!first) { - stats << "\n"; - } - first = false; - stats << "server:\n"; - stats << IndentText(Server->Bus->GetStatus()); - } - if (!!ServerUsingModule) { - if (!first) { - stats << "\n"; - } - first = false; - stats << "server using modules:\n"; - stats << IndentText(ServerUsingModule->Bus->GetStatus()); - } + } + + TStringStream stats; + + bool first = true; + if (!!Server) { + if (!first) { + stats << "\n"; + } + first = false; + stats << "server:\n"; + stats << IndentText(Server->Bus->GetStatus()); + } + if (!!ServerUsingModule) { + if (!first) { + stats << "\n"; + } + first = false; + stats << "server using modules:\n"; + stats << IndentText(ServerUsingModule->Bus->GetStatus()); + } for (const auto& client : clients) { - if (!first) { - stats << "\n"; - } - first = false; - stats << "client:\n"; + if (!first) { + stats << "\n"; + } + first = false; + stats << "client:\n"; stats << IndentText(client->Bus->GetStatus()); - } - + } + TUnbufferedFileOutput("stats").Write(stats.Str()); - } -} - + } +} + int main(int argc, char* argv[]) { - NLWTrace::StartLwtraceFromEnv(); + NLWTrace::StartLwtraceFromEnv(); /* unix foo */ setvbuf(stdout, nullptr, _IONBF, 0); setvbuf(stderr, nullptr, _IONBF, 0); Umask(0); SetAsyncSignalHandler(SIGINT, stopsignal); - SetAsyncSignalHandler(SIGTERM, stopsignal); + SetAsyncSignalHandler(SIGTERM, stopsignal); #ifndef _win_ - SetAsyncSignalHandler(SIGUSR1, stopsignal); + SetAsyncSignalHandler(SIGUSR1, stopsignal); #endif signal(SIGPIPE, SIG_IGN); - NLastGetopt::TOpts opts = NLastGetopt::TOpts::Default(); - opts.AddLongOption('s', "server-port", "server port").RequiredArgument("port").StoreResult(&TheConfig->ServerPort); - opts.AddCharOption('m', "average message size").RequiredArgument("size").StoreResult(&TheConfig->MessageSize); - opts.AddLongOption('c', "server-host", "server hosts").RequiredArgument("host[,host]...").StoreResult(&TheConfig->Nodes); + NLastGetopt::TOpts opts = NLastGetopt::TOpts::Default(); + opts.AddLongOption('s', "server-port", "server port").RequiredArgument("port").StoreResult(&TheConfig->ServerPort); + opts.AddCharOption('m', "average message size").RequiredArgument("size").StoreResult(&TheConfig->MessageSize); + opts.AddLongOption('c', "server-host", "server hosts").RequiredArgument("host[,host]...").StoreResult(&TheConfig->Nodes); opts.AddCharOption('f', "failure rate (rational number between 0 and 1)").RequiredArgument("rate").StoreResult(&TheConfig->Failure); opts.AddCharOption('w', "delay before reply").RequiredArgument("microseconds").StoreResult(&TheConfig->Delay); opts.AddCharOption('r', "run duration").RequiredArgument("seconds").StoreResult(&TheConfig->Run); opts.AddLongOption("client-count", "amount of clients").RequiredArgument("count").StoreResult(&TheConfig->ClientCount).DefaultValue("1"); - opts.AddLongOption("server-use-modules").StoreResult(&TheConfig->ServerUseModules, true); - opts.AddLongOption("on-message-in-pool", "execute OnMessage callback in worker pool") + opts.AddLongOption("server-use-modules").StoreResult(&TheConfig->ServerUseModules, true); + opts.AddLongOption("on-message-in-pool", "execute OnMessage callback in worker pool") .RequiredArgument("BOOL") .StoreResult(&TheConfig->ExecuteOnMessageInWorkerPool); - opts.AddLongOption("on-reply-in-pool", "execute OnReply callback in worker pool") + opts.AddLongOption("on-reply-in-pool", "execute OnReply callback in worker pool") .RequiredArgument("BOOL") .StoreResult(&TheConfig->ExecuteOnReplyInWorkerPool); - opts.AddLongOption("compression", "use compression").RequiredArgument("BOOL").StoreResult(&TheConfig->UseCompression); - opts.AddLongOption("simple-proto").SetFlag(&Config.SimpleProtocol); - opts.AddLongOption("profile").SetFlag(&TheConfig->Profile); - opts.AddLongOption("www-port").RequiredArgument("PORT").StoreResult(&TheConfig->WwwPort); - opts.AddHelpOption(); - - Config.ServerQueueConfig.ConfigureLastGetopt(opts, "server-"); - Config.ServerSessionConfig.ConfigureLastGetopt(opts, "server-"); - Config.ClientQueueConfig.ConfigureLastGetopt(opts, "client-"); - Config.ClientSessionConfig.ConfigureLastGetopt(opts, "client-"); - - opts.SetFreeArgsMax(0); - - NLastGetopt::TOptsParseResult parseResult(&opts, argc, argv); - + opts.AddLongOption("compression", "use compression").RequiredArgument("BOOL").StoreResult(&TheConfig->UseCompression); + opts.AddLongOption("simple-proto").SetFlag(&Config.SimpleProtocol); + opts.AddLongOption("profile").SetFlag(&TheConfig->Profile); + opts.AddLongOption("www-port").RequiredArgument("PORT").StoreResult(&TheConfig->WwwPort); + opts.AddHelpOption(); + + Config.ServerQueueConfig.ConfigureLastGetopt(opts, "server-"); + Config.ServerSessionConfig.ConfigureLastGetopt(opts, "server-"); + Config.ClientQueueConfig.ConfigureLastGetopt(opts, "client-"); + Config.ClientSessionConfig.ConfigureLastGetopt(opts, "client-"); + + opts.SetFreeArgsMax(0); + + NLastGetopt::TOptsParseResult parseResult(&opts, argc, argv); + TheConfig->Print(); - Config.Print(); + Config.Print(); - if (TheConfig->Profile) { - BeginProfiling(); - } - - TIntrusivePtr<TBusWww> www(new TBusWww); - - ServerAddresses = ParseNodes(TheConfig->Nodes); + if (TheConfig->Profile) { + BeginProfiling(); + } + + TIntrusivePtr<TBusWww> www(new TBusWww); + + ServerAddresses = ParseNodes(TheConfig->Nodes); if (TheConfig->ServerPort) { - if (TheConfig->ServerUseModules) { - ServerUsingModule = new TPerftestUsingModule(); - www->RegisterModule(ServerUsingModule.Get()); - } else { - Server = new TPerftestServer(); - www->RegisterServerSession(Server->Session); - } + if (TheConfig->ServerUseModules) { + ServerUsingModule = new TPerftestUsingModule(); + www->RegisterModule(ServerUsingModule.Get()); + } else { + Server = new TPerftestServer(); + www->RegisterServerSession(Server->Session); + } } TVector<TSimpleSharedPtr<NThreading::TLegacyFuture<void, false>>> futures; - - if (ServerAddresses.size() > 0 && TheConfig->ClientCount > 0) { - for (int i = 0; i < TheConfig->ClientCount; ++i) { - TGuard<TMutex> guard(ClientsLock); - Clients.push_back(new TPerftestClient); + + if (ServerAddresses.size() > 0 && TheConfig->ClientCount > 0) { + for (int i = 0; i < TheConfig->ClientCount; ++i) { + TGuard<TMutex> guard(ClientsLock); + Clients.push_back(new TPerftestClient); futures.push_back(new NThreading::TLegacyFuture<void, false>(std::bind(&TPerftestClient::Work, Clients.back()))); - www->RegisterClientSession(Clients.back()->Session); - } + www->RegisterClientSession(Clients.back()->Session); + } } futures.push_back(new NThreading::TLegacyFuture<void, false>(std::bind(&TTestStats::PeriodicallyPrint, std::ref(Stats)))); - - THolder<TBusWwwHttpServer> wwwServer; - if (TheConfig->WwwPort != 0) { - wwwServer.Reset(new TBusWwwHttpServer(www, TheConfig->WwwPort)); - } - - /* sit here until signal terminate our process */ - StopEvent.WaitT(TDuration::Seconds(TheConfig->Run)); - TheExit = true; - StopEvent.Signal(); - - if (!!Server) { - Cerr << "Stopping server\n"; - Server->Stop(); - } - if (!!ServerUsingModule) { - Cerr << "Stopping server (using modules)\n"; - ServerUsingModule->Stop(); - } - + + THolder<TBusWwwHttpServer> wwwServer; + if (TheConfig->WwwPort != 0) { + wwwServer.Reset(new TBusWwwHttpServer(www, TheConfig->WwwPort)); + } + + /* sit here until signal terminate our process */ + StopEvent.WaitT(TDuration::Seconds(TheConfig->Run)); + TheExit = true; + StopEvent.Signal(); + + if (!!Server) { + Cerr << "Stopping server\n"; + Server->Stop(); + } + if (!!ServerUsingModule) { + Cerr << "Stopping server (using modules)\n"; + ServerUsingModule->Stop(); + } + TVector<TSimpleSharedPtr<TPerftestClient>> clients; - { - TGuard<TMutex> guard(ClientsLock); - clients = Clients; - } - - if (!clients.empty()) { - Cerr << "Stopping clients\n"; - + { + TGuard<TMutex> guard(ClientsLock); + clients = Clients; + } + + if (!clients.empty()) { + Cerr << "Stopping clients\n"; + for (auto& client : clients) { client->Stop(); - } - } - - wwwServer.Destroy(); - + } + } + + wwwServer.Destroy(); + for (const auto& future : futures) { future->Get(); - } - - if (TheConfig->Profile) { - EndProfiling(); - } - - Cerr << "***SUCCESS***\n"; + } + + if (TheConfig->Profile) { + EndProfiling(); + } + + Cerr << "***SUCCESS***\n"; return 0; } diff --git a/library/cpp/messagebus/test/perftest/simple_proto.cpp b/library/cpp/messagebus/test/perftest/simple_proto.cpp index 7fab33be6b..19d6c15b9d 100644 --- a/library/cpp/messagebus/test/perftest/simple_proto.cpp +++ b/library/cpp/messagebus/test/perftest/simple_proto.cpp @@ -1,22 +1,22 @@ #include "simple_proto.h" - -#include <util/generic/cast.h> - + +#include <util/generic/cast.h> + #include <typeinfo> - -using namespace NBus; - + +using namespace NBus; + void TSimpleProtocol::Serialize(const TBusMessage* mess, TBuffer& data) { Y_VERIFY(typeid(TSimpleMessage) == typeid(*mess)); - const TSimpleMessage* typed = static_cast<const TSimpleMessage*>(mess); + const TSimpleMessage* typed = static_cast<const TSimpleMessage*>(mess); data.Append((const char*)&typed->Payload, 4); -} - +} + TAutoPtr<TBusMessage> TSimpleProtocol::Deserialize(ui16, TArrayRef<const char> payload) { - if (payload.size() != 4) { + if (payload.size() != 4) { return nullptr; - } - TAutoPtr<TSimpleMessage> r(new TSimpleMessage); - memcpy(&r->Payload, payload.data(), 4); - return r.Release(); -} + } + TAutoPtr<TSimpleMessage> r(new TSimpleMessage); + memcpy(&r->Payload, payload.data(), 4); + return r.Release(); +} diff --git a/library/cpp/messagebus/test/perftest/simple_proto.h b/library/cpp/messagebus/test/perftest/simple_proto.h index 8b0275cf51..4a0cc08db3 100644 --- a/library/cpp/messagebus/test/perftest/simple_proto.h +++ b/library/cpp/messagebus/test/perftest/simple_proto.h @@ -1,29 +1,29 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/ybus.h> - + struct TSimpleMessage: public NBus::TBusMessage { - ui32 Payload; - - TSimpleMessage() + ui32 Payload; + + TSimpleMessage() : TBusMessage(1) , Payload(0) { } - - TSimpleMessage(NBus::ECreateUninitialized) - : TBusMessage(NBus::ECreateUninitialized()) + + TSimpleMessage(NBus::ECreateUninitialized) + : TBusMessage(NBus::ECreateUninitialized()) { } -}; - -struct TSimpleProtocol: public NBus::TBusProtocol { +}; + +struct TSimpleProtocol: public NBus::TBusProtocol { TSimpleProtocol() : NBus::TBusProtocol("simple", 55666) { } - + void Serialize(const NBus::TBusMessage* mess, TBuffer& data) override; - + TAutoPtr<NBus::TBusMessage> Deserialize(ui16 ty, TArrayRef<const char> payload) override; -}; +}; diff --git a/library/cpp/messagebus/test/perftest/stackcollect.diff b/library/cpp/messagebus/test/perftest/stackcollect.diff index a454de3a5d..658f0141b3 100644 --- a/library/cpp/messagebus/test/perftest/stackcollect.diff +++ b/library/cpp/messagebus/test/perftest/stackcollect.diff @@ -1,13 +1,13 @@ -Index: test/perftest/CMakeLists.txt -=================================================================== ---- test/perftest/CMakeLists.txt (revision 1088840) -+++ test/perftest/CMakeLists.txt (working copy) -@@ -3,7 +3,7 @@ PROGRAM(messagebus_perftest) - OWNER(nga) - - PEERDIR( +Index: test/perftest/CMakeLists.txt +=================================================================== +--- test/perftest/CMakeLists.txt (revision 1088840) ++++ test/perftest/CMakeLists.txt (working copy) +@@ -3,7 +3,7 @@ PROGRAM(messagebus_perftest) + OWNER(nga) + + PEERDIR( - library/cpp/execprofile -+ junk/davenger/stackcollect ++ junk/davenger/stackcollect library/cpp/messagebus library/cpp/messagebus/protobuf library/cpp/sighandler diff --git a/library/cpp/messagebus/test/perftest/ya.make b/library/cpp/messagebus/test/perftest/ya.make index 37038ed2a5..24c2848ed5 100644 --- a/library/cpp/messagebus/test/perftest/ya.make +++ b/library/cpp/messagebus/test/perftest/ya.make @@ -1,7 +1,7 @@ -PROGRAM(messagebus_perftest) +PROGRAM(messagebus_perftest) OWNER(g:messagebus) - + PEERDIR( library/cpp/deprecated/threadable library/cpp/execprofile @@ -16,9 +16,9 @@ PEERDIR( ) SRCS( - messages.proto + messages.proto perftest.cpp - simple_proto.cpp + simple_proto.cpp ) END() diff --git a/library/cpp/messagebus/test/ut/count_down_latch.h b/library/cpp/messagebus/test/ut/count_down_latch.h index fb6374e773..5117db5731 100644 --- a/library/cpp/messagebus/test/ut/count_down_latch.h +++ b/library/cpp/messagebus/test/ut/count_down_latch.h @@ -1,30 +1,30 @@ -#pragma once - -#include <util/system/atomic.h> -#include <util/system/event.h> - -class TCountDownLatch { -private: - TAtomic Current; +#pragma once + +#include <util/system/atomic.h> +#include <util/system/event.h> + +class TCountDownLatch { +private: + TAtomic Current; TSystemEvent EventObject; -public: - TCountDownLatch(unsigned initial) - : Current(initial) +public: + TCountDownLatch(unsigned initial) + : Current(initial) { } - - void CountDown() { - if (AtomicDecrement(Current) == 0) { - EventObject.Signal(); - } - } - - void Await() { - EventObject.Wait(); - } - - bool Await(TDuration timeout) { - return EventObject.WaitT(timeout); - } -}; + + void CountDown() { + if (AtomicDecrement(Current) == 0) { + EventObject.Signal(); + } + } + + void Await() { + EventObject.Wait(); + } + + bool Await(TDuration timeout) { + return EventObject.WaitT(timeout); + } +}; diff --git a/library/cpp/messagebus/test/ut/messagebus_ut.cpp b/library/cpp/messagebus/test/ut/messagebus_ut.cpp index 42d4a1e9b2..040f9b7702 100644 --- a/library/cpp/messagebus/test/ut/messagebus_ut.cpp +++ b/library/cpp/messagebus/test/ut/messagebus_ut.cpp @@ -8,104 +8,104 @@ #include <library/cpp/messagebus/misc/test_sync.h> -#include <util/network/sock.h> - +#include <util/network/sock.h> + #include <utility> using namespace NBus; using namespace NBus::NTest; -namespace { - struct TExampleClientSlowOnMessageSent: public TExampleClient { - TAtomic SentCompleted; - +namespace { + struct TExampleClientSlowOnMessageSent: public TExampleClient { + TAtomic SentCompleted; + TSystemEvent ReplyReceived; - - TExampleClientSlowOnMessageSent() - : SentCompleted(0) + + TExampleClientSlowOnMessageSent() + : SentCompleted(0) { } - + ~TExampleClientSlowOnMessageSent() override { - Session->Shutdown(); - } - + Session->Shutdown(); + } + void OnReply(TAutoPtr<TBusMessage> mess, TAutoPtr<TBusMessage> reply) override { Y_VERIFY(AtomicGet(SentCompleted), "must be completed"); - - TExampleClient::OnReply(mess, reply); - - ReplyReceived.Signal(); - } - + + TExampleClient::OnReply(mess, reply); + + ReplyReceived.Signal(); + } + void OnMessageSent(TBusMessage*) override { - Sleep(TDuration::MilliSeconds(100)); - AtomicSet(SentCompleted, 1); - } - }; - -} - + Sleep(TDuration::MilliSeconds(100)); + AtomicSet(SentCompleted, 1); + } + }; + +} + Y_UNIT_TEST_SUITE(TMessageBusTests) { - void TestDestinationTemplate(bool useCompression, bool ackMessageBeforeReply, + void TestDestinationTemplate(bool useCompression, bool ackMessageBeforeReply, const TBusServerSessionConfig& sessionConfig) { - TObjectCountCheck objectCountCheck; - - TExampleServer server; - - TExampleClient client(sessionConfig); - client.CrashOnError = true; - - server.UseCompression = useCompression; - client.UseCompression = useCompression; - - server.AckMessageBeforeSendReply = ackMessageBeforeReply; - - client.SendMessagesWaitReplies(100, server.GetActualListenAddr()); - UNIT_ASSERT_EQUAL(server.Session->GetInFlight(), 0); - UNIT_ASSERT_EQUAL(client.Session->GetInFlight(), 0); - } - + TObjectCountCheck objectCountCheck; + + TExampleServer server; + + TExampleClient client(sessionConfig); + client.CrashOnError = true; + + server.UseCompression = useCompression; + client.UseCompression = useCompression; + + server.AckMessageBeforeSendReply = ackMessageBeforeReply; + + client.SendMessagesWaitReplies(100, server.GetActualListenAddr()); + UNIT_ASSERT_EQUAL(server.Session->GetInFlight(), 0); + UNIT_ASSERT_EQUAL(client.Session->GetInFlight(), 0); + } + Y_UNIT_TEST(TestDestination) { - TestDestinationTemplate(false, false, TBusServerSessionConfig()); - } - + TestDestinationTemplate(false, false, TBusServerSessionConfig()); + } + Y_UNIT_TEST(TestDestinationUsingAck) { - TestDestinationTemplate(false, true, TBusServerSessionConfig()); - } - + TestDestinationTemplate(false, true, TBusServerSessionConfig()); + } + Y_UNIT_TEST(TestDestinationWithCompression) { - TestDestinationTemplate(true, false, TBusServerSessionConfig()); - } - + TestDestinationTemplate(true, false, TBusServerSessionConfig()); + } + Y_UNIT_TEST(TestCork) { - TBusServerSessionConfig config; - config.SendThreshold = 1000000000000; - config.Cork = TDuration::MilliSeconds(10); - TestDestinationTemplate(false, false, config); - // TODO: test for cork hanging - } - + TBusServerSessionConfig config; + config.SendThreshold = 1000000000000; + config.Cork = TDuration::MilliSeconds(10); + TestDestinationTemplate(false, false, config); + // TODO: test for cork hanging + } + Y_UNIT_TEST(TestReconnect) { - if (!IsFixedPortTestAllowed()) { - return; - } - - TObjectCountCheck objectCountCheck; - - unsigned port = FixedPort; - TNetAddr serverAddr("localhost", port); - THolder<TExampleServer> server; - - TBusClientSessionConfig clientConfig; + if (!IsFixedPortTestAllowed()) { + return; + } + + TObjectCountCheck objectCountCheck; + + unsigned port = FixedPort; + TNetAddr serverAddr("localhost", port); + THolder<TExampleServer> server; + + TBusClientSessionConfig clientConfig; clientConfig.RetryInterval = 0; - TExampleClient client(clientConfig); - - server.Reset(new TExampleServer(port, "TExampleServer 1")); - - client.SendMessagesWaitReplies(17, serverAddr); - - server.Destroy(); + TExampleClient client(clientConfig); + + server.Reset(new TExampleServer(port, "TExampleServer 1")); + + client.SendMessagesWaitReplies(17, serverAddr); + + server.Destroy(); // Making the client to detect disconnection. client.SendMessages(1, serverAddr); @@ -116,11 +116,11 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { } UNIT_ASSERT_VALUES_EQUAL(MESSAGE_CONNECT_FAILED, error); - server.Reset(new TExampleServer(port, "TExampleServer 2")); - - client.SendMessagesWaitReplies(19, serverAddr); - } - + server.Reset(new TExampleServer(port, "TExampleServer 2")); + + client.SendMessagesWaitReplies(19, serverAddr); + } + struct TestNoServerImplClient: public TExampleClient { TTestSync TestSync; int failures = 0; @@ -145,8 +145,8 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { }; void TestNoServerImpl(unsigned port, bool oneWay) { - TNetAddr noServerAddr("localhost", port); - + TNetAddr noServerAddr("localhost", port); + TestNoServerImplClient client; int count = 0; @@ -174,167 +174,167 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { void HangingServerImpl(unsigned port) { TNetAddr noServerAddr("localhost", port); - TExampleClient client; - - int count = 0; - for (;; ++count) { - TAutoPtr<TBusMessage> message(new TExampleRequest(&client.Proto.RequestCount)); - EMessageStatus status = client.Session->SendMessageAutoPtr(message, &noServerAddr); - if (status == MESSAGE_BUSY) { - break; - } - UNIT_ASSERT_VALUES_EQUAL(int(MESSAGE_OK), int(status)); - - if (count == 0) { - // lame way to wait until it is connected - Sleep(TDuration::MilliSeconds(10)); - } - } - - UNIT_ASSERT_VALUES_EQUAL(client.Session->GetConfig()->MaxInFlight, count); - } - + TExampleClient client; + + int count = 0; + for (;; ++count) { + TAutoPtr<TBusMessage> message(new TExampleRequest(&client.Proto.RequestCount)); + EMessageStatus status = client.Session->SendMessageAutoPtr(message, &noServerAddr); + if (status == MESSAGE_BUSY) { + break; + } + UNIT_ASSERT_VALUES_EQUAL(int(MESSAGE_OK), int(status)); + + if (count == 0) { + // lame way to wait until it is connected + Sleep(TDuration::MilliSeconds(10)); + } + } + + UNIT_ASSERT_VALUES_EQUAL(client.Session->GetConfig()->MaxInFlight, count); + } + Y_UNIT_TEST(TestHangindServer) { - TObjectCountCheck objectCountCheck; - - THangingServer server(0); - + TObjectCountCheck objectCountCheck; + + THangingServer server(0); + HangingServerImpl(server.GetPort()); - } - + } + Y_UNIT_TEST(TestNoServer) { - TObjectCountCheck objectCountCheck; - + TObjectCountCheck objectCountCheck; + TestNoServerImpl(17, false); - } - + } + Y_UNIT_TEST(PauseInput) { - TObjectCountCheck objectCountCheck; - - TExampleServer server; - server.Session->PauseInput(true); - - TBusClientSessionConfig clientConfig; - clientConfig.MaxInFlight = 1000; - TExampleClient client(clientConfig); - - client.SendMessages(100, server.GetActualListenAddr()); - - server.TestSync.Check(0); - - server.Session->PauseInput(false); - - server.TestSync.WaitFor(100); - - client.WaitReplies(); - - server.Session->PauseInput(true); - - client.SendMessages(200, server.GetActualListenAddr()); - - server.TestSync.Check(100); - - server.Session->PauseInput(false); - - server.TestSync.WaitFor(300); - - client.WaitReplies(); - } - + TObjectCountCheck objectCountCheck; + + TExampleServer server; + server.Session->PauseInput(true); + + TBusClientSessionConfig clientConfig; + clientConfig.MaxInFlight = 1000; + TExampleClient client(clientConfig); + + client.SendMessages(100, server.GetActualListenAddr()); + + server.TestSync.Check(0); + + server.Session->PauseInput(false); + + server.TestSync.WaitFor(100); + + client.WaitReplies(); + + server.Session->PauseInput(true); + + client.SendMessages(200, server.GetActualListenAddr()); + + server.TestSync.Check(100); + + server.Session->PauseInput(false); + + server.TestSync.WaitFor(300); + + client.WaitReplies(); + } + struct TSendTimeoutCheckerExampleClient: public TExampleClient { - static TBusClientSessionConfig SessionConfig(bool periodLessThanConnectTimeout) { - TBusClientSessionConfig sessionConfig; - if (periodLessThanConnectTimeout) { - sessionConfig.SendTimeout = 1; - sessionConfig.Secret.TimeoutPeriod = TDuration::MilliSeconds(50); - } else { - sessionConfig.SendTimeout = 50; - sessionConfig.Secret.TimeoutPeriod = TDuration::MilliSeconds(1); - } - return sessionConfig; - } - - TSendTimeoutCheckerExampleClient(bool periodLessThanConnectTimeout) - : TExampleClient(SessionConfig(periodLessThanConnectTimeout)) + static TBusClientSessionConfig SessionConfig(bool periodLessThanConnectTimeout) { + TBusClientSessionConfig sessionConfig; + if (periodLessThanConnectTimeout) { + sessionConfig.SendTimeout = 1; + sessionConfig.Secret.TimeoutPeriod = TDuration::MilliSeconds(50); + } else { + sessionConfig.SendTimeout = 50; + sessionConfig.Secret.TimeoutPeriod = TDuration::MilliSeconds(1); + } + return sessionConfig; + } + + TSendTimeoutCheckerExampleClient(bool periodLessThanConnectTimeout) + : TExampleClient(SessionConfig(periodLessThanConnectTimeout)) { } - + ~TSendTimeoutCheckerExampleClient() override { - Session->Shutdown(); - } - + Session->Shutdown(); + } + TSystemEvent ErrorHappened; - + void OnError(TAutoPtr<TBusMessage>, EMessageStatus status) override { Y_VERIFY(status == MESSAGE_CONNECT_FAILED || status == MESSAGE_TIMEOUT, "got status: %s", ToString(status).data()); - ErrorHappened.Signal(); - } - }; - - void NoServer_SendTimeout_Callback_Impl(bool periodLessThanConnectTimeout) { - TObjectCountCheck objectCountCheck; - - TNetAddr serverAddr("localhost", 17); - - TSendTimeoutCheckerExampleClient client(periodLessThanConnectTimeout); - - client.SendMessages(1, serverAddr); - - client.ErrorHappened.WaitI(); - } - + ErrorHappened.Signal(); + } + }; + + void NoServer_SendTimeout_Callback_Impl(bool periodLessThanConnectTimeout) { + TObjectCountCheck objectCountCheck; + + TNetAddr serverAddr("localhost", 17); + + TSendTimeoutCheckerExampleClient client(periodLessThanConnectTimeout); + + client.SendMessages(1, serverAddr); + + client.ErrorHappened.WaitI(); + } + Y_UNIT_TEST(NoServer_SendTimeout_Callback_PeriodLess) { - NoServer_SendTimeout_Callback_Impl(true); - } - + NoServer_SendTimeout_Callback_Impl(true); + } + Y_UNIT_TEST(NoServer_SendTimeout_Callback_TimeoutLess) { - NoServer_SendTimeout_Callback_Impl(false); - } - + NoServer_SendTimeout_Callback_Impl(false); + } + Y_UNIT_TEST(TestOnReplyCalledAfterOnMessageSent) { - TObjectCountCheck objectCountCheck; - - TExampleServer server; - TNetAddr serverAddr = server.GetActualListenAddr(); - TExampleClientSlowOnMessageSent client; - - TAutoPtr<TExampleRequest> message(new TExampleRequest(&client.Proto.RequestCount)); - EMessageStatus s = client.Session->SendMessageAutoPtr(message, &serverAddr); - UNIT_ASSERT_EQUAL(s, MESSAGE_OK); - - UNIT_ASSERT(client.ReplyReceived.WaitT(TDuration::Seconds(5))); - } - - struct TDelayReplyServer: public TBusServerHandlerError { - TBusMessageQueuePtr Bus; - TExampleProtocol Proto; + TObjectCountCheck objectCountCheck; + + TExampleServer server; + TNetAddr serverAddr = server.GetActualListenAddr(); + TExampleClientSlowOnMessageSent client; + + TAutoPtr<TExampleRequest> message(new TExampleRequest(&client.Proto.RequestCount)); + EMessageStatus s = client.Session->SendMessageAutoPtr(message, &serverAddr); + UNIT_ASSERT_EQUAL(s, MESSAGE_OK); + + UNIT_ASSERT(client.ReplyReceived.WaitT(TDuration::Seconds(5))); + } + + struct TDelayReplyServer: public TBusServerHandlerError { + TBusMessageQueuePtr Bus; + TExampleProtocol Proto; TSystemEvent MessageReceivedEvent; // 1 wait for 1 message - TBusServerSessionPtr Session; + TBusServerSessionPtr Session; TMutex Lock_; TDeque<TAutoPtr<TOnMessageContext>> DelayedMessages; - + TDelayReplyServer() : MessageReceivedEvent(TEventResetType::rAuto) { - Bus = CreateMessageQueue("TDelayReplyServer"); - TBusServerSessionConfig sessionConfig; - sessionConfig.SendTimeout = 1000; - sessionConfig.TotalTimeout = 2001; - Session = TBusServerSession::Create(&Proto, this, sessionConfig, Bus); - if (!Session) { - ythrow yexception() << "Failed to create destination session"; - } - } - + Bus = CreateMessageQueue("TDelayReplyServer"); + TBusServerSessionConfig sessionConfig; + sessionConfig.SendTimeout = 1000; + sessionConfig.TotalTimeout = 2001; + Session = TBusServerSession::Create(&Proto, this, sessionConfig, Bus); + if (!Session) { + ythrow yexception() << "Failed to create destination session"; + } + } + void OnMessage(TOnMessageContext& mess) override { Y_VERIFY(mess.IsConnectionAlive(), "connection should be alive here"); TAutoPtr<TOnMessageContext> delayedMsg(new TOnMessageContext); delayedMsg->Swap(mess); auto g(Guard(Lock_)); DelayedMessages.push_back(delayedMsg); - MessageReceivedEvent.Signal(); + MessageReceivedEvent.Signal(); } - + bool CheckClientIsAlive() { auto g(Guard(Lock_)); for (auto& delayedMessage : DelayedMessages) { @@ -370,252 +370,252 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { msg.SendReplyMove(reply); } } - + size_t GetDelayedMessageCount() const { auto g(Guard(Lock_)); return DelayedMessages.size(); - } - + } + void OnError(TAutoPtr<TBusMessage> mess, EMessageStatus status) override { Y_UNUSED(mess); Y_VERIFY(status == MESSAGE_SHUTDOWN, "only shutdown allowed, got %s", ToString(status).data()); - } - }; - + } + }; + Y_UNIT_TEST(TestReplyCalledAfterClientDisconnected) { - TObjectCountCheck objectCountCheck; - - TDelayReplyServer server; - - THolder<TExampleClient> client(new TExampleClient); - - client->SendMessages(1, TNetAddr("localhost", server.Session->GetActualListenPort())); - - UNIT_ASSERT(server.MessageReceivedEvent.WaitT(TDuration::Seconds(5))); - - UNIT_ASSERT_VALUES_EQUAL(1, server.Session->GetInFlight()); - - client.Destroy(); - + TObjectCountCheck objectCountCheck; + + TDelayReplyServer server; + + THolder<TExampleClient> client(new TExampleClient); + + client->SendMessages(1, TNetAddr("localhost", server.Session->GetActualListenPort())); + + UNIT_ASSERT(server.MessageReceivedEvent.WaitT(TDuration::Seconds(5))); + + UNIT_ASSERT_VALUES_EQUAL(1, server.Session->GetInFlight()); + + client.Destroy(); + UNIT_WAIT_FOR(server.CheckClientIsDead()); - + server.ReplyToDelayedMessages(); - // wait until all server message are delivered - UNIT_WAIT_FOR(0 == server.Session->GetInFlight()); - } - - struct TPackUnpackServer: public TBusServerHandlerError { - TBusMessageQueuePtr Bus; - TExampleProtocol Proto; + // wait until all server message are delivered + UNIT_WAIT_FOR(0 == server.Session->GetInFlight()); + } + + struct TPackUnpackServer: public TBusServerHandlerError { + TBusMessageQueuePtr Bus; + TExampleProtocol Proto; TSystemEvent MessageReceivedEvent; TSystemEvent ClientDiedEvent; - TBusServerSessionPtr Session; - - TPackUnpackServer() { - Bus = CreateMessageQueue("TPackUnpackServer"); - TBusServerSessionConfig sessionConfig; - Session = TBusServerSession::Create(&Proto, this, sessionConfig, Bus); - } - + TBusServerSessionPtr Session; + + TPackUnpackServer() { + Bus = CreateMessageQueue("TPackUnpackServer"); + TBusServerSessionConfig sessionConfig; + Session = TBusServerSession::Create(&Proto, this, sessionConfig, Bus); + } + void OnMessage(TOnMessageContext& mess) override { - TBusIdentity ident; - mess.AckMessage(ident); - - char packed[BUS_IDENTITY_PACKED_SIZE]; - ident.Pack(packed); - TBusIdentity resurrected; - resurrected.Unpack(packed); - - mess.GetSession()->SendReply(resurrected, new TExampleResponse(&Proto.ResponseCount)); - } - + TBusIdentity ident; + mess.AckMessage(ident); + + char packed[BUS_IDENTITY_PACKED_SIZE]; + ident.Pack(packed); + TBusIdentity resurrected; + resurrected.Unpack(packed); + + mess.GetSession()->SendReply(resurrected, new TExampleResponse(&Proto.ResponseCount)); + } + void OnError(TAutoPtr<TBusMessage> mess, EMessageStatus status) override { Y_UNUSED(mess); Y_VERIFY(status == MESSAGE_SHUTDOWN, "only shutdown allowed"); - } - }; - + } + }; + Y_UNIT_TEST(PackUnpack) { - TObjectCountCheck objectCountCheck; - - TPackUnpackServer server; - - THolder<TExampleClient> client(new TExampleClient); - - client->SendMessagesWaitReplies(1, TNetAddr("localhost", server.Session->GetActualListenPort())); - } - + TObjectCountCheck objectCountCheck; + + TPackUnpackServer server; + + THolder<TExampleClient> client(new TExampleClient); + + client->SendMessagesWaitReplies(1, TNetAddr("localhost", server.Session->GetActualListenPort())); + } + Y_UNIT_TEST(ClientRequestTooLarge) { - TObjectCountCheck objectCountCheck; - - TExampleServer server; - - TBusClientSessionConfig clientConfig; - clientConfig.MaxMessageSize = 100; - TExampleClient client(clientConfig); - - client.DataSize = 10; - client.SendMessagesWaitReplies(1, server.GetActualListenAddr()); - - client.DataSize = 1000; - client.SendMessages(1, server.GetActualListenAddr()); - client.WaitForError(MESSAGE_MESSAGE_TOO_LARGE); - - client.DataSize = 20; - client.SendMessagesWaitReplies(10, server.GetActualListenAddr()); - - client.DataSize = 10000; - client.SendMessages(1, server.GetActualListenAddr()); - client.WaitForError(MESSAGE_MESSAGE_TOO_LARGE); - } - + TObjectCountCheck objectCountCheck; + + TExampleServer server; + + TBusClientSessionConfig clientConfig; + clientConfig.MaxMessageSize = 100; + TExampleClient client(clientConfig); + + client.DataSize = 10; + client.SendMessagesWaitReplies(1, server.GetActualListenAddr()); + + client.DataSize = 1000; + client.SendMessages(1, server.GetActualListenAddr()); + client.WaitForError(MESSAGE_MESSAGE_TOO_LARGE); + + client.DataSize = 20; + client.SendMessagesWaitReplies(10, server.GetActualListenAddr()); + + client.DataSize = 10000; + client.SendMessages(1, server.GetActualListenAddr()); + client.WaitForError(MESSAGE_MESSAGE_TOO_LARGE); + } + struct TServerForResponseTooLarge: public TExampleServer { - TTestSync TestSync; - - static TBusServerSessionConfig Config() { - TBusServerSessionConfig config; - config.MaxMessageSize = 100; - return config; - } - - TServerForResponseTooLarge() - : TExampleServer("TServerForResponseTooLarge", Config()) + TTestSync TestSync; + + static TBusServerSessionConfig Config() { + TBusServerSessionConfig config; + config.MaxMessageSize = 100; + return config; + } + + TServerForResponseTooLarge() + : TExampleServer("TServerForResponseTooLarge", Config()) { } - + ~TServerForResponseTooLarge() override { - Session->Shutdown(); - } - + Session->Shutdown(); + } + void OnMessage(TOnMessageContext& mess) override { - TAutoPtr<TBusMessage> response; - - if (TestSync.Get() == 0) { - TestSync.CheckAndIncrement(0); - response.Reset(new TExampleResponse(&Proto.ResponseCount, 1000)); - } else { - TestSync.WaitForAndIncrement(3); - response.Reset(new TExampleResponse(&Proto.ResponseCount, 10)); - } - - mess.SendReplyMove(response); - } - + TAutoPtr<TBusMessage> response; + + if (TestSync.Get() == 0) { + TestSync.CheckAndIncrement(0); + response.Reset(new TExampleResponse(&Proto.ResponseCount, 1000)); + } else { + TestSync.WaitForAndIncrement(3); + response.Reset(new TExampleResponse(&Proto.ResponseCount, 10)); + } + + mess.SendReplyMove(response); + } + void OnError(TAutoPtr<TBusMessage>, EMessageStatus status) override { - TestSync.WaitForAndIncrement(1); - + TestSync.WaitForAndIncrement(1); + Y_VERIFY(status == MESSAGE_MESSAGE_TOO_LARGE, "status"); - } - }; - + } + }; + Y_UNIT_TEST(ServerResponseTooLarge) { - TObjectCountCheck objectCountCheck; - - TServerForResponseTooLarge server; - - TExampleClient client; - client.DataSize = 10; - - client.SendMessages(1, server.GetActualListenAddr()); - server.TestSync.WaitForAndIncrement(2); - client.ResetCounters(); - - client.SendMessages(1, server.GetActualListenAddr()); - - client.WorkDone.WaitI(); - - server.TestSync.CheckAndIncrement(4); - - UNIT_ASSERT_VALUES_EQUAL(1, client.Session->GetInFlight()); - } - + TObjectCountCheck objectCountCheck; + + TServerForResponseTooLarge server; + + TExampleClient client; + client.DataSize = 10; + + client.SendMessages(1, server.GetActualListenAddr()); + server.TestSync.WaitForAndIncrement(2); + client.ResetCounters(); + + client.SendMessages(1, server.GetActualListenAddr()); + + client.WorkDone.WaitI(); + + server.TestSync.CheckAndIncrement(4); + + UNIT_ASSERT_VALUES_EQUAL(1, client.Session->GetInFlight()); + } + struct TServerForRequestTooLarge: public TExampleServer { - TTestSync TestSync; - - static TBusServerSessionConfig Config() { - TBusServerSessionConfig config; - config.MaxMessageSize = 100; - return config; - } - - TServerForRequestTooLarge() - : TExampleServer("TServerForRequestTooLarge", Config()) + TTestSync TestSync; + + static TBusServerSessionConfig Config() { + TBusServerSessionConfig config; + config.MaxMessageSize = 100; + return config; + } + + TServerForRequestTooLarge() + : TExampleServer("TServerForRequestTooLarge", Config()) { } - + ~TServerForRequestTooLarge() override { - Session->Shutdown(); - } - + Session->Shutdown(); + } + void OnMessage(TOnMessageContext& req) override { - unsigned n = TestSync.Get(); - if (n < 2) { - TestSync.CheckAndIncrement(n); - TAutoPtr<TExampleResponse> resp(new TExampleResponse(&Proto.ResponseCount, 10)); - req.SendReplyMove(resp); - } else { + unsigned n = TestSync.Get(); + if (n < 2) { + TestSync.CheckAndIncrement(n); + TAutoPtr<TExampleResponse> resp(new TExampleResponse(&Proto.ResponseCount, 10)); + req.SendReplyMove(resp); + } else { Y_FAIL("wrong"); - } - } - }; - + } + } + }; + Y_UNIT_TEST(ServerRequestTooLarge) { - TObjectCountCheck objectCountCheck; - - TServerForRequestTooLarge server; - - TExampleClient client; - client.DataSize = 10; - - client.SendMessagesWaitReplies(2, server.GetActualListenAddr()); - - server.TestSync.CheckAndIncrement(2); - - client.DataSize = 200; - client.SendMessages(1, server.GetActualListenAddr()); - // server closes connection, so MESSAGE_DELIVERY_FAILED is returned to client - client.WaitForError(MESSAGE_DELIVERY_FAILED); - } - + TObjectCountCheck objectCountCheck; + + TServerForRequestTooLarge server; + + TExampleClient client; + client.DataSize = 10; + + client.SendMessagesWaitReplies(2, server.GetActualListenAddr()); + + server.TestSync.CheckAndIncrement(2); + + client.DataSize = 200; + client.SendMessages(1, server.GetActualListenAddr()); + // server closes connection, so MESSAGE_DELIVERY_FAILED is returned to client + client.WaitForError(MESSAGE_DELIVERY_FAILED); + } + Y_UNIT_TEST(ClientResponseTooLarge) { - TObjectCountCheck objectCountCheck; - - TExampleServer server; - - server.DataSize = 10; - - TBusClientSessionConfig clientSessionConfig; - clientSessionConfig.MaxMessageSize = 100; - TExampleClient client(clientSessionConfig); - client.DataSize = 10; - - client.SendMessagesWaitReplies(3, server.GetActualListenAddr()); - - server.DataSize = 1000; - - client.SendMessages(1, server.GetActualListenAddr()); - client.WaitForError(MESSAGE_DELIVERY_FAILED); - } - + TObjectCountCheck objectCountCheck; + + TExampleServer server; + + server.DataSize = 10; + + TBusClientSessionConfig clientSessionConfig; + clientSessionConfig.MaxMessageSize = 100; + TExampleClient client(clientSessionConfig); + client.DataSize = 10; + + client.SendMessagesWaitReplies(3, server.GetActualListenAddr()); + + server.DataSize = 1000; + + client.SendMessages(1, server.GetActualListenAddr()); + client.WaitForError(MESSAGE_DELIVERY_FAILED); + } + Y_UNIT_TEST(ServerUnknownMessage) { - TObjectCountCheck objectCountCheck; - - TExampleServer server; - TNetAddr serverAddr = server.GetActualListenAddr(); - - TExampleClient client; - - client.SendMessagesWaitReplies(2, serverAddr); - - TAutoPtr<TBusMessage> req(new TExampleRequest(&client.Proto.RequestCount)); - req->GetHeader()->Type = 11; - client.Session->SendMessageAutoPtr(req, &serverAddr); - client.MessageCount = 1; - - client.WaitForError(MESSAGE_DELIVERY_FAILED); - } - + TObjectCountCheck objectCountCheck; + + TExampleServer server; + TNetAddr serverAddr = server.GetActualListenAddr(); + + TExampleClient client; + + client.SendMessagesWaitReplies(2, serverAddr); + + TAutoPtr<TBusMessage> req(new TExampleRequest(&client.Proto.RequestCount)); + req->GetHeader()->Type = 11; + client.Session->SendMessageAutoPtr(req, &serverAddr); + client.MessageCount = 1; + + client.WaitForError(MESSAGE_DELIVERY_FAILED); + } + Y_UNIT_TEST(ServerMessageReservedIds) { TObjectCountCheck objectCountCheck; @@ -642,18 +642,18 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { } Y_UNIT_TEST(TestGetInFlightForDestination) { - TObjectCountCheck objectCountCheck; - - TDelayReplyServer server; - - TExampleClient client; - - TNetAddr addr("localhost", server.Session->GetActualListenPort()); - - UNIT_ASSERT_VALUES_EQUAL(size_t(0), client.Session->GetInFlight(addr)); - - client.SendMessages(2, &addr); - + TObjectCountCheck objectCountCheck; + + TDelayReplyServer server; + + TExampleClient client; + + TNetAddr addr("localhost", server.Session->GetActualListenPort()); + + UNIT_ASSERT_VALUES_EQUAL(size_t(0), client.Session->GetInFlight(addr)); + + client.SendMessages(2, &addr); + for (size_t i = 0; i < 5; ++i) { // One MessageReceivedEvent indicates one message, we need to wait for two UNIT_ASSERT(server.MessageReceivedEvent.WaitT(TDuration::Seconds(5))); @@ -662,98 +662,98 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { } } UNIT_ASSERT_VALUES_EQUAL(server.GetDelayedMessageCount(), 2); - - size_t inFlight = client.Session->GetInFlight(addr); - // 4 is for messagebus1 that adds inFlight counter twice for some reason - UNIT_ASSERT(inFlight == 2 || inFlight == 4); - + + size_t inFlight = client.Session->GetInFlight(addr); + // 4 is for messagebus1 that adds inFlight counter twice for some reason + UNIT_ASSERT(inFlight == 2 || inFlight == 4); + UNIT_ASSERT(server.CheckClientIsAlive()); - + server.ReplyToDelayedMessages(); - client.WaitReplies(); - } - + client.WaitReplies(); + } + struct TResetAfterSendOneWayErrorInCallbackClient: public TExampleClient { - TTestSync TestSync; - - static TBusClientSessionConfig SessionConfig() { - TBusClientSessionConfig config; - // 1 ms is not enough when test is running under valgrind - config.ConnectTimeout = 10; - config.SendTimeout = 10; - config.Secret.TimeoutPeriod = TDuration::MilliSeconds(1); - return config; - } - - TResetAfterSendOneWayErrorInCallbackClient() - : TExampleClient(SessionConfig()) - { - } - + TTestSync TestSync; + + static TBusClientSessionConfig SessionConfig() { + TBusClientSessionConfig config; + // 1 ms is not enough when test is running under valgrind + config.ConnectTimeout = 10; + config.SendTimeout = 10; + config.Secret.TimeoutPeriod = TDuration::MilliSeconds(1); + return config; + } + + TResetAfterSendOneWayErrorInCallbackClient() + : TExampleClient(SessionConfig()) + { + } + ~TResetAfterSendOneWayErrorInCallbackClient() override { - Session->Shutdown(); - } - + Session->Shutdown(); + } + void OnError(TAutoPtr<TBusMessage> mess, EMessageStatus status) override { - TestSync.WaitForAndIncrement(0); + TestSync.WaitForAndIncrement(0); Y_VERIFY(status == MESSAGE_CONNECT_FAILED || status == MESSAGE_TIMEOUT, "must be connection failed, got %s", ToString(status).data()); - mess.Destroy(); - TestSync.CheckAndIncrement(1); - } - }; - + mess.Destroy(); + TestSync.CheckAndIncrement(1); + } + }; + Y_UNIT_TEST(ResetAfterSendOneWayErrorInCallback) { - TObjectCountCheck objectCountCheck; - - TNetAddr noServerAddr("localhost", 17); - - TResetAfterSendOneWayErrorInCallbackClient client; - - EMessageStatus ok = client.Session->SendMessageOneWayMove(new TExampleRequest(&client.Proto.RequestCount), &noServerAddr); - UNIT_ASSERT_VALUES_EQUAL(MESSAGE_OK, ok); - - client.TestSync.WaitForAndIncrement(2); - } - + TObjectCountCheck objectCountCheck; + + TNetAddr noServerAddr("localhost", 17); + + TResetAfterSendOneWayErrorInCallbackClient client; + + EMessageStatus ok = client.Session->SendMessageOneWayMove(new TExampleRequest(&client.Proto.RequestCount), &noServerAddr); + UNIT_ASSERT_VALUES_EQUAL(MESSAGE_OK, ok); + + client.TestSync.WaitForAndIncrement(2); + } + struct TResetAfterSendMessageOneWayDuringShutdown: public TExampleClient { - TTestSync TestSync; - + TTestSync TestSync; + ~TResetAfterSendMessageOneWayDuringShutdown() override { - Session->Shutdown(); - } - + Session->Shutdown(); + } + void OnError(TAutoPtr<TBusMessage> message, EMessageStatus status) override { - TestSync.CheckAndIncrement(0); - + TestSync.CheckAndIncrement(0); + Y_VERIFY(status == MESSAGE_CONNECT_FAILED, "must be MESSAGE_CONNECT_FAILED, got %s", ToString(status).data()); - - // check reset is possible here - message->Reset(); - + + // check reset is possible here + message->Reset(); + // intentionally don't destroy the message // we will try to resend it Y_UNUSED(message.Release()); - TestSync.CheckAndIncrement(1); - } - }; - + TestSync.CheckAndIncrement(1); + } + }; + Y_UNIT_TEST(ResetAfterSendMessageOneWayDuringShutdown) { - TObjectCountCheck objectCountCheck; - - TNetAddr noServerAddr("localhost", 17); - - TResetAfterSendMessageOneWayDuringShutdown client; - + TObjectCountCheck objectCountCheck; + + TNetAddr noServerAddr("localhost", 17); + + TResetAfterSendMessageOneWayDuringShutdown client; + TExampleRequest* message = new TExampleRequest(&client.Proto.RequestCount); EMessageStatus ok = client.Session->SendMessageOneWay(message, &noServerAddr); - UNIT_ASSERT_VALUES_EQUAL(MESSAGE_OK, ok); - + UNIT_ASSERT_VALUES_EQUAL(MESSAGE_OK, ok); + client.TestSync.WaitForAndIncrement(2); - client.Session->Shutdown(); - + client.Session->Shutdown(); + ok = client.Session->SendMessageOneWay(message); Y_VERIFY(ok == MESSAGE_SHUTDOWN, "must be shutdown when sending during shutdown, got %s", ToString(ok).data()); @@ -762,148 +762,148 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { client.TestSync.CheckAndIncrement(3); delete message; - } - + } + Y_UNIT_TEST(ResetAfterSendOneWayErrorInReturn) { - TObjectCountCheck objectCountCheck; - + TObjectCountCheck objectCountCheck; + TestNoServerImpl(17, true); - } - + } + struct TResetAfterSendOneWaySuccessClient: public TExampleClient { - TTestSync TestSync; - + TTestSync TestSync; + ~TResetAfterSendOneWaySuccessClient() override { - Session->Shutdown(); - } - + Session->Shutdown(); + } + void OnMessageSentOneWay(TAutoPtr<TBusMessage> sent) override { - TestSync.WaitForAndIncrement(0); - sent->Reset(); - TestSync.CheckAndIncrement(1); - } - }; - + TestSync.WaitForAndIncrement(0); + sent->Reset(); + TestSync.CheckAndIncrement(1); + } + }; + Y_UNIT_TEST(ResetAfterSendOneWaySuccess) { - TObjectCountCheck objectCountCheck; - - TExampleServer server; - TNetAddr serverAddr = server.GetActualListenAddr(); - - TResetAfterSendOneWaySuccessClient client; - - EMessageStatus ok = client.Session->SendMessageOneWay(new TExampleRequest(&client.Proto.RequestCount), &serverAddr); - UNIT_ASSERT_VALUES_EQUAL(MESSAGE_OK, ok); - // otherwize message might go to OnError(MESSAGE_SHUTDOWN) - server.WaitForOnMessageCount(1); - - client.TestSync.WaitForAndIncrement(2); - } - + TObjectCountCheck objectCountCheck; + + TExampleServer server; + TNetAddr serverAddr = server.GetActualListenAddr(); + + TResetAfterSendOneWaySuccessClient client; + + EMessageStatus ok = client.Session->SendMessageOneWay(new TExampleRequest(&client.Proto.RequestCount), &serverAddr); + UNIT_ASSERT_VALUES_EQUAL(MESSAGE_OK, ok); + // otherwize message might go to OnError(MESSAGE_SHUTDOWN) + server.WaitForOnMessageCount(1); + + client.TestSync.WaitForAndIncrement(2); + } + Y_UNIT_TEST(GetStatus) { - TObjectCountCheck objectCountCheck; - - TExampleServer server; - - TExampleClient client; - // make sure connected - client.SendMessagesWaitReplies(3, server.GetActualListenAddr()); - - server.Bus->GetStatus(); - server.Bus->GetStatus(); - server.Bus->GetStatus(); - - client.Bus->GetStatus(); - client.Bus->GetStatus(); - client.Bus->GetStatus(); - } - + TObjectCountCheck objectCountCheck; + + TExampleServer server; + + TExampleClient client; + // make sure connected + client.SendMessagesWaitReplies(3, server.GetActualListenAddr()); + + server.Bus->GetStatus(); + server.Bus->GetStatus(); + server.Bus->GetStatus(); + + client.Bus->GetStatus(); + client.Bus->GetStatus(); + client.Bus->GetStatus(); + } + Y_UNIT_TEST(BindOnRandomPort) { - TObjectCountCheck objectCountCheck; - - TBusServerSessionConfig serverConfig; - TExampleServer server; - - TExampleClient client; - TNetAddr addr(TNetAddr("127.0.0.1", server.Session->GetActualListenPort())); - client.SendMessagesWaitReplies(3, &addr); - } - + TObjectCountCheck objectCountCheck; + + TBusServerSessionConfig serverConfig; + TExampleServer server; + + TExampleClient client; + TNetAddr addr(TNetAddr("127.0.0.1", server.Session->GetActualListenPort())); + client.SendMessagesWaitReplies(3, &addr); + } + Y_UNIT_TEST(UnbindOnShutdown) { - TBusMessageQueuePtr queue(CreateMessageQueue()); - - TExampleProtocol proto; - TBusServerHandlerError handler; - TBusServerSessionPtr session = TBusServerSession::Create( + TBusMessageQueuePtr queue(CreateMessageQueue()); + + TExampleProtocol proto; + TBusServerHandlerError handler; + TBusServerSessionPtr session = TBusServerSession::Create( &proto, &handler, TBusServerSessionConfig(), queue); - - unsigned port = session->GetActualListenPort(); - UNIT_ASSERT(port > 0); - - session->Shutdown(); - - // fails is Shutdown() didn't unbind - THangingServer hangingServer(port); - } - + + unsigned port = session->GetActualListenPort(); + UNIT_ASSERT(port > 0); + + session->Shutdown(); + + // fails is Shutdown() didn't unbind + THangingServer hangingServer(port); + } + Y_UNIT_TEST(VersionNegotiation) { - TObjectCountCheck objectCountCheck; - - TExampleServer server; - - TSockAddrInet addr(IpFromString("127.0.0.1"), server.Session->GetActualListenPort()); - - TInetStreamSocket socket; - int r1 = socket.Connect(&addr); - UNIT_ASSERT(r1 >= 0); - - TStreamSocketOutput output(&socket); - - TBusHeader request; - Zero(request); - request.Size = sizeof(request); - request.SetVersionInternal(0xF); // max - output.Write(&request, sizeof(request)); - + TObjectCountCheck objectCountCheck; + + TExampleServer server; + + TSockAddrInet addr(IpFromString("127.0.0.1"), server.Session->GetActualListenPort()); + + TInetStreamSocket socket; + int r1 = socket.Connect(&addr); + UNIT_ASSERT(r1 >= 0); + + TStreamSocketOutput output(&socket); + + TBusHeader request; + Zero(request); + request.Size = sizeof(request); + request.SetVersionInternal(0xF); // max + output.Write(&request, sizeof(request)); + UNIT_ASSERT_VALUES_EQUAL(IsVersionNegotiation(request), true); - TStreamSocketInput input(&socket); - - TBusHeader response; - size_t pos = 0; - - while (pos < sizeof(response)) { + TStreamSocketInput input(&socket); + + TBusHeader response; + size_t pos = 0; + + while (pos < sizeof(response)) { size_t count = input.Read(((char*)&response) + pos, sizeof(response) - pos); - pos += count; - } - - UNIT_ASSERT_VALUES_EQUAL(sizeof(response), pos); - - UNIT_ASSERT_VALUES_EQUAL(YBUS_VERSION, response.GetVersionInternal()); - } - + pos += count; + } + + UNIT_ASSERT_VALUES_EQUAL(sizeof(response), pos); + + UNIT_ASSERT_VALUES_EQUAL(YBUS_VERSION, response.GetVersionInternal()); + } + struct TOnConnectionEventClient: public TExampleClient { - TTestSync Sync; - + TTestSync Sync; + ~TOnConnectionEventClient() override { - Session->Shutdown(); - } - + Session->Shutdown(); + } + void OnClientConnectionEvent(const TClientConnectionEvent& event) override { - if (Sync.Get() > 2) { - // Test OnClientConnectionEvent_Disconnect is broken. - // Sometimes reconnect happens during server shutdown - // when acceptor connections is still alive, and - // server connection is already closed - return; - } - - if (event.GetType() == TClientConnectionEvent::CONNECTED) { - Sync.WaitForAndIncrement(0); - } else if (event.GetType() == TClientConnectionEvent::DISCONNECTED) { - Sync.WaitForAndIncrement(2); - } - } + if (Sync.Get() > 2) { + // Test OnClientConnectionEvent_Disconnect is broken. + // Sometimes reconnect happens during server shutdown + // when acceptor connections is still alive, and + // server connection is already closed + return; + } + + if (event.GetType() == TClientConnectionEvent::CONNECTED) { + Sync.WaitForAndIncrement(0); + } else if (event.GetType() == TClientConnectionEvent::DISCONNECTED) { + Sync.WaitForAndIncrement(2); + } + } void OnError(TAutoPtr<TBusMessage>, EMessageStatus) override { // We do not check for message errors in this test. @@ -911,8 +911,8 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { void OnMessageSentOneWay(TAutoPtr<TBusMessage>) override { } - }; - + }; + struct TOnConnectionEventServer: public TExampleServer { TOnConnectionEventServer() : TExampleServer("TOnConnectionEventServer") @@ -929,39 +929,39 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { }; Y_UNIT_TEST(OnClientConnectionEvent_Shutdown) { - TObjectCountCheck objectCountCheck; - + TObjectCountCheck objectCountCheck; + TOnConnectionEventServer server; - - TOnConnectionEventClient client; - - TNetAddr addr("127.0.0.1", server.Session->GetActualListenPort()); - + + TOnConnectionEventClient client; + + TNetAddr addr("127.0.0.1", server.Session->GetActualListenPort()); + client.Session->SendMessageOneWay(new TExampleRequest(&client.Proto.RequestCount), &addr); - - client.Sync.WaitForAndIncrement(1); - - client.Session->Shutdown(); - - client.Sync.WaitForAndIncrement(3); - } - + + client.Sync.WaitForAndIncrement(1); + + client.Session->Shutdown(); + + client.Sync.WaitForAndIncrement(3); + } + Y_UNIT_TEST(OnClientConnectionEvent_Disconnect) { - TObjectCountCheck objectCountCheck; - + TObjectCountCheck objectCountCheck; + THolder<TOnConnectionEventServer> server(new TOnConnectionEventServer); - - TOnConnectionEventClient client; - TNetAddr addr("127.0.0.1", server->Session->GetActualListenPort()); - + + TOnConnectionEventClient client; + TNetAddr addr("127.0.0.1", server->Session->GetActualListenPort()); + client.Session->SendMessageOneWay(new TExampleRequest(&client.Proto.RequestCount), &addr); - - client.Sync.WaitForAndIncrement(1); - - server.Destroy(); - - client.Sync.WaitForAndIncrement(3); - } + + client.Sync.WaitForAndIncrement(1); + + server.Destroy(); + + client.Sync.WaitForAndIncrement(3); + } struct TServerForQuotaWake: public TExampleServer { TSystemEvent GoOn; @@ -1042,7 +1042,7 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { start = now; // TODO: properly check that server is blocked - } else if (start + TDuration::MilliSeconds(100) < now) { + } else if (start + TDuration::MilliSeconds(100) < now) { break; } } diff --git a/library/cpp/messagebus/test/ut/module_client_one_way_ut.cpp b/library/cpp/messagebus/test/ut/module_client_one_way_ut.cpp index 9c1224ada9..4083cf3b7b 100644 --- a/library/cpp/messagebus/test/ut/module_client_one_way_ut.cpp +++ b/library/cpp/messagebus/test/ut/module_client_one_way_ut.cpp @@ -1,143 +1,143 @@ #include <library/cpp/testing/unittest/registar.h> - + #include <library/cpp/messagebus/test/helper/example.h> #include <library/cpp/messagebus/test/helper/message_handler_error.h> - + #include <library/cpp/messagebus/misc/test_sync.h> #include <library/cpp/messagebus/oldmodule/module.h> -using namespace NBus; -using namespace NBus::NTest; - +using namespace NBus; +using namespace NBus::NTest; + Y_UNIT_TEST_SUITE(ModuleClientOneWay) { - struct TTestServer: public TBusServerHandlerError { - TExampleProtocol Proto; - - TTestSync* const TestSync; - - TBusMessageQueuePtr Queue; - TBusServerSessionPtr ServerSession; - - TTestServer(TTestSync* testSync) - : TestSync(testSync) - { - Queue = CreateMessageQueue(); - ServerSession = TBusServerSession::Create(&Proto, this, TBusServerSessionConfig(), Queue); - } - + struct TTestServer: public TBusServerHandlerError { + TExampleProtocol Proto; + + TTestSync* const TestSync; + + TBusMessageQueuePtr Queue; + TBusServerSessionPtr ServerSession; + + TTestServer(TTestSync* testSync) + : TestSync(testSync) + { + Queue = CreateMessageQueue(); + ServerSession = TBusServerSession::Create(&Proto, this, TBusServerSessionConfig(), Queue); + } + void OnMessage(TOnMessageContext& context) override { - TestSync->WaitForAndIncrement(1); - context.ForgetRequest(); - } - }; - - struct TClientModule: public TBusModule { - TExampleProtocol Proto; - - TTestSync* const TestSync; - unsigned const Port; - - TBusClientSessionPtr ClientSession; - - TClientModule(TTestSync* testSync, unsigned port) - : TBusModule("m") - , TestSync(testSync) - , Port(port) + TestSync->WaitForAndIncrement(1); + context.ForgetRequest(); + } + }; + + struct TClientModule: public TBusModule { + TExampleProtocol Proto; + + TTestSync* const TestSync; + unsigned const Port; + + TBusClientSessionPtr ClientSession; + + TClientModule(TTestSync* testSync, unsigned port) + : TBusModule("m") + , TestSync(testSync) + , Port(port) { } - + TJobHandler Start(TBusJob* job, TBusMessage*) override { - TestSync->WaitForAndIncrement(0); - - job->SendOneWayTo(new TExampleRequest(&Proto.RequestCount), ClientSession.Get(), TNetAddr("localhost", Port)); - - return &TClientModule::Sent; - } - - TJobHandler Sent(TBusJob* job, TBusMessage*) { - TestSync->WaitForAndIncrement(2); - job->Cancel(MESSAGE_DONT_ASK); + TestSync->WaitForAndIncrement(0); + + job->SendOneWayTo(new TExampleRequest(&Proto.RequestCount), ClientSession.Get(), TNetAddr("localhost", Port)); + + return &TClientModule::Sent; + } + + TJobHandler Sent(TBusJob* job, TBusMessage*) { + TestSync->WaitForAndIncrement(2); + job->Cancel(MESSAGE_DONT_ASK); return nullptr; - } - + } + TBusServerSessionPtr CreateExtSession(TBusMessageQueue& queue) override { - ClientSession = CreateDefaultSource(queue, &Proto, TBusServerSessionConfig()); + ClientSession = CreateDefaultSource(queue, &Proto, TBusServerSessionConfig()); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(Simple) { - TTestSync testSync; - - TTestServer server(&testSync); - - TBusMessageQueuePtr queue = CreateMessageQueue(); - TClientModule clientModule(&testSync, server.ServerSession->GetActualListenPort()); - - clientModule.CreatePrivateSessions(queue.Get()); - clientModule.StartInput(); - - clientModule.StartJob(new TExampleRequest(&clientModule.Proto.StartCount)); - - testSync.WaitForAndIncrement(3); - - clientModule.Shutdown(); - } - - struct TSendErrorModule: public TBusModule { - TExampleProtocol Proto; - - TTestSync* const TestSync; - - TBusClientSessionPtr ClientSession; - - TSendErrorModule(TTestSync* testSync) - : TBusModule("m") - , TestSync(testSync) + TTestSync testSync; + + TTestServer server(&testSync); + + TBusMessageQueuePtr queue = CreateMessageQueue(); + TClientModule clientModule(&testSync, server.ServerSession->GetActualListenPort()); + + clientModule.CreatePrivateSessions(queue.Get()); + clientModule.StartInput(); + + clientModule.StartJob(new TExampleRequest(&clientModule.Proto.StartCount)); + + testSync.WaitForAndIncrement(3); + + clientModule.Shutdown(); + } + + struct TSendErrorModule: public TBusModule { + TExampleProtocol Proto; + + TTestSync* const TestSync; + + TBusClientSessionPtr ClientSession; + + TSendErrorModule(TTestSync* testSync) + : TBusModule("m") + , TestSync(testSync) { } - + TJobHandler Start(TBusJob* job, TBusMessage*) override { - TestSync->WaitForAndIncrement(0); - - job->SendOneWayTo(new TExampleRequest(&Proto.RequestCount), ClientSession.Get(), TNetAddr("localhost", 1)); - - return &TSendErrorModule::Sent; - } - - TJobHandler Sent(TBusJob* job, TBusMessage*) { - TestSync->WaitForAndIncrement(1); - job->Cancel(MESSAGE_DONT_ASK); + TestSync->WaitForAndIncrement(0); + + job->SendOneWayTo(new TExampleRequest(&Proto.RequestCount), ClientSession.Get(), TNetAddr("localhost", 1)); + + return &TSendErrorModule::Sent; + } + + TJobHandler Sent(TBusJob* job, TBusMessage*) { + TestSync->WaitForAndIncrement(1); + job->Cancel(MESSAGE_DONT_ASK); return nullptr; - } - + } + TBusServerSessionPtr CreateExtSession(TBusMessageQueue& queue) override { - TBusServerSessionConfig sessionConfig; - sessionConfig.ConnectTimeout = 1; - sessionConfig.SendTimeout = 1; - sessionConfig.TotalTimeout = 1; - sessionConfig.Secret.TimeoutPeriod = TDuration::MilliSeconds(1); - ClientSession = CreateDefaultSource(queue, &Proto, sessionConfig); + TBusServerSessionConfig sessionConfig; + sessionConfig.ConnectTimeout = 1; + sessionConfig.SendTimeout = 1; + sessionConfig.TotalTimeout = 1; + sessionConfig.Secret.TimeoutPeriod = TDuration::MilliSeconds(1); + ClientSession = CreateDefaultSource(queue, &Proto, sessionConfig); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(SendError) { - TTestSync testSync; - - TBusQueueConfig queueConfig; - queueConfig.NumWorkers = 5; - - TBusMessageQueuePtr queue = CreateMessageQueue(queueConfig); - TSendErrorModule clientModule(&testSync); - - clientModule.CreatePrivateSessions(queue.Get()); - clientModule.StartInput(); - - clientModule.StartJob(new TExampleRequest(&clientModule.Proto.StartCount)); - - testSync.WaitForAndIncrement(2); - - clientModule.Shutdown(); - } -} + TTestSync testSync; + + TBusQueueConfig queueConfig; + queueConfig.NumWorkers = 5; + + TBusMessageQueuePtr queue = CreateMessageQueue(queueConfig); + TSendErrorModule clientModule(&testSync); + + clientModule.CreatePrivateSessions(queue.Get()); + clientModule.StartInput(); + + clientModule.StartJob(new TExampleRequest(&clientModule.Proto.StartCount)); + + testSync.WaitForAndIncrement(2); + + clientModule.Shutdown(); + } +} diff --git a/library/cpp/messagebus/test/ut/module_client_ut.cpp b/library/cpp/messagebus/test/ut/module_client_ut.cpp index faffdbb625..ebfe185cc6 100644 --- a/library/cpp/messagebus/test/ut/module_client_ut.cpp +++ b/library/cpp/messagebus/test/ut/module_client_ut.cpp @@ -1,368 +1,368 @@ #include <library/cpp/testing/unittest/registar.h> - + #include "count_down_latch.h" -#include "moduletest.h" - +#include "moduletest.h" + #include <library/cpp/messagebus/test/helper/example.h> #include <library/cpp/messagebus/test/helper/example_module.h> #include <library/cpp/messagebus/test/helper/object_count_check.h> #include <library/cpp/messagebus/test/helper/wait_for.h> - + #include <library/cpp/messagebus/misc/test_sync.h> #include <library/cpp/messagebus/oldmodule/module.h> #include <util/generic/cast.h> #include <util/system/event.h> -using namespace NBus; -using namespace NBus::NTest; - -// helper class that cleans TBusJob instance, so job's destructor can -// be completed without assertion fail. -struct TJobGuard { +using namespace NBus; +using namespace NBus::NTest; + +// helper class that cleans TBusJob instance, so job's destructor can +// be completed without assertion fail. +struct TJobGuard { public: TJobGuard(NBus::TBusJob* job) : Job(job) { } - + ~TJobGuard() { Job->ClearAllMessageStates(); } - + private: NBus::TBusJob* Job; -}; - +}; + class TMessageOk: public NBus::TBusMessage { public: TMessageOk() : NBus::TBusMessage(1) { } -}; - +}; + class TMessageError: public NBus::TBusMessage { public: TMessageError() : NBus::TBusMessage(2) { } -}; - +}; + Y_UNIT_TEST_SUITE(BusJobTest) { -#if 0 +#if 0 Y_UNIT_TEST(TestPending) { - TObjectCountCheck objectCountCheck; - - TDupDetectModule module; - TBusJob job(&module, new TBusMessage(0)); - // Guard will clear the job if unit-assertion fails. - TJobGuard g(&job); - - NBus::TBusMessage* msg = new NBus::TBusMessage(1); - job.Send(msg, NULL); - NBus::TJobStateVec pending; - job.GetPending(&pending); - - UNIT_ASSERT_VALUES_EQUAL(pending.size(), 1u); - UNIT_ASSERT_EQUAL(msg, pending[0].Message); - } - + TObjectCountCheck objectCountCheck; + + TDupDetectModule module; + TBusJob job(&module, new TBusMessage(0)); + // Guard will clear the job if unit-assertion fails. + TJobGuard g(&job); + + NBus::TBusMessage* msg = new NBus::TBusMessage(1); + job.Send(msg, NULL); + NBus::TJobStateVec pending; + job.GetPending(&pending); + + UNIT_ASSERT_VALUES_EQUAL(pending.size(), 1u); + UNIT_ASSERT_EQUAL(msg, pending[0].Message); + } + Y_UNIT_TEST(TestCallReplyHandler) { - TObjectCountCheck objectCountCheck; - - TDupDetectModule module; - NBus::TBusJob job(&module, new NBus::TBusMessage(0)); - // Guard will clear the job if unit-assertion fails. - TJobGuard g(&job); - - NBus::TBusMessage* msgOk = new TMessageOk; - NBus::TBusMessage* msgError = new TMessageError; - job.Send(msgOk, NULL); - job.Send(msgError, NULL); - - UNIT_ASSERT_EQUAL(job.GetState<TMessageOk>(), NULL); - UNIT_ASSERT_EQUAL(job.GetState<TMessageError>(), NULL); - - NBus::TBusMessage* reply = new NBus::TBusMessage(0); - job.CallReplyHandler(NBus::MESSAGE_OK, msgOk, reply); - job.CallReplyHandler(NBus::MESSAGE_TIMEOUT, msgError, NULL); - - UNIT_ASSERT_UNEQUAL(job.GetState<TMessageOk>(), NULL); - UNIT_ASSERT_UNEQUAL(job.GetState<TMessageError>(), NULL); - - UNIT_ASSERT_VALUES_EQUAL(job.GetStatus<TMessageError>(), NBus::MESSAGE_TIMEOUT); - UNIT_ASSERT_EQUAL(job.GetState<TMessageError>()->Status, NBus::MESSAGE_TIMEOUT); - - UNIT_ASSERT_VALUES_EQUAL(job.GetStatus<TMessageOk>(), NBus::MESSAGE_OK); - UNIT_ASSERT_EQUAL(job.GetState<TMessageOk>()->Reply, reply); - } -#endif - - struct TParallelOnReplyModule : TExampleClientModule { - TNetAddr ServerAddr; - - TCountDownLatch RepliesLatch; - - TParallelOnReplyModule(const TNetAddr& serverAddr) - : ServerAddr(serverAddr) - , RepliesLatch(2) + TObjectCountCheck objectCountCheck; + + TDupDetectModule module; + NBus::TBusJob job(&module, new NBus::TBusMessage(0)); + // Guard will clear the job if unit-assertion fails. + TJobGuard g(&job); + + NBus::TBusMessage* msgOk = new TMessageOk; + NBus::TBusMessage* msgError = new TMessageError; + job.Send(msgOk, NULL); + job.Send(msgError, NULL); + + UNIT_ASSERT_EQUAL(job.GetState<TMessageOk>(), NULL); + UNIT_ASSERT_EQUAL(job.GetState<TMessageError>(), NULL); + + NBus::TBusMessage* reply = new NBus::TBusMessage(0); + job.CallReplyHandler(NBus::MESSAGE_OK, msgOk, reply); + job.CallReplyHandler(NBus::MESSAGE_TIMEOUT, msgError, NULL); + + UNIT_ASSERT_UNEQUAL(job.GetState<TMessageOk>(), NULL); + UNIT_ASSERT_UNEQUAL(job.GetState<TMessageError>(), NULL); + + UNIT_ASSERT_VALUES_EQUAL(job.GetStatus<TMessageError>(), NBus::MESSAGE_TIMEOUT); + UNIT_ASSERT_EQUAL(job.GetState<TMessageError>()->Status, NBus::MESSAGE_TIMEOUT); + + UNIT_ASSERT_VALUES_EQUAL(job.GetStatus<TMessageOk>(), NBus::MESSAGE_OK); + UNIT_ASSERT_EQUAL(job.GetState<TMessageOk>()->Reply, reply); + } +#endif + + struct TParallelOnReplyModule : TExampleClientModule { + TNetAddr ServerAddr; + + TCountDownLatch RepliesLatch; + + TParallelOnReplyModule(const TNetAddr& serverAddr) + : ServerAddr(serverAddr) + , RepliesLatch(2) { } - + TJobHandler Start(TBusJob* job, TBusMessage* mess) override { Y_UNUSED(mess); - job->Send(new TExampleRequest(&Proto.RequestCount), Source, TReplyHandler(&TParallelOnReplyModule::ReplyHandler), 0, ServerAddr); - return &TParallelOnReplyModule::HandleReplies; - } - - void ReplyHandler(TBusJob*, EMessageStatus status, TBusMessage* mess, TBusMessage* reply) { + job->Send(new TExampleRequest(&Proto.RequestCount), Source, TReplyHandler(&TParallelOnReplyModule::ReplyHandler), 0, ServerAddr); + return &TParallelOnReplyModule::HandleReplies; + } + + void ReplyHandler(TBusJob*, EMessageStatus status, TBusMessage* mess, TBusMessage* reply) { Y_UNUSED(mess); Y_UNUSED(reply); Y_VERIFY(status == MESSAGE_OK, "failed to get reply: %s", ToCString(status)); - } - - TJobHandler HandleReplies(TBusJob* job, TBusMessage* mess) { + } + + TJobHandler HandleReplies(TBusJob* job, TBusMessage* mess) { Y_UNUSED(mess); - RepliesLatch.CountDown(); + RepliesLatch.CountDown(); Y_VERIFY(RepliesLatch.Await(TDuration::Seconds(10)), "failed to get answers"); - job->Cancel(MESSAGE_UNKNOWN); + job->Cancel(MESSAGE_UNKNOWN); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(TestReplyHandlerCalledInParallel) { - TObjectCountCheck objectCountCheck; - - TExampleServer server; - - TExampleProtocol proto; - - TBusQueueConfig config; - config.NumWorkers = 5; - - TParallelOnReplyModule module(server.GetActualListenAddr()); - module.StartModule(); - - module.StartJob(new TExampleRequest(&proto.StartCount)); - module.StartJob(new TExampleRequest(&proto.StartCount)); - - UNIT_ASSERT(module.RepliesLatch.Await(TDuration::Seconds(10))); - - module.Shutdown(); - } - - struct TErrorHandlerCheckerModule : TExampleModule { - TNetAddr ServerAddr; - - TBusClientSessionPtr Source; - - TCountDownLatch GotReplyLatch; - - TBusMessage* SentMessage; - - TErrorHandlerCheckerModule() - : ServerAddr("localhost", 17) - , GotReplyLatch(2) - , SentMessage() + TObjectCountCheck objectCountCheck; + + TExampleServer server; + + TExampleProtocol proto; + + TBusQueueConfig config; + config.NumWorkers = 5; + + TParallelOnReplyModule module(server.GetActualListenAddr()); + module.StartModule(); + + module.StartJob(new TExampleRequest(&proto.StartCount)); + module.StartJob(new TExampleRequest(&proto.StartCount)); + + UNIT_ASSERT(module.RepliesLatch.Await(TDuration::Seconds(10))); + + module.Shutdown(); + } + + struct TErrorHandlerCheckerModule : TExampleModule { + TNetAddr ServerAddr; + + TBusClientSessionPtr Source; + + TCountDownLatch GotReplyLatch; + + TBusMessage* SentMessage; + + TErrorHandlerCheckerModule() + : ServerAddr("localhost", 17) + , GotReplyLatch(2) + , SentMessage() { } - + TJobHandler Start(TBusJob* job, TBusMessage* mess) override { Y_UNUSED(mess); - TExampleRequest* message = new TExampleRequest(&Proto.RequestCount); - job->Send(message, Source, TReplyHandler(&TErrorHandlerCheckerModule::ReplyHandler), 0, ServerAddr); - SentMessage = message; - return &TErrorHandlerCheckerModule::HandleReplies; - } - - void ReplyHandler(TBusJob*, EMessageStatus status, TBusMessage* req, TBusMessage* resp) { + TExampleRequest* message = new TExampleRequest(&Proto.RequestCount); + job->Send(message, Source, TReplyHandler(&TErrorHandlerCheckerModule::ReplyHandler), 0, ServerAddr); + SentMessage = message; + return &TErrorHandlerCheckerModule::HandleReplies; + } + + void ReplyHandler(TBusJob*, EMessageStatus status, TBusMessage* req, TBusMessage* resp) { Y_VERIFY(status == MESSAGE_CONNECT_FAILED || status == MESSAGE_TIMEOUT, "got wrong status: %s", ToString(status).data()); Y_VERIFY(req == SentMessage, "checking request"); Y_VERIFY(resp == nullptr, "checking response"); - GotReplyLatch.CountDown(); - } - - TJobHandler HandleReplies(TBusJob* job, TBusMessage* mess) { + GotReplyLatch.CountDown(); + } + + TJobHandler HandleReplies(TBusJob* job, TBusMessage* mess) { Y_UNUSED(mess); - job->Cancel(MESSAGE_UNKNOWN); - GotReplyLatch.CountDown(); + job->Cancel(MESSAGE_UNKNOWN); + GotReplyLatch.CountDown(); return nullptr; - } - + } + TBusServerSessionPtr CreateExtSession(TBusMessageQueue& queue) override { - TBusClientSessionConfig sessionConfig; - sessionConfig.SendTimeout = 1; // TODO: allow 0 - sessionConfig.Secret.TimeoutPeriod = TDuration::MilliSeconds(10); - Source = CreateDefaultSource(queue, &Proto, sessionConfig); - Source->RegisterService("localhost"); + TBusClientSessionConfig sessionConfig; + sessionConfig.SendTimeout = 1; // TODO: allow 0 + sessionConfig.Secret.TimeoutPeriod = TDuration::MilliSeconds(10); + Source = CreateDefaultSource(queue, &Proto, sessionConfig); + Source->RegisterService("localhost"); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(ErrorHandler) { - TExampleProtocol proto; - - TBusQueueConfig config; - config.NumWorkers = 5; - - TErrorHandlerCheckerModule module; - - TBusModuleConfig moduleConfig; - moduleConfig.Secret.SchedulePeriod = TDuration::MilliSeconds(10); - module.SetConfig(moduleConfig); - - module.StartModule(); - - module.StartJob(new TExampleRequest(&proto.StartCount)); - - module.GotReplyLatch.Await(); - - module.Shutdown(); - } - + TExampleProtocol proto; + + TBusQueueConfig config; + config.NumWorkers = 5; + + TErrorHandlerCheckerModule module; + + TBusModuleConfig moduleConfig; + moduleConfig.Secret.SchedulePeriod = TDuration::MilliSeconds(10); + module.SetConfig(moduleConfig); + + module.StartModule(); + + module.StartJob(new TExampleRequest(&proto.StartCount)); + + module.GotReplyLatch.Await(); + + module.Shutdown(); + } + struct TSlowReplyServer: public TBusServerHandlerError { - TTestSync* const TestSync; - TBusMessageQueuePtr Bus; - TBusServerSessionPtr ServerSession; - TExampleProtocol Proto; - - TAtomic OnMessageCount; - - TSlowReplyServer(TTestSync* testSync) - : TestSync(testSync) - , OnMessageCount(0) - { - Bus = CreateMessageQueue("TSlowReplyServer"); - TBusServerSessionConfig sessionConfig; - ServerSession = TBusServerSession::Create(&Proto, this, sessionConfig, Bus); - } - + TTestSync* const TestSync; + TBusMessageQueuePtr Bus; + TBusServerSessionPtr ServerSession; + TExampleProtocol Proto; + + TAtomic OnMessageCount; + + TSlowReplyServer(TTestSync* testSync) + : TestSync(testSync) + , OnMessageCount(0) + { + Bus = CreateMessageQueue("TSlowReplyServer"); + TBusServerSessionConfig sessionConfig; + ServerSession = TBusServerSession::Create(&Proto, this, sessionConfig, Bus); + } + void OnMessage(TOnMessageContext& req) override { - if (AtomicIncrement(OnMessageCount) == 1) { - TestSync->WaitForAndIncrement(0); - } - TAutoPtr<TBusMessage> response(new TExampleResponse(&Proto.ResponseCount)); - req.SendReplyMove(response); - } - }; - + if (AtomicIncrement(OnMessageCount) == 1) { + TestSync->WaitForAndIncrement(0); + } + TAutoPtr<TBusMessage> response(new TExampleResponse(&Proto.ResponseCount)); + req.SendReplyMove(response); + } + }; + struct TModuleThatSendsReplyEarly: public TExampleClientModule { - TTestSync* const TestSync; - const unsigned ServerPort; - - TBusServerSessionPtr ServerSession; - TAtomic ReplyCount; - - TModuleThatSendsReplyEarly(TTestSync* testSync, unsigned serverPort) - : TestSync(testSync) - , ServerPort(serverPort) + TTestSync* const TestSync; + const unsigned ServerPort; + + TBusServerSessionPtr ServerSession; + TAtomic ReplyCount; + + TModuleThatSendsReplyEarly(TTestSync* testSync, unsigned serverPort) + : TestSync(testSync) + , ServerPort(serverPort) , ServerSession(nullptr) - , ReplyCount(0) + , ReplyCount(0) { } - + TJobHandler Start(TBusJob* job, TBusMessage* mess) override { Y_UNUSED(mess); - for (unsigned i = 0; i < 2; ++i) { - job->Send( - new TExampleRequest(&Proto.RequestCount), - Source, - TReplyHandler(&TModuleThatSendsReplyEarly::ReplyHandler), - 0, - TNetAddr("127.0.0.1", ServerPort)); - } - return &TModuleThatSendsReplyEarly::HandleReplies; - } - - void ReplyHandler(TBusJob* job, EMessageStatus status, TBusMessage* mess, TBusMessage* reply) { + for (unsigned i = 0; i < 2; ++i) { + job->Send( + new TExampleRequest(&Proto.RequestCount), + Source, + TReplyHandler(&TModuleThatSendsReplyEarly::ReplyHandler), + 0, + TNetAddr("127.0.0.1", ServerPort)); + } + return &TModuleThatSendsReplyEarly::HandleReplies; + } + + void ReplyHandler(TBusJob* job, EMessageStatus status, TBusMessage* mess, TBusMessage* reply) { Y_UNUSED(mess); Y_UNUSED(reply); Y_VERIFY(status == MESSAGE_OK, "failed to get reply"); - if (AtomicIncrement(ReplyCount) == 1) { - TestSync->WaitForAndIncrement(1); - job->SendReply(new TExampleResponse(&Proto.ResponseCount)); - } else { - TestSync->WaitForAndIncrement(3); - } - } - - TJobHandler HandleReplies(TBusJob* job, TBusMessage* mess) { + if (AtomicIncrement(ReplyCount) == 1) { + TestSync->WaitForAndIncrement(1); + job->SendReply(new TExampleResponse(&Proto.ResponseCount)); + } else { + TestSync->WaitForAndIncrement(3); + } + } + + TJobHandler HandleReplies(TBusJob* job, TBusMessage* mess) { Y_UNUSED(mess); - job->Cancel(MESSAGE_UNKNOWN); + job->Cancel(MESSAGE_UNKNOWN); return nullptr; - } - + } + TBusServerSessionPtr CreateExtSession(TBusMessageQueue& queue) override { - TExampleClientModule::CreateExtSession(queue); - TBusServerSessionConfig sessionConfig; - return ServerSession = CreateDefaultDestination(queue, &Proto, sessionConfig); - } - }; - + TExampleClientModule::CreateExtSession(queue); + TBusServerSessionConfig sessionConfig; + return ServerSession = CreateDefaultDestination(queue, &Proto, sessionConfig); + } + }; + Y_UNIT_TEST(SendReplyCalledBeforeAllRepliesReceived) { - TTestSync testSync; - - TSlowReplyServer slowReplyServer(&testSync); - - TModuleThatSendsReplyEarly module(&testSync, slowReplyServer.ServerSession->GetActualListenPort()); - module.StartModule(); - - TExampleClient client; - TNetAddr addr("127.0.0.1", module.ServerSession->GetActualListenPort()); - client.SendMessagesWaitReplies(1, &addr); - - testSync.WaitForAndIncrement(2); - - module.Shutdown(); - } - + TTestSync testSync; + + TSlowReplyServer slowReplyServer(&testSync); + + TModuleThatSendsReplyEarly module(&testSync, slowReplyServer.ServerSession->GetActualListenPort()); + module.StartModule(); + + TExampleClient client; + TNetAddr addr("127.0.0.1", module.ServerSession->GetActualListenPort()); + client.SendMessagesWaitReplies(1, &addr); + + testSync.WaitForAndIncrement(2); + + module.Shutdown(); + } + struct TShutdownCalledBeforeReplyReceivedModule: public TExampleClientModule { - unsigned ServerPort; - - TTestSync TestSync; - - TShutdownCalledBeforeReplyReceivedModule(unsigned serverPort) - : ServerPort(serverPort) + unsigned ServerPort; + + TTestSync TestSync; + + TShutdownCalledBeforeReplyReceivedModule(unsigned serverPort) + : ServerPort(serverPort) { } - + TJobHandler Start(TBusJob* job, TBusMessage*) override { - TestSync.CheckAndIncrement(0); - - job->Send(new TExampleRequest(&Proto.RequestCount), Source, + TestSync.CheckAndIncrement(0); + + job->Send(new TExampleRequest(&Proto.RequestCount), Source, TReplyHandler(&TShutdownCalledBeforeReplyReceivedModule::HandleReply), 0, TNetAddr("localhost", ServerPort)); - return &TShutdownCalledBeforeReplyReceivedModule::End; - } - - void HandleReply(TBusJob*, EMessageStatus status, TBusMessage*, TBusMessage*) { + return &TShutdownCalledBeforeReplyReceivedModule::End; + } + + void HandleReply(TBusJob*, EMessageStatus status, TBusMessage*, TBusMessage*) { Y_VERIFY(status == MESSAGE_SHUTDOWN, "got %s", ToCString(status)); - TestSync.CheckAndIncrement(1); - } - - TJobHandler End(TBusJob* job, TBusMessage*) { - TestSync.CheckAndIncrement(2); - job->Cancel(MESSAGE_SHUTDOWN); + TestSync.CheckAndIncrement(1); + } + + TJobHandler End(TBusJob* job, TBusMessage*) { + TestSync.CheckAndIncrement(2); + job->Cancel(MESSAGE_SHUTDOWN); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(ShutdownCalledBeforeReplyReceived) { - TExampleServer server; - server.ForgetRequest = true; - - TShutdownCalledBeforeReplyReceivedModule module(server.GetActualListenPort()); - - module.StartModule(); - - module.StartJob(new TExampleRequest(&module.Proto.RequestCount)); - - server.TestSync.WaitFor(1); - - module.Shutdown(); - - module.TestSync.CheckAndIncrement(3); - } -} + TExampleServer server; + server.ForgetRequest = true; + + TShutdownCalledBeforeReplyReceivedModule module(server.GetActualListenPort()); + + module.StartModule(); + + module.StartJob(new TExampleRequest(&module.Proto.RequestCount)); + + server.TestSync.WaitFor(1); + + module.Shutdown(); + + module.TestSync.CheckAndIncrement(3); + } +} diff --git a/library/cpp/messagebus/test/ut/module_server_ut.cpp b/library/cpp/messagebus/test/ut/module_server_ut.cpp index 38f3fcc4ed..88fe1dd9b6 100644 --- a/library/cpp/messagebus/test/ut/module_server_ut.cpp +++ b/library/cpp/messagebus/test/ut/module_server_ut.cpp @@ -1,8 +1,8 @@ #include <library/cpp/testing/unittest/registar.h> - + #include "count_down_latch.h" -#include "moduletest.h" - +#include "moduletest.h" + #include <library/cpp/messagebus/test/helper/example.h> #include <library/cpp/messagebus/test/helper/example_module.h> #include <library/cpp/messagebus/test/helper/object_count_check.h> @@ -12,108 +12,108 @@ #include <util/generic/cast.h> -using namespace NBus; -using namespace NBus::NTest; - +using namespace NBus; +using namespace NBus::NTest; + Y_UNIT_TEST_SUITE(ModuleServerTests) { Y_UNIT_TEST(TestModule) { - TObjectCountCheck objectCountCheck; - - /// create or get instance of message queue, need one per application - TBusMessageQueuePtr bus(CreateMessageQueue()); + TObjectCountCheck objectCountCheck; + + /// create or get instance of message queue, need one per application + TBusMessageQueuePtr bus(CreateMessageQueue()); THostInfoHandler hostHandler(bus.Get()); - TDupDetectModule module(hostHandler.GetActualListenAddr()); - bool success; - success = module.Init(bus.Get()); - UNIT_ASSERT_C(success, "failed to initialize dupdetect module"); - - success = module.StartInput(); - UNIT_ASSERT_C(success, "failed to start dupdetect module"); - - TDupDetectHandler dupHandler(module.ListenAddr, bus.Get()); - dupHandler.Work(); - - UNIT_WAIT_FOR(dupHandler.NumMessages == dupHandler.NumReplies); - - module.Shutdown(); - dupHandler.DupDetect->Shutdown(); - } - + TDupDetectModule module(hostHandler.GetActualListenAddr()); + bool success; + success = module.Init(bus.Get()); + UNIT_ASSERT_C(success, "failed to initialize dupdetect module"); + + success = module.StartInput(); + UNIT_ASSERT_C(success, "failed to start dupdetect module"); + + TDupDetectHandler dupHandler(module.ListenAddr, bus.Get()); + dupHandler.Work(); + + UNIT_WAIT_FOR(dupHandler.NumMessages == dupHandler.NumReplies); + + module.Shutdown(); + dupHandler.DupDetect->Shutdown(); + } + struct TParallelOnMessageModule: public TExampleServerModule { - TCountDownLatch WaitTwoRequestsLatch; - - TParallelOnMessageModule() - : WaitTwoRequestsLatch(2) + TCountDownLatch WaitTwoRequestsLatch; + + TParallelOnMessageModule() + : WaitTwoRequestsLatch(2) { } - + TJobHandler Start(TBusJob* job, TBusMessage* mess) override { - WaitTwoRequestsLatch.CountDown(); + WaitTwoRequestsLatch.CountDown(); Y_VERIFY(WaitTwoRequestsLatch.Await(TDuration::Seconds(5)), "oops"); - - VerifyDynamicCast<TExampleRequest*>(mess); - - job->SendReply(new TExampleResponse(&Proto.ResponseCount)); + + VerifyDynamicCast<TExampleRequest*>(mess); + + job->SendReply(new TExampleResponse(&Proto.ResponseCount)); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(TestOnMessageHandlerCalledInParallel) { - TObjectCountCheck objectCountCheck; - - TBusQueueConfig config; - config.NumWorkers = 5; - - TParallelOnMessageModule module; - module.StartModule(); - - TExampleClient client; - - client.SendMessagesWaitReplies(2, module.ServerAddr); - - module.Shutdown(); - } - - struct TDelayReplyServer: public TExampleServerModule { + TObjectCountCheck objectCountCheck; + + TBusQueueConfig config; + config.NumWorkers = 5; + + TParallelOnMessageModule module; + module.StartModule(); + + TExampleClient client; + + client.SendMessagesWaitReplies(2, module.ServerAddr); + + module.Shutdown(); + } + + struct TDelayReplyServer: public TExampleServerModule { TSystemEvent MessageReceivedEvent; TSystemEvent ClientDiedEvent; - + TJobHandler Start(TBusJob* job, TBusMessage* mess) override { Y_UNUSED(mess); - - MessageReceivedEvent.Signal(); - + + MessageReceivedEvent.Signal(); + Y_VERIFY(ClientDiedEvent.WaitT(TDuration::Seconds(5)), "oops"); - - job->SendReply(new TExampleResponse(&Proto.ResponseCount)); + + job->SendReply(new TExampleResponse(&Proto.ResponseCount)); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(TestReplyCalledAfterClientDisconnected) { - TObjectCountCheck objectCountCheck; - - TBusQueueConfig config; - config.NumWorkers = 5; - - TDelayReplyServer server; - server.StartModule(); - - THolder<TExampleClient> client(new TExampleClient); - - client->SendMessages(1, server.ServerAddr); - - UNIT_ASSERT(server.MessageReceivedEvent.WaitT(TDuration::Seconds(5))); - - UNIT_ASSERT_VALUES_EQUAL(1, server.GetModuleSessionInFlight()); - - client.Destroy(); - - server.ClientDiedEvent.Signal(); - - // wait until all server message are delivered - UNIT_WAIT_FOR(0 == server.GetModuleSessionInFlight()); - - server.Shutdown(); - } -} + TObjectCountCheck objectCountCheck; + + TBusQueueConfig config; + config.NumWorkers = 5; + + TDelayReplyServer server; + server.StartModule(); + + THolder<TExampleClient> client(new TExampleClient); + + client->SendMessages(1, server.ServerAddr); + + UNIT_ASSERT(server.MessageReceivedEvent.WaitT(TDuration::Seconds(5))); + + UNIT_ASSERT_VALUES_EQUAL(1, server.GetModuleSessionInFlight()); + + client.Destroy(); + + server.ClientDiedEvent.Signal(); + + // wait until all server message are delivered + UNIT_WAIT_FOR(0 == server.GetModuleSessionInFlight()); + + server.Shutdown(); + } +} diff --git a/library/cpp/messagebus/test/ut/moduletest.h b/library/cpp/messagebus/test/ut/moduletest.h index 0f9834d9ff..d5da72c0cb 100644 --- a/library/cpp/messagebus/test/ut/moduletest.h +++ b/library/cpp/messagebus/test/ut/moduletest.h @@ -7,10 +7,10 @@ #include <library/cpp/messagebus/test/helper/alloc_counter.h> #include <library/cpp/messagebus/test/helper/example.h> #include <library/cpp/messagebus/test/helper/message_handler_error.h> - + #include <library/cpp/messagebus/ybus.h> #include <library/cpp/messagebus/oldmodule/module.h> - + namespace NBus { namespace NTest { using namespace std; @@ -71,7 +71,7 @@ namespace NBus { /// deserialized TBusData into new instance of the message TAutoPtr<TBusMessage> Deserialize(ui16 messageType, TArrayRef<const char> payload) override { Y_UNUSED(payload); - + if (messageType == TYPE_HOSTINFOREQUEST) { return new THostInfoMessage(MESSAGE_CREATE_UNINITIALIZED); } else if (messageType == TYPE_HOSTINFORESPONSE) { @@ -100,7 +100,7 @@ namespace NBus { mess.SendReplyMove(reply); } - + TNetAddr GetActualListenAddr() { return TNetAddr("localhost", Session->GetActualListenPort()); } @@ -110,7 +110,7 @@ namespace NBus { /// \brief DupDetect handler (should convert it to module too) struct TDupDetectHandler: public TBusClientHandlerError { TNetAddr ServerAddr; - + TBusClientSessionPtr DupDetect; TBusClientSessionConfig DupDetectConfig; TExampleProtocol DupDetectProto; @@ -147,7 +147,7 @@ namespace NBus { struct TDupDetectModule: public TBusModule { TNetAddr HostInfoAddr; - + TBusClientSessionPtr HostInfoClientSession; TBusClientSessionConfig HostInfoConfig; THostInfoProtocol HostInfoProto; @@ -162,7 +162,7 @@ namespace NBus { , HostInfoAddr(hostInfoAddr) { } - + bool Init(TBusMessageQueue* queue) { HostInfoClientSession = CreateDefaultSource(*queue, &HostInfoProto, HostInfoConfig); HostInfoClientSession->RegisterService("localhost"); @@ -174,7 +174,7 @@ namespace NBus { TBusServerSessionPtr session = CreateDefaultDestination(queue, &DupDetectProto, DupDetectConfig); ListenAddr = TNetAddr("localhost", session->GetActualListenPort()); - + return session; } diff --git a/library/cpp/messagebus/test/ut/one_way_ut.cpp b/library/cpp/messagebus/test/ut/one_way_ut.cpp index 7a907cc620..9c21227e2b 100644 --- a/library/cpp/messagebus/test/ut/one_way_ut.cpp +++ b/library/cpp/messagebus/test/ut/one_way_ut.cpp @@ -32,33 +32,33 @@ #include <library/cpp/messagebus/test/helper/wait_for.h> #include <library/cpp/messagebus/ybus.h> - + using namespace std; -using namespace NBus; -using namespace NBus::NPrivate; -using namespace NBus::NTest; +using namespace NBus; +using namespace NBus::NPrivate; +using namespace NBus::NTest; //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// /// \brief Reply-less client and handler struct NullClient : TBusClientHandlerError { - TNetAddr ServerAddr; - - TBusMessageQueuePtr Queue; - TBusClientSessionPtr Session; - TExampleProtocol Proto; + TNetAddr ServerAddr; + + TBusMessageQueuePtr Queue; + TBusClientSessionPtr Session; + TExampleProtocol Proto; /// constructor creates instances of protocol and session - NullClient(const TNetAddr& serverAddr, const TBusClientSessionConfig& sessionConfig = TBusClientSessionConfig()) - : ServerAddr(serverAddr) - { - UNIT_ASSERT(serverAddr.GetPort() > 0); + NullClient(const TNetAddr& serverAddr, const TBusClientSessionConfig& sessionConfig = TBusClientSessionConfig()) + : ServerAddr(serverAddr) + { + UNIT_ASSERT(serverAddr.GetPort() > 0); /// create or get instance of message queue, need one per application Queue = CreateMessageQueue(); /// register source/client session - Session = TBusClientSession::Create(&Proto, this, sessionConfig, Queue); + Session = TBusClientSession::Create(&Proto, this, sessionConfig, Queue); /// register service, announce to clients via LocatorService Session->RegisterService("localhost"); @@ -74,8 +74,8 @@ struct NullClient : TBusClientHandlerError { for (int i = 0; i < batch; i++) { TExampleRequest* mess = new TExampleRequest(&Proto.RequestCount); - mess->Data = "TADA"; - Session->SendMessageOneWay(mess, &ServerAddr); + mess->Data = "TADA"; + Session->SendMessageOneWay(mess, &ServerAddr); } } @@ -85,12 +85,12 @@ struct NullClient : TBusClientHandlerError { ///////////////////////////////////////////////////////////////////// /// \brief Reply-less server and handler -class NullServer: public TBusServerHandlerError { +class NullServer: public TBusServerHandlerError { public: /// session object to maintian - TBusMessageQueuePtr Queue; - TBusServerSessionPtr Session; - TExampleProtocol Proto; + TBusMessageQueuePtr Queue; + TBusServerSessionPtr Session; + TExampleProtocol Proto; public: TAtomic NumMessages; @@ -102,8 +102,8 @@ public: Queue = CreateMessageQueue(); /// register destination session - TBusServerSessionConfig sessionConfig; - Session = TBusServerSession::Create(&Proto, this, sessionConfig, Queue); + TBusServerSessionConfig sessionConfig; + Session = TBusServerSession::Create(&Proto, this, sessionConfig, Queue); } ~NullServer() override { @@ -117,7 +117,7 @@ public: Y_ASSERT(fmess->Data == "TADA"); /// tell session to forget this message and never expect any reply - mess.ForgetRequest(); + mess.ForgetRequest(); AtomicIncrement(NumMessages); } @@ -131,125 +131,125 @@ public: Y_UNIT_TEST_SUITE(TMessageBusTests_OneWay) { Y_UNIT_TEST(Simple) { - TObjectCountCheck objectCountCheck; - - NullServer server; - NullClient client(TNetAddr("localhost", server.Session->GetActualListenPort())); - - client.Work(); - - // wait until all client message are delivered + TObjectCountCheck objectCountCheck; + + NullServer server; + NullClient client(TNetAddr("localhost", server.Session->GetActualListenPort())); + + client.Work(); + + // wait until all client message are delivered UNIT_WAIT_FOR(AtomicGet(server.NumMessages) == 10); - - // assert correct number of messages + + // assert correct number of messages UNIT_ASSERT_VALUES_EQUAL(AtomicGet(server.NumMessages), 10); - UNIT_ASSERT_VALUES_EQUAL(server.Session->GetInFlight(), 0); - UNIT_ASSERT_VALUES_EQUAL(client.Session->GetInFlight(), 0); - } - - struct TMessageTooLargeClient: public NullClient { + UNIT_ASSERT_VALUES_EQUAL(server.Session->GetInFlight(), 0); + UNIT_ASSERT_VALUES_EQUAL(client.Session->GetInFlight(), 0); + } + + struct TMessageTooLargeClient: public NullClient { TSystemEvent GotTooLarge; - - TBusClientSessionConfig Config() { - TBusClientSessionConfig r; - r.MaxMessageSize = 1; - return r; - } - - TMessageTooLargeClient(unsigned port) - : NullClient(TNetAddr("localhost", port), Config()) + + TBusClientSessionConfig Config() { + TBusClientSessionConfig r; + r.MaxMessageSize = 1; + return r; + } + + TMessageTooLargeClient(unsigned port) + : NullClient(TNetAddr("localhost", port), Config()) { } - + ~TMessageTooLargeClient() override { - Session->Shutdown(); - } - + Session->Shutdown(); + } + void OnError(TAutoPtr<TBusMessage> mess, EMessageStatus status) override { Y_UNUSED(mess); - + Y_VERIFY(status == MESSAGE_MESSAGE_TOO_LARGE, "wrong status: %s", ToCString(status)); - - GotTooLarge.Signal(); - } - }; - + + GotTooLarge.Signal(); + } + }; + Y_UNIT_TEST(MessageTooLargeOnClient) { - TObjectCountCheck objectCountCheck; - - NullServer server; - - TMessageTooLargeClient client(server.Session->GetActualListenPort()); - - EMessageStatus ok = client.Session->SendMessageOneWayMove(new TExampleRequest(&client.Proto.RequestCount), &client.ServerAddr); - UNIT_ASSERT_VALUES_EQUAL(MESSAGE_OK, ok); - - client.GotTooLarge.WaitI(); - } - + TObjectCountCheck objectCountCheck; + + NullServer server; + + TMessageTooLargeClient client(server.Session->GetActualListenPort()); + + EMessageStatus ok = client.Session->SendMessageOneWayMove(new TExampleRequest(&client.Proto.RequestCount), &client.ServerAddr); + UNIT_ASSERT_VALUES_EQUAL(MESSAGE_OK, ok); + + client.GotTooLarge.WaitI(); + } + struct TCheckTimeoutClient: public NullClient { ~TCheckTimeoutClient() override { - Session->Shutdown(); - } - - static TBusClientSessionConfig SessionConfig() { - TBusClientSessionConfig sessionConfig; - sessionConfig.SendTimeout = 1; - sessionConfig.ConnectTimeout = 1; + Session->Shutdown(); + } + + static TBusClientSessionConfig SessionConfig() { + TBusClientSessionConfig sessionConfig; + sessionConfig.SendTimeout = 1; + sessionConfig.ConnectTimeout = 1; sessionConfig.Secret.TimeoutPeriod = TDuration::MilliSeconds(10); - return sessionConfig; - } - + return sessionConfig; + } + TCheckTimeoutClient(const TNetAddr& serverAddr) : NullClient(serverAddr, SessionConfig()) { } - + TSystemEvent GotError; - - /// message that could not be delivered + + /// message that could not be delivered void OnError(TAutoPtr<TBusMessage> mess, EMessageStatus status) override { Y_UNUSED(mess); Y_UNUSED(status); // TODO: check status - - GotError.Signal(); - } - }; - + + GotError.Signal(); + } + }; + Y_UNIT_TEST(SendTimeout_Callback_NoServer) { - TObjectCountCheck objectCountCheck; - - TCheckTimeoutClient client(TNetAddr("localhost", 17)); - - EMessageStatus ok = client.Session->SendMessageOneWay(new TExampleRequest(&client.Proto.RequestCount), &client.ServerAddr); - UNIT_ASSERT_EQUAL(ok, MESSAGE_OK); - - client.GotError.WaitI(); - } - + TObjectCountCheck objectCountCheck; + + TCheckTimeoutClient client(TNetAddr("localhost", 17)); + + EMessageStatus ok = client.Session->SendMessageOneWay(new TExampleRequest(&client.Proto.RequestCount), &client.ServerAddr); + UNIT_ASSERT_EQUAL(ok, MESSAGE_OK); + + client.GotError.WaitI(); + } + Y_UNIT_TEST(SendTimeout_Callback_HangingServer) { - THangingServer server; - - TObjectCountCheck objectCountCheck; - - TCheckTimeoutClient client(TNetAddr("localhost", server.GetPort())); - - bool first = true; - for (;;) { - EMessageStatus ok = client.Session->SendMessageOneWayMove(new TExampleRequest(&client.Proto.RequestCount), &client.ServerAddr); - if (ok == MESSAGE_BUSY) { - UNIT_ASSERT(!first); - break; - } - UNIT_ASSERT_VALUES_EQUAL(ok, MESSAGE_OK); - first = false; - } - + THangingServer server; + + TObjectCountCheck objectCountCheck; + + TCheckTimeoutClient client(TNetAddr("localhost", server.GetPort())); + + bool first = true; + for (;;) { + EMessageStatus ok = client.Session->SendMessageOneWayMove(new TExampleRequest(&client.Proto.RequestCount), &client.ServerAddr); + if (ok == MESSAGE_BUSY) { + UNIT_ASSERT(!first); + break; + } + UNIT_ASSERT_VALUES_EQUAL(ok, MESSAGE_OK); + first = false; + } + // BUGBUG: The test is buggy: the client might not get any error when sending one-way messages. // All the messages that the client has sent before he gets first MESSAGE_BUSY error might get // serailized and written to the socket buffer, so the write queue gets drained and there are // no messages to timeout when periodic timeout check happens. - client.GotError.WaitI(); - } -} + client.GotError.WaitI(); + } +} diff --git a/library/cpp/messagebus/test/ut/starter_ut.cpp b/library/cpp/messagebus/test/ut/starter_ut.cpp index ebb628ab28..dd4d3aaa5e 100644 --- a/library/cpp/messagebus/test/ut/starter_ut.cpp +++ b/library/cpp/messagebus/test/ut/starter_ut.cpp @@ -1,140 +1,140 @@ #include <library/cpp/testing/unittest/registar.h> - + #include <library/cpp/messagebus/test/helper/example_module.h> #include <library/cpp/messagebus/test/helper/object_count_check.h> #include <library/cpp/messagebus/test/helper/wait_for.h> - -using namespace NBus; -using namespace NBus::NTest; - + +using namespace NBus; +using namespace NBus::NTest; + Y_UNIT_TEST_SUITE(TBusStarterTest) { struct TStartJobTestModule: public TExampleModule { - using TBusModule::CreateDefaultStarter; - - TAtomic StartCount; - - TStartJobTestModule() - : StartCount(0) - { - } - + using TBusModule::CreateDefaultStarter; + + TAtomic StartCount; + + TStartJobTestModule() + : StartCount(0) + { + } + TJobHandler Start(TBusJob* job, TBusMessage* mess) override { Y_UNUSED(mess); - AtomicIncrement(StartCount); - job->Sleep(10); - return &TStartJobTestModule::End; - } - - TJobHandler End(TBusJob* job, TBusMessage* mess) { + AtomicIncrement(StartCount); + job->Sleep(10); + return &TStartJobTestModule::End; + } + + TJobHandler End(TBusJob* job, TBusMessage* mess) { Y_UNUSED(mess); - AtomicIncrement(StartCount); - job->Cancel(MESSAGE_UNKNOWN); + AtomicIncrement(StartCount); + job->Cancel(MESSAGE_UNKNOWN); return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(Test) { - TObjectCountCheck objectCountCheck; - - TBusMessageQueuePtr bus(CreateMessageQueue()); - - TStartJobTestModule module; - - //module.StartModule(); - module.CreatePrivateSessions(bus.Get()); - module.StartInput(); - - TBusSessionConfig config; - config.SendTimeout = 10; - - module.CreateDefaultStarter(*bus, config); - - UNIT_WAIT_FOR(AtomicGet(module.StartCount) >= 3); - - module.Shutdown(); - bus->Stop(); - } - + TObjectCountCheck objectCountCheck; + + TBusMessageQueuePtr bus(CreateMessageQueue()); + + TStartJobTestModule module; + + //module.StartModule(); + module.CreatePrivateSessions(bus.Get()); + module.StartInput(); + + TBusSessionConfig config; + config.SendTimeout = 10; + + module.CreateDefaultStarter(*bus, config); + + UNIT_WAIT_FOR(AtomicGet(module.StartCount) >= 3); + + module.Shutdown(); + bus->Stop(); + } + Y_UNIT_TEST(TestModuleStartJob) { - TObjectCountCheck objectCountCheck; - - TExampleProtocol proto; - - TStartJobTestModule module; - - TBusModuleConfig moduleConfig; - moduleConfig.Secret.SchedulePeriod = TDuration::MilliSeconds(10); - module.SetConfig(moduleConfig); - - module.StartModule(); - - module.StartJob(new TExampleRequest(&proto.RequestCount)); - - UNIT_WAIT_FOR(AtomicGet(module.StartCount) != 2); - - module.Shutdown(); - } - + TObjectCountCheck objectCountCheck; + + TExampleProtocol proto; + + TStartJobTestModule module; + + TBusModuleConfig moduleConfig; + moduleConfig.Secret.SchedulePeriod = TDuration::MilliSeconds(10); + module.SetConfig(moduleConfig); + + module.StartModule(); + + module.StartJob(new TExampleRequest(&proto.RequestCount)); + + UNIT_WAIT_FOR(AtomicGet(module.StartCount) != 2); + + module.Shutdown(); + } + struct TSleepModule: public TExampleServerModule { TSystemEvent MessageReceivedEvent; - + TJobHandler Start(TBusJob* job, TBusMessage* mess) override { Y_UNUSED(mess); - - MessageReceivedEvent.Signal(); - - job->Sleep(1000000000); - - return TJobHandler(&TSleepModule::Never); - } - - TJobHandler Never(TBusJob*, TBusMessage*) { + + MessageReceivedEvent.Signal(); + + job->Sleep(1000000000); + + return TJobHandler(&TSleepModule::Never); + } + + TJobHandler Never(TBusJob*, TBusMessage*) { Y_FAIL("happens"); - throw 1; - } - }; - + throw 1; + } + }; + Y_UNIT_TEST(StartJobDestroyDuringSleep) { - TObjectCountCheck objectCountCheck; - - TExampleProtocol proto; - - TSleepModule module; - - module.StartModule(); - - module.StartJob(new TExampleRequest(&proto.StartCount)); - - module.MessageReceivedEvent.WaitI(); - - module.Shutdown(); - } - + TObjectCountCheck objectCountCheck; + + TExampleProtocol proto; + + TSleepModule module; + + module.StartModule(); + + module.StartJob(new TExampleRequest(&proto.StartCount)); + + module.MessageReceivedEvent.WaitI(); + + module.Shutdown(); + } + struct TSendReplyModule: public TExampleServerModule { TSystemEvent MessageReceivedEvent; - + TJobHandler Start(TBusJob* job, TBusMessage* mess) override { Y_UNUSED(mess); - - job->SendReply(new TExampleResponse(&Proto.ResponseCount)); - - MessageReceivedEvent.Signal(); - + + job->SendReply(new TExampleResponse(&Proto.ResponseCount)); + + MessageReceivedEvent.Signal(); + return nullptr; - } - }; - + } + }; + Y_UNIT_TEST(AllowSendReplyInStarted) { - TObjectCountCheck objectCountCheck; - - TExampleProtocol proto; - - TSendReplyModule module; - module.StartModule(); - module.StartJob(new TExampleRequest(&proto.StartCount)); - - module.MessageReceivedEvent.WaitI(); - - module.Shutdown(); - } -} + TObjectCountCheck objectCountCheck; + + TExampleProtocol proto; + + TSendReplyModule module; + module.StartModule(); + module.StartJob(new TExampleRequest(&proto.StartCount)); + + module.MessageReceivedEvent.WaitI(); + + module.Shutdown(); + } +} diff --git a/library/cpp/messagebus/test/ut/sync_client_ut.cpp b/library/cpp/messagebus/test/ut/sync_client_ut.cpp index 848a9d3457..400128193f 100644 --- a/library/cpp/messagebus/test/ut/sync_client_ut.cpp +++ b/library/cpp/messagebus/test/ut/sync_client_ut.cpp @@ -4,7 +4,7 @@ namespace NBus { namespace NTest { using namespace std; - + //////////////////////////////////////////////////////////////////// /// \brief Client for sending synchronous message to local server struct TSyncClient { @@ -13,7 +13,7 @@ namespace NBus { TExampleProtocol Proto; TBusMessageQueuePtr Bus; TBusSyncClientSessionPtr Session; - + int NumReplies; int NumMessages; @@ -53,7 +53,7 @@ namespace NBus { Y_UNIT_TEST_SUITE(SyncClientTest) { Y_UNIT_TEST(TestSync) { TObjectCountCheck objectCountCheck; - + TExampleServer server; TSyncClient client(server.GetActualListenAddr()); client.Work(); @@ -65,5 +65,5 @@ namespace NBus { } } - } -} + } +} diff --git a/library/cpp/messagebus/test/ut/ya.make b/library/cpp/messagebus/test/ut/ya.make index 5af102e0ba..fe1b4961d6 100644 --- a/library/cpp/messagebus/test/ut/ya.make +++ b/library/cpp/messagebus/test/ut/ya.make @@ -1,7 +1,7 @@ OWNER(g:messagebus) - + UNITTEST_FOR(library/cpp/messagebus) - + TIMEOUT(1200) SIZE(LARGE) diff --git a/library/cpp/messagebus/test/ya.make b/library/cpp/messagebus/test/ya.make index 1c1f8bbd9c..0dc4bd4720 100644 --- a/library/cpp/messagebus/test/ya.make +++ b/library/cpp/messagebus/test/ya.make @@ -1,5 +1,5 @@ OWNER(g:messagebus) - + RECURSE( example perftest diff --git a/library/cpp/messagebus/text_utils.h b/library/cpp/messagebus/text_utils.h index 75489d1b07..c2dcad834c 100644 --- a/library/cpp/messagebus/text_utils.h +++ b/library/cpp/messagebus/text_utils.h @@ -1,3 +1,3 @@ -#pragma once - +#pragma once + #include <library/cpp/string_utils/indent_text/indent_text.h> diff --git a/library/cpp/messagebus/thread_extra.h b/library/cpp/messagebus/thread_extra.h index 9b19d516fa..2c79741e88 100644 --- a/library/cpp/messagebus/thread_extra.h +++ b/library/cpp/messagebus/thread_extra.h @@ -1,3 +1,3 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/actor/thread_extra.h> diff --git a/library/cpp/messagebus/use_after_free_checker.cpp b/library/cpp/messagebus/use_after_free_checker.cpp index f6586f8e7f..4904e7c614 100644 --- a/library/cpp/messagebus/use_after_free_checker.cpp +++ b/library/cpp/messagebus/use_after_free_checker.cpp @@ -1,22 +1,22 @@ #include "use_after_free_checker.h" -#include <util/system/yassert.h> - -namespace { +#include <util/system/yassert.h> + +namespace { const ui64 VALID = (ui64)0xAABBCCDDEEFF0011LL; const ui64 INVALID = (ui64)0x1122334455667788LL; -} - -TUseAfterFreeChecker::TUseAfterFreeChecker() - : Magic(VALID) -{ -} - +} + +TUseAfterFreeChecker::TUseAfterFreeChecker() + : Magic(VALID) +{ +} + TUseAfterFreeChecker::~TUseAfterFreeChecker() { Y_VERIFY(Magic == VALID, "Corrupted"); - Magic = INVALID; -} - -void TUseAfterFreeChecker::CheckNotFreed() const { + Magic = INVALID; +} + +void TUseAfterFreeChecker::CheckNotFreed() const { Y_VERIFY(Magic == VALID, "Freed or corrupted"); -} +} diff --git a/library/cpp/messagebus/use_after_free_checker.h b/library/cpp/messagebus/use_after_free_checker.h index 077abc4d92..590b076156 100644 --- a/library/cpp/messagebus/use_after_free_checker.h +++ b/library/cpp/messagebus/use_after_free_checker.h @@ -1,31 +1,31 @@ -#pragma once - -#include <util/system/platform.h> +#pragma once + +#include <util/system/platform.h> #include <util/system/types.h> - -class TUseAfterFreeChecker { -private: - ui64 Magic; -public: - TUseAfterFreeChecker(); - ~TUseAfterFreeChecker(); - void CheckNotFreed() const; -}; - -// check twice: in constructor and in destructor -class TUseAfterFreeCheckerGuard { -private: - const TUseAfterFreeChecker& Check; +class TUseAfterFreeChecker { +private: + ui64 Magic; + +public: + TUseAfterFreeChecker(); + ~TUseAfterFreeChecker(); + void CheckNotFreed() const; +}; + +// check twice: in constructor and in destructor +class TUseAfterFreeCheckerGuard { +private: + const TUseAfterFreeChecker& Check; + +public: + TUseAfterFreeCheckerGuard(const TUseAfterFreeChecker& check) + : Check(check) + { + Check.CheckNotFreed(); + } -public: - TUseAfterFreeCheckerGuard(const TUseAfterFreeChecker& check) - : Check(check) - { - Check.CheckNotFreed(); - } - - ~TUseAfterFreeCheckerGuard() { - Check.CheckNotFreed(); - } -}; + ~TUseAfterFreeCheckerGuard() { + Check.CheckNotFreed(); + } +}; diff --git a/library/cpp/messagebus/use_count_checker.cpp b/library/cpp/messagebus/use_count_checker.cpp index 5b253aca6f..c6243ea21f 100644 --- a/library/cpp/messagebus/use_count_checker.cpp +++ b/library/cpp/messagebus/use_count_checker.cpp @@ -1,53 +1,53 @@ #include "use_count_checker.h" #include <util/generic/utility.h> -#include <util/system/yassert.h> - -TUseCountChecker::TUseCountChecker() { -} - -TUseCountChecker::~TUseCountChecker() { - TAtomicBase count = Counter.Val(); +#include <util/system/yassert.h> + +TUseCountChecker::TUseCountChecker() { +} + +TUseCountChecker::~TUseCountChecker() { + TAtomicBase count = Counter.Val(); Y_VERIFY(count == 0, "must not release when count is not zero: %ld", (long)count); -} - -void TUseCountChecker::Inc() { - Counter.Inc(); -} - -void TUseCountChecker::Dec() { - Counter.Dec(); -} - -TUseCountHolder::TUseCountHolder() +} + +void TUseCountChecker::Inc() { + Counter.Inc(); +} + +void TUseCountChecker::Dec() { + Counter.Dec(); +} + +TUseCountHolder::TUseCountHolder() : CurrentChecker(nullptr) { } - -TUseCountHolder::TUseCountHolder(TUseCountChecker* currentChecker) - : CurrentChecker(currentChecker) -{ - if (!!CurrentChecker) { - CurrentChecker->Inc(); - } -} - + +TUseCountHolder::TUseCountHolder(TUseCountChecker* currentChecker) + : CurrentChecker(currentChecker) +{ + if (!!CurrentChecker) { + CurrentChecker->Inc(); + } +} + TUseCountHolder::~TUseCountHolder() { - if (!!CurrentChecker) { - CurrentChecker->Dec(); - } -} - -TUseCountHolder& TUseCountHolder::operator=(TUseCountHolder that) { - Swap(that); - return *this; -} - -void TUseCountHolder::Swap(TUseCountHolder& that) { - DoSwap(CurrentChecker, that.CurrentChecker); -} - -void TUseCountHolder::Reset() { - TUseCountHolder tmp; - Swap(tmp); -} + if (!!CurrentChecker) { + CurrentChecker->Dec(); + } +} + +TUseCountHolder& TUseCountHolder::operator=(TUseCountHolder that) { + Swap(that); + return *this; +} + +void TUseCountHolder::Swap(TUseCountHolder& that) { + DoSwap(CurrentChecker, that.CurrentChecker); +} + +void TUseCountHolder::Reset() { + TUseCountHolder tmp; + Swap(tmp); +} diff --git a/library/cpp/messagebus/use_count_checker.h b/library/cpp/messagebus/use_count_checker.h index 9437bace98..70bef6fa8a 100644 --- a/library/cpp/messagebus/use_count_checker.h +++ b/library/cpp/messagebus/use_count_checker.h @@ -1,27 +1,27 @@ -#pragma once - -#include <util/generic/refcount.h> - -class TUseCountChecker { -private: - TAtomicCounter Counter; +#pragma once -public: - TUseCountChecker(); - ~TUseCountChecker(); - void Inc(); - void Dec(); -}; - -class TUseCountHolder { -private: - TUseCountChecker* CurrentChecker; +#include <util/generic/refcount.h> -public: - TUseCountHolder(); - explicit TUseCountHolder(TUseCountChecker* currentChecker); - TUseCountHolder& operator=(TUseCountHolder that); - ~TUseCountHolder(); - void Swap(TUseCountHolder&); - void Reset(); -}; +class TUseCountChecker { +private: + TAtomicCounter Counter; + +public: + TUseCountChecker(); + ~TUseCountChecker(); + void Inc(); + void Dec(); +}; + +class TUseCountHolder { +private: + TUseCountChecker* CurrentChecker; + +public: + TUseCountHolder(); + explicit TUseCountHolder(TUseCountChecker* currentChecker); + TUseCountHolder& operator=(TUseCountHolder that); + ~TUseCountHolder(); + void Swap(TUseCountHolder&); + void Reset(); +}; diff --git a/library/cpp/messagebus/vector_swaps.h b/library/cpp/messagebus/vector_swaps.h index 510ee39ef9..b920bcf03e 100644 --- a/library/cpp/messagebus/vector_swaps.h +++ b/library/cpp/messagebus/vector_swaps.h @@ -1,171 +1,171 @@ -#pragma once - +#pragma once + #include <util/generic/array_ref.h> -#include <util/generic/noncopyable.h> +#include <util/generic/noncopyable.h> #include <util/generic/utility.h> -#include <util/system/yassert.h> - +#include <util/system/yassert.h> + #include <stdlib.h> template <typename T, class A = std::allocator<T>> class TVectorSwaps : TNonCopyable { -private: - T* Start; - T* Finish; - T* EndOfStorage; - - void StateCheck() { +private: + T* Start; + T* Finish; + T* EndOfStorage; + + void StateCheck() { Y_ASSERT(Start <= Finish); Y_ASSERT(Finish <= EndOfStorage); - } - -public: - typedef T* iterator; - typedef const T* const_iterator; - + } + +public: + typedef T* iterator; + typedef const T* const_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - + TVectorSwaps() : Start() , Finish() , EndOfStorage() { } - - ~TVectorSwaps() { - for (size_t i = 0; i < size(); ++i) { - Start[i].~T(); - } - free(Start); - } - + + ~TVectorSwaps() { + for (size_t i = 0; i < size(); ++i) { + Start[i].~T(); + } + free(Start); + } + operator TArrayRef<const T>() const { return MakeArrayRef(data(), size()); - } - + } + operator TArrayRef<T>() { return MakeArrayRef(data(), size()); - } - - size_t capacity() const { - return EndOfStorage - Start; - } - - size_t size() const { - return Finish - Start; - } - - bool empty() const { - return size() == 0; - } - - T* data() { - return Start; - } - - const T* data() const { - return Start; - } - - T& operator[](size_t index) { + } + + size_t capacity() const { + return EndOfStorage - Start; + } + + size_t size() const { + return Finish - Start; + } + + bool empty() const { + return size() == 0; + } + + T* data() { + return Start; + } + + const T* data() const { + return Start; + } + + T& operator[](size_t index) { Y_ASSERT(index < size()); - return Start[index]; - } - - const T& operator[](size_t index) const { + return Start[index]; + } + + const T& operator[](size_t index) const { Y_ASSERT(index < size()); - return Start[index]; - } - - iterator begin() { - return Start; - } - - iterator end() { - return Finish; - } - - const_iterator begin() const { - return Start; - } - - const_iterator end() const { - return Finish; - } - + return Start[index]; + } + + iterator begin() { + return Start; + } + + iterator end() { + return Finish; + } + + const_iterator begin() const { + return Start; + } + + const_iterator end() const { + return Finish; + } + reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } - + const_reverse_iterator rbegin() const { return reverse_iterator(end()); } const_reverse_iterator rend() const { return reverse_iterator(begin()); } - - void swap(TVectorSwaps<T>& that) { - DoSwap(Start, that.Start); - DoSwap(Finish, that.Finish); - DoSwap(EndOfStorage, that.EndOfStorage); - } - - void reserve(size_t n) { - if (n <= capacity()) { - return; - } - - size_t newCapacity = FastClp2(n); - TVectorSwaps<T> tmp; + + void swap(TVectorSwaps<T>& that) { + DoSwap(Start, that.Start); + DoSwap(Finish, that.Finish); + DoSwap(EndOfStorage, that.EndOfStorage); + } + + void reserve(size_t n) { + if (n <= capacity()) { + return; + } + + size_t newCapacity = FastClp2(n); + TVectorSwaps<T> tmp; tmp.Start = (T*)malloc(sizeof(T) * newCapacity); Y_VERIFY(!!tmp.Start); - - tmp.EndOfStorage = tmp.Start + newCapacity; - - for (size_t i = 0; i < size(); ++i) { - // TODO: catch exceptions - new (tmp.Start + i) T(); - DoSwap(Start[i], tmp.Start[i]); - } - - tmp.Finish = tmp.Start + size(); - - swap(tmp); - - StateCheck(); - } - - void clear() { - TVectorSwaps<T> tmp; - swap(tmp); - } - - template <class TIterator> - void insert(iterator pos, TIterator b, TIterator e) { + + tmp.EndOfStorage = tmp.Start + newCapacity; + + for (size_t i = 0; i < size(); ++i) { + // TODO: catch exceptions + new (tmp.Start + i) T(); + DoSwap(Start[i], tmp.Start[i]); + } + + tmp.Finish = tmp.Start + size(); + + swap(tmp); + + StateCheck(); + } + + void clear() { + TVectorSwaps<T> tmp; + swap(tmp); + } + + template <class TIterator> + void insert(iterator pos, TIterator b, TIterator e) { Y_VERIFY(pos == end(), "TODO: only insert at the end is implemented"); - - size_t count = e - b; - - reserve(size() + count); - - TIterator next = b; - - for (size_t i = 0; i < count; ++i) { - new (Start + size() + i) T(); - DoSwap(Start[size() + i], *next); - ++next; - } - - Finish += count; - - StateCheck(); - } - - void push_back(T& elem) { + + size_t count = e - b; + + reserve(size() + count); + + TIterator next = b; + + for (size_t i = 0; i < count; ++i) { + new (Start + size() + i) T(); + DoSwap(Start[size() + i], *next); + ++next; + } + + Finish += count; + + StateCheck(); + } + + void push_back(T& elem) { insert(end(), &elem, &elem + 1); - } -}; + } +}; diff --git a/library/cpp/messagebus/vector_swaps_ut.cpp b/library/cpp/messagebus/vector_swaps_ut.cpp index d30544092d..693cc6857b 100644 --- a/library/cpp/messagebus/vector_swaps_ut.cpp +++ b/library/cpp/messagebus/vector_swaps_ut.cpp @@ -1,17 +1,17 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "vector_swaps.h" - + +#include "vector_swaps.h" + Y_UNIT_TEST_SUITE(TVectorSwapsTest) { Y_UNIT_TEST(Simple) { TVectorSwaps<THolder<unsigned>> v; - for (unsigned i = 0; i < 100; ++i) { - THolder<unsigned> tmp(new unsigned(i)); - v.push_back(tmp); - } - - for (unsigned i = 0; i < 100; ++i) { - UNIT_ASSERT_VALUES_EQUAL(i, *v[i]); - } - } -} + for (unsigned i = 0; i < 100; ++i) { + THolder<unsigned> tmp(new unsigned(i)); + v.push_back(tmp); + } + + for (unsigned i = 0; i < 100; ++i) { + UNIT_ASSERT_VALUES_EQUAL(i, *v[i]); + } + } +} diff --git a/library/cpp/messagebus/www/concat_strings.h b/library/cpp/messagebus/www/concat_strings.h index bfaeab2c76..7b730564eb 100644 --- a/library/cpp/messagebus/www/concat_strings.h +++ b/library/cpp/messagebus/www/concat_strings.h @@ -1,22 +1,22 @@ -#pragma once - +#pragma once + #include <util/generic/string.h> -#include <util/stream/str.h> - +#include <util/stream/str.h> + // ATTN: not equivalent to TString::Join - cat concat anything "outputable" to stream, not only TString convertable types. - + inline void DoConcatStrings(TStringStream&) { -} - +} + template <class T, class... R> inline void DoConcatStrings(TStringStream& ss, const T& t, const R&... r) { ss << t; DoConcatStrings(ss, r...); -} - +} + template <class... R> inline TString ConcatStrings(const R&... r) { - TStringStream ss; + TStringStream ss; DoConcatStrings(ss, r...); - return ss.Str(); -} + return ss.Str(); +} diff --git a/library/cpp/messagebus/www/html_output.cpp b/library/cpp/messagebus/www/html_output.cpp index 9a35c5ca53..10ea2e163b 100644 --- a/library/cpp/messagebus/www/html_output.cpp +++ b/library/cpp/messagebus/www/html_output.cpp @@ -1,4 +1,4 @@ -#include "html_output.h" - +#include "html_output.h" + Y_POD_THREAD(IOutputStream*) HtmlOutputStreamPtr; diff --git a/library/cpp/messagebus/www/html_output.h b/library/cpp/messagebus/www/html_output.h index ff1c5da17b..27e77adefa 100644 --- a/library/cpp/messagebus/www/html_output.h +++ b/library/cpp/messagebus/www/html_output.h @@ -1,37 +1,37 @@ -#pragma once - +#pragma once + #include "concat_strings.h" #include <util/generic/string.h> -#include <util/stream/output.h> +#include <util/stream/output.h> #include <library/cpp/html/pcdata/pcdata.h> -#include <util/system/tls.h> - +#include <util/system/tls.h> + extern Y_POD_THREAD(IOutputStream*) HtmlOutputStreamPtr; - + static IOutputStream& HtmlOutputStream() { Y_VERIFY(!!HtmlOutputStreamPtr); - return *HtmlOutputStreamPtr; -} - -struct THtmlOutputStreamPushPop { + return *HtmlOutputStreamPtr; +} + +struct THtmlOutputStreamPushPop { IOutputStream* const Prev; - + THtmlOutputStreamPushPop(IOutputStream* outputStream) - : Prev(HtmlOutputStreamPtr) - { - HtmlOutputStreamPtr = outputStream; - } - - ~THtmlOutputStreamPushPop() { - HtmlOutputStreamPtr = Prev; - } -}; - -struct TChars { + : Prev(HtmlOutputStreamPtr) + { + HtmlOutputStreamPtr = outputStream; + } + + ~THtmlOutputStreamPushPop() { + HtmlOutputStreamPtr = Prev; + } +}; + +struct TChars { TString Text; - bool NeedEscape; - + bool NeedEscape; + TChars(TStringBuf text) : Text(text) , NeedEscape(true) @@ -52,273 +52,273 @@ struct TChars { , NeedEscape(escape) { } - + TString Escape() { - if (NeedEscape) { - return EncodeHtmlPcdata(Text); - } else { - return Text; - } - } -}; - -struct TAttr { + if (NeedEscape) { + return EncodeHtmlPcdata(Text); + } else { + return Text; + } + } +}; + +struct TAttr { TString Name; TString Value; - - TAttr(TStringBuf name, TStringBuf value) + + TAttr(TStringBuf name, TStringBuf value) : Name(name) , Value(value) { } - + TAttr() { } - - bool operator!() const { - return !Name; - } -}; - -static inline void Doctype() { - HtmlOutputStream() << "<!doctype html>\n"; -} - -static inline void Nl() { - HtmlOutputStream() << "\n"; -} - -static inline void Sp() { - HtmlOutputStream() << " "; -} - -static inline void Text(TStringBuf text) { - HtmlOutputStream() << EncodeHtmlPcdata(text); -} - -static inline void Line(TStringBuf text) { - Text(text); - Nl(); -} - -static inline void WriteAttr(TAttr a) { - if (!!a) { - HtmlOutputStream() << " " << a.Name << "='" << EncodeHtmlPcdata(a.Value) << "'"; - } -} - -static inline void Open(TStringBuf tag, TAttr a1 = TAttr(), TAttr a2 = TAttr(), TAttr a3 = TAttr(), TAttr a4 = TAttr()) { - HtmlOutputStream() << "<" << tag; - WriteAttr(a1); - WriteAttr(a2); - WriteAttr(a3); - WriteAttr(a4); - HtmlOutputStream() << ">"; -} - -static inline void Open(TStringBuf tag, TStringBuf cssClass, TStringBuf id = "") { - Open(tag, TAttr("class", cssClass), !!id ? TAttr("id", id) : TAttr()); -} - -static inline void OpenBlock(TStringBuf tag, TStringBuf cssClass = "") { - Open(tag, cssClass); - Nl(); -} - -static inline void Close(TStringBuf tag) { - HtmlOutputStream() << "</" << tag << ">\n"; -} - -static inline void CloseBlock(TStringBuf tag) { - Close(tag); - Nl(); -} - -static inline void TagWithContent(TStringBuf tag, TChars content) { - HtmlOutputStream() << "<" << tag << ">" << content.Escape() << "</" << tag << ">"; -} - -static inline void BlockTagWithContent(TStringBuf tag, TStringBuf content) { - TagWithContent(tag, content); - Nl(); -} - -static inline void TagWithClass(TStringBuf tag, TStringBuf cssClass) { - Open(tag, cssClass); - Close(tag); -} - -static inline void Hn(unsigned n, TStringBuf title) { - BlockTagWithContent(ConcatStrings("h", n), title); -} - -static inline void Small(TStringBuf text) { - TagWithContent("small", text); -} - -static inline void HnWithSmall(unsigned n, TStringBuf title, TStringBuf small) { + + bool operator!() const { + return !Name; + } +}; + +static inline void Doctype() { + HtmlOutputStream() << "<!doctype html>\n"; +} + +static inline void Nl() { + HtmlOutputStream() << "\n"; +} + +static inline void Sp() { + HtmlOutputStream() << " "; +} + +static inline void Text(TStringBuf text) { + HtmlOutputStream() << EncodeHtmlPcdata(text); +} + +static inline void Line(TStringBuf text) { + Text(text); + Nl(); +} + +static inline void WriteAttr(TAttr a) { + if (!!a) { + HtmlOutputStream() << " " << a.Name << "='" << EncodeHtmlPcdata(a.Value) << "'"; + } +} + +static inline void Open(TStringBuf tag, TAttr a1 = TAttr(), TAttr a2 = TAttr(), TAttr a3 = TAttr(), TAttr a4 = TAttr()) { + HtmlOutputStream() << "<" << tag; + WriteAttr(a1); + WriteAttr(a2); + WriteAttr(a3); + WriteAttr(a4); + HtmlOutputStream() << ">"; +} + +static inline void Open(TStringBuf tag, TStringBuf cssClass, TStringBuf id = "") { + Open(tag, TAttr("class", cssClass), !!id ? TAttr("id", id) : TAttr()); +} + +static inline void OpenBlock(TStringBuf tag, TStringBuf cssClass = "") { + Open(tag, cssClass); + Nl(); +} + +static inline void Close(TStringBuf tag) { + HtmlOutputStream() << "</" << tag << ">\n"; +} + +static inline void CloseBlock(TStringBuf tag) { + Close(tag); + Nl(); +} + +static inline void TagWithContent(TStringBuf tag, TChars content) { + HtmlOutputStream() << "<" << tag << ">" << content.Escape() << "</" << tag << ">"; +} + +static inline void BlockTagWithContent(TStringBuf tag, TStringBuf content) { + TagWithContent(tag, content); + Nl(); +} + +static inline void TagWithClass(TStringBuf tag, TStringBuf cssClass) { + Open(tag, cssClass); + Close(tag); +} + +static inline void Hn(unsigned n, TStringBuf title) { + BlockTagWithContent(ConcatStrings("h", n), title); +} + +static inline void Small(TStringBuf text) { + TagWithContent("small", text); +} + +static inline void HnWithSmall(unsigned n, TStringBuf title, TStringBuf small) { TString tagName = ConcatStrings("h", n); - Open(tagName); - HtmlOutputStream() << title; - Sp(); - Small(small); - Close(tagName); -} - -static inline void H1(TStringBuf title) { - Hn(1, title); -} - -static inline void H2(TStringBuf title) { - Hn(2, title); -} - -static inline void H3(TStringBuf title) { - Hn(3, title); -} - -static inline void H4(TStringBuf title) { - Hn(4, title); -} - -static inline void H5(TStringBuf title) { - Hn(5, title); -} - -static inline void H6(TStringBuf title) { - Hn(6, title); -} - -static inline void Pre(TStringBuf content) { - HtmlOutputStream() << "<pre>" << EncodeHtmlPcdata(content) << "</pre>\n"; -} - -static inline void Li(TStringBuf content) { - BlockTagWithContent("li", content); -} - -static inline void LiWithClass(TStringBuf cssClass, TStringBuf content) { - Open("li", cssClass); - Text(content); - Close("li"); -} - -static inline void OpenA(TStringBuf href) { - Open("a", TAttr("href", href)); -} - -static inline void A(TStringBuf href, TStringBuf text) { - OpenA(href); - Text(text); - Close("a"); -} - -static inline void Td(TStringBuf content) { - TagWithContent("td", content); -} - -static inline void Th(TStringBuf content, TStringBuf cssClass = "") { - OpenBlock("th", cssClass); - Text(content); - CloseBlock("th"); -} - -static inline void DivWithClassAndContent(TStringBuf cssClass, TStringBuf content) { - Open("div", cssClass); - Text(content); - Close("div"); -} - -static inline void BootstrapError(TStringBuf text) { - DivWithClassAndContent("alert alert-danger", text); -} - -static inline void BootstrapInfo(TStringBuf text) { - DivWithClassAndContent("alert alert-info", text); -} - -static inline void ScriptHref(TStringBuf href) { - Open("script", + Open(tagName); + HtmlOutputStream() << title; + Sp(); + Small(small); + Close(tagName); +} + +static inline void H1(TStringBuf title) { + Hn(1, title); +} + +static inline void H2(TStringBuf title) { + Hn(2, title); +} + +static inline void H3(TStringBuf title) { + Hn(3, title); +} + +static inline void H4(TStringBuf title) { + Hn(4, title); +} + +static inline void H5(TStringBuf title) { + Hn(5, title); +} + +static inline void H6(TStringBuf title) { + Hn(6, title); +} + +static inline void Pre(TStringBuf content) { + HtmlOutputStream() << "<pre>" << EncodeHtmlPcdata(content) << "</pre>\n"; +} + +static inline void Li(TStringBuf content) { + BlockTagWithContent("li", content); +} + +static inline void LiWithClass(TStringBuf cssClass, TStringBuf content) { + Open("li", cssClass); + Text(content); + Close("li"); +} + +static inline void OpenA(TStringBuf href) { + Open("a", TAttr("href", href)); +} + +static inline void A(TStringBuf href, TStringBuf text) { + OpenA(href); + Text(text); + Close("a"); +} + +static inline void Td(TStringBuf content) { + TagWithContent("td", content); +} + +static inline void Th(TStringBuf content, TStringBuf cssClass = "") { + OpenBlock("th", cssClass); + Text(content); + CloseBlock("th"); +} + +static inline void DivWithClassAndContent(TStringBuf cssClass, TStringBuf content) { + Open("div", cssClass); + Text(content); + Close("div"); +} + +static inline void BootstrapError(TStringBuf text) { + DivWithClassAndContent("alert alert-danger", text); +} + +static inline void BootstrapInfo(TStringBuf text) { + DivWithClassAndContent("alert alert-info", text); +} + +static inline void ScriptHref(TStringBuf href) { + Open("script", TAttr("language", "javascript"), TAttr("type", "text/javascript"), TAttr("src", href)); - Close("script"); - Nl(); -} - -static inline void LinkStylesheet(TStringBuf href) { - Open("link", TAttr("rel", "stylesheet"), TAttr("href", href)); - Close("link"); - Nl(); -} - -static inline void LinkFavicon(TStringBuf href) { - Open("link", TAttr("rel", "shortcut icon"), TAttr("href", href)); - Close("link"); - Nl(); -} - -static inline void Title(TChars title) { - TagWithContent("title", title); - Nl(); -} - -static inline void Code(TStringBuf content) { - TagWithContent("code", content); -} - -struct TTagGuard { + Close("script"); + Nl(); +} + +static inline void LinkStylesheet(TStringBuf href) { + Open("link", TAttr("rel", "stylesheet"), TAttr("href", href)); + Close("link"); + Nl(); +} + +static inline void LinkFavicon(TStringBuf href) { + Open("link", TAttr("rel", "shortcut icon"), TAttr("href", href)); + Close("link"); + Nl(); +} + +static inline void Title(TChars title) { + TagWithContent("title", title); + Nl(); +} + +static inline void Code(TStringBuf content) { + TagWithContent("code", content); +} + +struct TTagGuard { const TString TagName; - - TTagGuard(TStringBuf tagName, TStringBuf cssClass, TStringBuf id = "") - : TagName(tagName) - { - Open(TagName, cssClass, id); - } - - TTagGuard(TStringBuf tagName, TAttr a1 = TAttr(), TAttr a2 = TAttr(), TAttr a3 = TAttr(), TAttr a4 = TAttr()) - : TagName(tagName) - { - Open(tagName, a1, a2, a3, a4); - } - - ~TTagGuard() { - Close(TagName); - } -}; - -struct TDivGuard: public TTagGuard { - TDivGuard(TStringBuf cssClass, TStringBuf id = "") - : TTagGuard("div", cssClass, id) + + TTagGuard(TStringBuf tagName, TStringBuf cssClass, TStringBuf id = "") + : TagName(tagName) { + Open(TagName, cssClass, id); } - - TDivGuard(TAttr a1 = TAttr(), TAttr a2 = TAttr(), TAttr a3 = TAttr()) - : TTagGuard("div", a1, a2, a3) + + TTagGuard(TStringBuf tagName, TAttr a1 = TAttr(), TAttr a2 = TAttr(), TAttr a3 = TAttr(), TAttr a4 = TAttr()) + : TagName(tagName) + { + Open(tagName, a1, a2, a3, a4); + } + + ~TTagGuard() { + Close(TagName); + } +}; + +struct TDivGuard: public TTagGuard { + TDivGuard(TStringBuf cssClass, TStringBuf id = "") + : TTagGuard("div", cssClass, id) { } -}; - -struct TAGuard { + + TDivGuard(TAttr a1 = TAttr(), TAttr a2 = TAttr(), TAttr a3 = TAttr()) + : TTagGuard("div", a1, a2, a3) + { + } +}; + +struct TAGuard { TAGuard(TStringBuf href) { - OpenA(href); - } - - ~TAGuard() { - Close("a"); - } -}; - -struct TScriptFunctionGuard { - TTagGuard Script; - - TScriptFunctionGuard() - : Script("script") - { - Line("$(function() {"); - } - + OpenA(href); + } + + ~TAGuard() { + Close("a"); + } +}; + +struct TScriptFunctionGuard { + TTagGuard Script; + + TScriptFunctionGuard() + : Script("script") + { + Line("$(function() {"); + } + ~TScriptFunctionGuard() { - Line("});"); - } -}; + Line("});"); + } +}; diff --git a/library/cpp/messagebus/www/messagebus.js b/library/cpp/messagebus/www/messagebus.js index 2781f47df3..e30508b879 100644 --- a/library/cpp/messagebus/www/messagebus.js +++ b/library/cpp/messagebus/www/messagebus.js @@ -1,48 +1,48 @@ -function logTransform(v) { - return Math.log(v + 1); -} - -function plotHist(where, hist) { +function logTransform(v) { + return Math.log(v + 1); +} + +function plotHist(where, hist) { var max = hist.map(function(x) {return x[1]}).reduce(function(x, y) {return Math.max(x, y)}); - - var ticks = []; - for (var t = 1; ; t *= 10) { - if (t > max) { - break; - } - ticks.push(t); - } - - $.plot(where, [hist], - { - data: hist, - series: { - bars: { - show: true, - barWidth: 0.9 - } - }, - xaxis: { - mode: 'categories', - tickLength: 0 - }, - yaxis: { - ticks: ticks, - transform: logTransform - } - } - ); -} - -function plotQueueSize(where, data, ticks) { - $.plot(where, [data], - { - xaxis: { - ticks: ticks, - }, - yaxis: { - //transform: logTransform - } - } - ); -} + + var ticks = []; + for (var t = 1; ; t *= 10) { + if (t > max) { + break; + } + ticks.push(t); + } + + $.plot(where, [hist], + { + data: hist, + series: { + bars: { + show: true, + barWidth: 0.9 + } + }, + xaxis: { + mode: 'categories', + tickLength: 0 + }, + yaxis: { + ticks: ticks, + transform: logTransform + } + } + ); +} + +function plotQueueSize(where, data, ticks) { + $.plot(where, [data], + { + xaxis: { + ticks: ticks, + }, + yaxis: { + //transform: logTransform + } + } + ); +} diff --git a/library/cpp/messagebus/www/www.cpp b/library/cpp/messagebus/www/www.cpp index 90c50aacfc..62ec241d85 100644 --- a/library/cpp/messagebus/www/www.cpp +++ b/library/cpp/messagebus/www/www.cpp @@ -1,8 +1,8 @@ #include "www.h" - + #include "concat_strings.h" #include "html_output.h" - + #include <library/cpp/messagebus/remote_connection_status.h> #include <library/cpp/monlib/deprecated/json/writer.h> @@ -12,243 +12,243 @@ #include <library/cpp/http/server/http.h> #include <library/cpp/json/writer/json.h> #include <library/cpp/uri/http_url.h> - + #include <util/string/cast.h> #include <util/string/printf.h> #include <util/system/mutex.h> - + #include <utility> - -using namespace NBus; -using namespace NBus::NPrivate; -using namespace NActor; -using namespace NActor::NPrivate; - -static const char HTTP_OK_JS[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/javascript\r\nConnection: Close\r\n\r\n"; -static const char HTTP_OK_JSON[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/json; charset=utf-8\r\nConnection: Close\r\n\r\n"; -static const char HTTP_OK_PNG[] = "HTTP/1.1 200 Ok\r\nContent-Type: image/png\r\nConnection: Close\r\n\r\n"; -static const char HTTP_OK_BIN[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/octet-stream\r\nConnection: Close\r\n\r\n"; -static const char HTTP_OK_HTML[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/html; charset=utf-8\r\nConnection: Close\r\n\r\n"; - -namespace { - typedef TIntrusivePtr<TBusModuleInternal> TBusModuleInternalPtr; - - template <typename TValuePtr> - struct TNamedValues { + +using namespace NBus; +using namespace NBus::NPrivate; +using namespace NActor; +using namespace NActor::NPrivate; + +static const char HTTP_OK_JS[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/javascript\r\nConnection: Close\r\n\r\n"; +static const char HTTP_OK_JSON[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/json; charset=utf-8\r\nConnection: Close\r\n\r\n"; +static const char HTTP_OK_PNG[] = "HTTP/1.1 200 Ok\r\nContent-Type: image/png\r\nConnection: Close\r\n\r\n"; +static const char HTTP_OK_BIN[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/octet-stream\r\nConnection: Close\r\n\r\n"; +static const char HTTP_OK_HTML[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/html; charset=utf-8\r\nConnection: Close\r\n\r\n"; + +namespace { + typedef TIntrusivePtr<TBusModuleInternal> TBusModuleInternalPtr; + + template <typename TValuePtr> + struct TNamedValues { TVector<std::pair<TString, TValuePtr>> Entries; - - TValuePtr FindByName(TStringBuf name) { + + TValuePtr FindByName(TStringBuf name) { Y_VERIFY(!!name); - - for (unsigned i = 0; i < Entries.size(); ++i) { - if (Entries[i].first == name) { - return Entries[i].second; - } - } - return TValuePtr(); - } - + + for (unsigned i = 0; i < Entries.size(); ++i) { + if (Entries[i].first == name) { + return Entries[i].second; + } + } + return TValuePtr(); + } + TString FindNameByPtr(TValuePtr value) { Y_VERIFY(!!value); - - for (unsigned i = 0; i < Entries.size(); ++i) { - if (Entries[i].second.Get() == value.Get()) { - return Entries[i].first; - } - } - + + for (unsigned i = 0; i < Entries.size(); ++i) { + if (Entries[i].second.Get() == value.Get()) { + return Entries[i].first; + } + } + Y_FAIL("unregistered"); - } - - void Add(TValuePtr p) { + } + + void Add(TValuePtr p) { Y_VERIFY(!!p); - - // Do not add twice - for (unsigned i = 0; i < Entries.size(); ++i) { - if (Entries[i].second.Get() == p.Get()) { - return; - } - } - - if (!!p->GetNameInternal()) { - TValuePtr current = FindByName(p->GetNameInternal()); - - if (!current) { + + // Do not add twice + for (unsigned i = 0; i < Entries.size(); ++i) { + if (Entries[i].second.Get() == p.Get()) { + return; + } + } + + if (!!p->GetNameInternal()) { + TValuePtr current = FindByName(p->GetNameInternal()); + + if (!current) { Entries.emplace_back(p->GetNameInternal(), p); - return; - } - } - + return; + } + } + for (unsigned i = 1;; ++i) { TString prefix = p->GetNameInternal(); - if (!prefix) { - prefix = "unnamed"; - } + if (!prefix) { + prefix = "unnamed"; + } TString name = ConcatStrings(prefix, "-", i); - - TValuePtr current = FindByName(name); - - if (!current) { + + TValuePtr current = FindByName(name); + + if (!current) { Entries.emplace_back(name, p); - return; - } - } - } - - size_t size() const { - return Entries.size(); - } - - bool operator!() const { - return size() == 0; - } - }; - - template <typename TSessionPtr> - struct TSessionValues: public TNamedValues<TSessionPtr> { - typedef TNamedValues<TSessionPtr> TBase; - + return; + } + } + } + + size_t size() const { + return Entries.size(); + } + + bool operator!() const { + return size() == 0; + } + }; + + template <typename TSessionPtr> + struct TSessionValues: public TNamedValues<TSessionPtr> { + typedef TNamedValues<TSessionPtr> TBase; + TVector<TString> GetNamesForQueue(TBusMessageQueue* queue) { TVector<TString> r; - for (unsigned i = 0; i < TBase::size(); ++i) { - if (TBase::Entries[i].second->GetQueue() == queue) { - r.push_back(TBase::Entries[i].first); - } - } - return r; - } - }; -} - -namespace { + for (unsigned i = 0; i < TBase::size(); ++i) { + if (TBase::Entries[i].second->GetQueue() == queue) { + r.push_back(TBase::Entries[i].first); + } + } + return r; + } + }; +} + +namespace { TString RootHref() { - return ConcatStrings("?"); - } - + return ConcatStrings("?"); + } + TString QueueHref(TStringBuf name) { - return ConcatStrings("?q=", name); - } - + return ConcatStrings("?q=", name); + } + TString ServerSessionHref(TStringBuf name) { - return ConcatStrings("?ss=", name); - } - + return ConcatStrings("?ss=", name); + } + TString ClientSessionHref(TStringBuf name) { - return ConcatStrings("?cs=", name); - } - + return ConcatStrings("?cs=", name); + } + TString OldModuleHref(TStringBuf name) { - return ConcatStrings("?om=", name); - } - - /* - static void RootLink() { - A(RootHref(), "root"); - } - */ - + return ConcatStrings("?om=", name); + } + + /* + static void RootLink() { + A(RootHref(), "root"); + } + */ + void QueueLink(TStringBuf name) { - A(QueueHref(name), name); - } - + A(QueueHref(name), name); + } + void ServerSessionLink(TStringBuf name) { - A(ServerSessionHref(name), name); - } - + A(ServerSessionHref(name), name); + } + void ClientSessionLink(TStringBuf name) { - A(ClientSessionHref(name), name); - } - + A(ClientSessionHref(name), name); + } + void OldModuleLink(TStringBuf name) { - A(OldModuleHref(name), name); - } - -} - -const unsigned char WWW_STATIC_DATA[] = { -#include "www_static.inc" -}; - + A(OldModuleHref(name), name); + } + +} + +const unsigned char WWW_STATIC_DATA[] = { +#include "www_static.inc" +}; + class TWwwStaticLoader: public TArchiveReader { -public: - TWwwStaticLoader() - : TArchiveReader(TBlob::NoCopy(WWW_STATIC_DATA, sizeof(WWW_STATIC_DATA))) - { - } -}; - -struct TBusWww::TImpl { - // TODO: use weak pointers - TNamedValues<TBusMessageQueuePtr> Queues; +public: + TWwwStaticLoader() + : TArchiveReader(TBlob::NoCopy(WWW_STATIC_DATA, sizeof(WWW_STATIC_DATA))) + { + } +}; + +struct TBusWww::TImpl { + // TODO: use weak pointers + TNamedValues<TBusMessageQueuePtr> Queues; TSessionValues<TIntrusivePtr<TBusClientSession>> ClientSessions; TSessionValues<TIntrusivePtr<TBusServerSession>> ServerSessions; - TSessionValues<TBusModuleInternalPtr> Modules; - - TMutex Mutex; - - void RegisterClientSession(TBusClientSessionPtr s) { + TSessionValues<TBusModuleInternalPtr> Modules; + + TMutex Mutex; + + void RegisterClientSession(TBusClientSessionPtr s) { Y_VERIFY(!!s); - TGuard<TMutex> g(Mutex); - ClientSessions.Add(s.Get()); - Queues.Add(s->GetQueue()); - } - - void RegisterServerSession(TBusServerSessionPtr s) { + TGuard<TMutex> g(Mutex); + ClientSessions.Add(s.Get()); + Queues.Add(s->GetQueue()); + } + + void RegisterServerSession(TBusServerSessionPtr s) { Y_VERIFY(!!s); - TGuard<TMutex> g(Mutex); - ServerSessions.Add(s.Get()); - Queues.Add(s->GetQueue()); - } - + TGuard<TMutex> g(Mutex); + ServerSessions.Add(s.Get()); + Queues.Add(s->GetQueue()); + } + void RegisterQueue(TBusMessageQueuePtr q) { Y_VERIFY(!!q); TGuard<TMutex> g(Mutex); Queues.Add(q); } - void RegisterModule(TBusModule* module) { + void RegisterModule(TBusModule* module) { Y_VERIFY(!!module); - TGuard<TMutex> g(Mutex); - - { + TGuard<TMutex> g(Mutex); + + { TVector<TBusClientSessionPtr> clientSessions = module->GetInternal()->GetClientSessionsInternal(); - for (unsigned i = 0; i < clientSessions.size(); ++i) { - RegisterClientSession(clientSessions[i]); - } - } - - { + for (unsigned i = 0; i < clientSessions.size(); ++i) { + RegisterClientSession(clientSessions[i]); + } + } + + { TVector<TBusServerSessionPtr> serverSessions = module->GetInternal()->GetServerSessionsInternal(); - for (unsigned i = 0; i < serverSessions.size(); ++i) { - RegisterServerSession(serverSessions[i]); - } - } - - Queues.Add(module->GetInternal()->GetQueue()); - Modules.Add(module->GetInternal()); - } - + for (unsigned i = 0; i < serverSessions.size(); ++i) { + RegisterServerSession(serverSessions[i]); + } + } + + Queues.Add(module->GetInternal()->GetQueue()); + Modules.Add(module->GetInternal()); + } + TString FindQueueNameBySessionName(TStringBuf sessionName, bool client) { - TIntrusivePtr<TBusClientSession> clientSession; - TIntrusivePtr<TBusServerSession> serverSession; - TBusSession* session; - if (client) { - clientSession = ClientSessions.FindByName(sessionName); - session = clientSession.Get(); - } else { - serverSession = ServerSessions.FindByName(sessionName); - session = serverSession.Get(); - } + TIntrusivePtr<TBusClientSession> clientSession; + TIntrusivePtr<TBusServerSession> serverSession; + TBusSession* session; + if (client) { + clientSession = ClientSessions.FindByName(sessionName); + session = clientSession.Get(); + } else { + serverSession = ServerSessions.FindByName(sessionName); + session = serverSession.Get(); + } Y_VERIFY(!!session); - return Queues.FindNameByPtr(session->GetQueue()); - } - - struct TRequest { - TImpl* const Outer; + return Queues.FindNameByPtr(session->GetQueue()); + } + + struct TRequest { + TImpl* const Outer; IOutputStream& Os; - const TCgiParameters& CgiParams; - const TOptionalParams& Params; - + const TCgiParameters& CgiParams; + const TOptionalParams& Params; + TRequest(TImpl* outer, IOutputStream& os, const TCgiParameters& cgiParams, const TOptionalParams& params) : Outer(outer) , Os(os) @@ -256,675 +256,675 @@ struct TBusWww::TImpl { , Params(params) { } - - void CrumbsParentLinks() { - for (unsigned i = 0; i < Params.ParentLinks.size(); ++i) { - const TLink& link = Params.ParentLinks[i]; - TTagGuard li("li"); - A(link.Href, link.Title); - } - } - - void Crumb(TStringBuf name, TStringBuf href = "") { - if (!!href) { - TTagGuard li("li"); - A(href, name); - } else { - LiWithClass("active", name); - } - } - - void BreadcrumbRoot() { - TTagGuard ol("ol", "breadcrumb"); - CrumbsParentLinks(); - Crumb("MessageBus"); - } - - void BreadcrumbQueue(TStringBuf queueName) { - TTagGuard ol("ol", "breadcrumb"); - CrumbsParentLinks(); - Crumb("MessageBus", RootHref()); - Crumb(ConcatStrings("queue ", queueName)); - } - - void BreadcrumbSession(TStringBuf sessionName, bool client) { + + void CrumbsParentLinks() { + for (unsigned i = 0; i < Params.ParentLinks.size(); ++i) { + const TLink& link = Params.ParentLinks[i]; + TTagGuard li("li"); + A(link.Href, link.Title); + } + } + + void Crumb(TStringBuf name, TStringBuf href = "") { + if (!!href) { + TTagGuard li("li"); + A(href, name); + } else { + LiWithClass("active", name); + } + } + + void BreadcrumbRoot() { + TTagGuard ol("ol", "breadcrumb"); + CrumbsParentLinks(); + Crumb("MessageBus"); + } + + void BreadcrumbQueue(TStringBuf queueName) { + TTagGuard ol("ol", "breadcrumb"); + CrumbsParentLinks(); + Crumb("MessageBus", RootHref()); + Crumb(ConcatStrings("queue ", queueName)); + } + + void BreadcrumbSession(TStringBuf sessionName, bool client) { TString queueName = Outer->FindQueueNameBySessionName(sessionName, client); - TStringBuf whatSession = client ? "client session" : "server session"; - - TTagGuard ol("ol", "breadcrumb"); - CrumbsParentLinks(); - Crumb("MessageBus", RootHref()); - Crumb(ConcatStrings("queue ", queueName), QueueHref(queueName)); - Crumb(ConcatStrings(whatSession, " ", sessionName)); - } - - void ServeSessionsOfQueue(TBusMessageQueuePtr queue, bool includeQueue) { + TStringBuf whatSession = client ? "client session" : "server session"; + + TTagGuard ol("ol", "breadcrumb"); + CrumbsParentLinks(); + Crumb("MessageBus", RootHref()); + Crumb(ConcatStrings("queue ", queueName), QueueHref(queueName)); + Crumb(ConcatStrings(whatSession, " ", sessionName)); + } + + void ServeSessionsOfQueue(TBusMessageQueuePtr queue, bool includeQueue) { TVector<TString> clientNames = Outer->ClientSessions.GetNamesForQueue(queue.Get()); TVector<TString> serverNames = Outer->ServerSessions.GetNamesForQueue(queue.Get()); TVector<TString> moduleNames = Outer->Modules.GetNamesForQueue(queue.Get()); - - TTagGuard table("table", "table table-condensed table-bordered"); - - { - TTagGuard colgroup("colgroup"); - TagWithClass("col", "col-md-2"); - TagWithClass("col", "col-md-2"); - TagWithClass("col", "col-md-8"); - } - - { - TTagGuard tr("tr"); - Th("What", "span2"); - Th("Name", "span2"); - Th("Status", "span6"); - } - - if (includeQueue) { + + TTagGuard table("table", "table table-condensed table-bordered"); + + { + TTagGuard colgroup("colgroup"); + TagWithClass("col", "col-md-2"); + TagWithClass("col", "col-md-2"); + TagWithClass("col", "col-md-8"); + } + + { + TTagGuard tr("tr"); + Th("What", "span2"); + Th("Name", "span2"); + Th("Status", "span6"); + } + + if (includeQueue) { TTagGuard tr1("tr"); - Td("queue"); - - { - TTagGuard td("td"); - QueueLink(Outer->Queues.FindNameByPtr(queue)); - } - - { + Td("queue"); + + { + TTagGuard td("td"); + QueueLink(Outer->Queues.FindNameByPtr(queue)); + } + + { TTagGuard tr2("td"); - Pre(queue->GetStatusSingleLine()); - } - } - - for (unsigned j = 0; j < clientNames.size(); ++j) { - TTagGuard tr("tr"); - Td("client session"); - - { - TTagGuard td("td"); - ClientSessionLink(clientNames[j]); - } - - { - TTagGuard td("td"); - Pre(Outer->ClientSessions.FindByName(clientNames[j])->GetStatusSingleLine()); - } - } - - for (unsigned j = 0; j < serverNames.size(); ++j) { - TTagGuard tr("tr"); - Td("server session"); - - { - TTagGuard td("td"); - ServerSessionLink(serverNames[j]); - } - - { - TTagGuard td("td"); - Pre(Outer->ServerSessions.FindByName(serverNames[j])->GetStatusSingleLine()); - } - } - - for (unsigned j = 0; j < moduleNames.size(); ++j) { - TTagGuard tr("tr"); - Td("module"); - - { - TTagGuard td("td"); - if (false) { - OldModuleLink(moduleNames[j]); - } else { - // TODO - Text(moduleNames[j]); - } - } - - { - TTagGuard td("td"); - Pre(Outer->Modules.FindByName(moduleNames[j])->GetStatusSingleLine()); - } - } - } - + Pre(queue->GetStatusSingleLine()); + } + } + + for (unsigned j = 0; j < clientNames.size(); ++j) { + TTagGuard tr("tr"); + Td("client session"); + + { + TTagGuard td("td"); + ClientSessionLink(clientNames[j]); + } + + { + TTagGuard td("td"); + Pre(Outer->ClientSessions.FindByName(clientNames[j])->GetStatusSingleLine()); + } + } + + for (unsigned j = 0; j < serverNames.size(); ++j) { + TTagGuard tr("tr"); + Td("server session"); + + { + TTagGuard td("td"); + ServerSessionLink(serverNames[j]); + } + + { + TTagGuard td("td"); + Pre(Outer->ServerSessions.FindByName(serverNames[j])->GetStatusSingleLine()); + } + } + + for (unsigned j = 0; j < moduleNames.size(); ++j) { + TTagGuard tr("tr"); + Td("module"); + + { + TTagGuard td("td"); + if (false) { + OldModuleLink(moduleNames[j]); + } else { + // TODO + Text(moduleNames[j]); + } + } + + { + TTagGuard td("td"); + Pre(Outer->Modules.FindByName(moduleNames[j])->GetStatusSingleLine()); + } + } + } + void ServeQueue(const TString& name) { - TBusMessageQueuePtr queue = Outer->Queues.FindByName(name); - - if (!queue) { - BootstrapError(ConcatStrings("queue not found by name: ", name)); - return; - } - - BreadcrumbQueue(name); - - TDivGuard container("container"); - - H1(ConcatStrings("MessageBus queue ", '"', name, '"')); - - TBusMessageQueueStatus status = queue->GetStatusRecordInternal(); - - Pre(status.PrintToString()); - - ServeSessionsOfQueue(queue, false); - - HnWithSmall(3, "Peak queue size", "(stored for an hour)"); - - { - TDivGuard div; - TDivGuard div2(TAttr("id", "queue-size-graph"), TAttr("style", "height: 300px")); - } - - { - TScriptFunctionGuard script; - - NJsonWriter::TBuf data(NJsonWriter::HEM_ESCAPE_HTML); - NJsonWriter::TBuf ticks(NJsonWriter::HEM_ESCAPE_HTML); - - const TExecutorHistory& history = status.ExecutorStatus.History; - - data.BeginList(); - ticks.BeginList(); - for (unsigned i = 0; i < history.HistoryRecords.size(); ++i) { - ui64 secondOfMinute = (history.FirstHistoryRecordSecond() + i) % 60; - ui64 minuteOfHour = (history.FirstHistoryRecordSecond() + i) / 60 % 60; - - unsigned printEach; - - if (history.HistoryRecords.size() <= 500) { - printEach = 1; - } else if (history.HistoryRecords.size() <= 1000) { - printEach = 2; - } else if (history.HistoryRecords.size() <= 3000) { - printEach = 6; - } else { - printEach = 12; - } - - if (secondOfMinute % printEach != 0) { - continue; - } - - ui32 max = 0; - for (unsigned j = 0; j < printEach; ++j) { - if (i < j) { - continue; - } - max = Max<ui32>(max, history.HistoryRecords[i - j].MaxQueueSize); - } - - data.BeginList(); - data.WriteString(ToString(i)); - data.WriteInt(max); - data.EndList(); - - // TODO: can be done with flot time plugin - if (history.HistoryRecords.size() <= 20) { - ticks.BeginList(); - ticks.WriteInt(i); - ticks.WriteString(ToString(secondOfMinute)); - ticks.EndList(); - } else if (history.HistoryRecords.size() <= 60) { - if (secondOfMinute % 5 == 0) { - ticks.BeginList(); - ticks.WriteInt(i); - ticks.WriteString(ToString(secondOfMinute)); - ticks.EndList(); - } - } else { - bool needTick; - if (history.HistoryRecords.size() <= 3 * 60) { - needTick = secondOfMinute % 15 == 0; - } else if (history.HistoryRecords.size() <= 7 * 60) { - needTick = secondOfMinute % 30 == 0; - } else if (history.HistoryRecords.size() <= 20 * 60) { - needTick = secondOfMinute == 0; - } else { - needTick = secondOfMinute == 0 && minuteOfHour % 5 == 0; - } - if (needTick) { - ticks.BeginList(); - ticks.WriteInt(i); + TBusMessageQueuePtr queue = Outer->Queues.FindByName(name); + + if (!queue) { + BootstrapError(ConcatStrings("queue not found by name: ", name)); + return; + } + + BreadcrumbQueue(name); + + TDivGuard container("container"); + + H1(ConcatStrings("MessageBus queue ", '"', name, '"')); + + TBusMessageQueueStatus status = queue->GetStatusRecordInternal(); + + Pre(status.PrintToString()); + + ServeSessionsOfQueue(queue, false); + + HnWithSmall(3, "Peak queue size", "(stored for an hour)"); + + { + TDivGuard div; + TDivGuard div2(TAttr("id", "queue-size-graph"), TAttr("style", "height: 300px")); + } + + { + TScriptFunctionGuard script; + + NJsonWriter::TBuf data(NJsonWriter::HEM_ESCAPE_HTML); + NJsonWriter::TBuf ticks(NJsonWriter::HEM_ESCAPE_HTML); + + const TExecutorHistory& history = status.ExecutorStatus.History; + + data.BeginList(); + ticks.BeginList(); + for (unsigned i = 0; i < history.HistoryRecords.size(); ++i) { + ui64 secondOfMinute = (history.FirstHistoryRecordSecond() + i) % 60; + ui64 minuteOfHour = (history.FirstHistoryRecordSecond() + i) / 60 % 60; + + unsigned printEach; + + if (history.HistoryRecords.size() <= 500) { + printEach = 1; + } else if (history.HistoryRecords.size() <= 1000) { + printEach = 2; + } else if (history.HistoryRecords.size() <= 3000) { + printEach = 6; + } else { + printEach = 12; + } + + if (secondOfMinute % printEach != 0) { + continue; + } + + ui32 max = 0; + for (unsigned j = 0; j < printEach; ++j) { + if (i < j) { + continue; + } + max = Max<ui32>(max, history.HistoryRecords[i - j].MaxQueueSize); + } + + data.BeginList(); + data.WriteString(ToString(i)); + data.WriteInt(max); + data.EndList(); + + // TODO: can be done with flot time plugin + if (history.HistoryRecords.size() <= 20) { + ticks.BeginList(); + ticks.WriteInt(i); + ticks.WriteString(ToString(secondOfMinute)); + ticks.EndList(); + } else if (history.HistoryRecords.size() <= 60) { + if (secondOfMinute % 5 == 0) { + ticks.BeginList(); + ticks.WriteInt(i); + ticks.WriteString(ToString(secondOfMinute)); + ticks.EndList(); + } + } else { + bool needTick; + if (history.HistoryRecords.size() <= 3 * 60) { + needTick = secondOfMinute % 15 == 0; + } else if (history.HistoryRecords.size() <= 7 * 60) { + needTick = secondOfMinute % 30 == 0; + } else if (history.HistoryRecords.size() <= 20 * 60) { + needTick = secondOfMinute == 0; + } else { + needTick = secondOfMinute == 0 && minuteOfHour % 5 == 0; + } + if (needTick) { + ticks.BeginList(); + ticks.WriteInt(i); ticks.WriteString(Sprintf(":%02u:%02u", (unsigned)minuteOfHour, (unsigned)secondOfMinute)); - ticks.EndList(); - } - } - } - ticks.EndList(); - data.EndList(); - - HtmlOutputStream() << " var data = " << data.Str() << ";\n"; - HtmlOutputStream() << " var ticks = " << ticks.Str() << ";\n"; - HtmlOutputStream() << " plotQueueSize('#queue-size-graph', data, ticks);\n"; - } - } - - void ServeSession(TStringBuf name, bool client) { - TIntrusivePtr<TBusClientSession> clientSession; - TIntrusivePtr<TBusServerSession> serverSession; - TBusSession* session; - TStringBuf whatSession; - if (client) { - whatSession = "client session"; - clientSession = Outer->ClientSessions.FindByName(name); - session = clientSession.Get(); - } else { - whatSession = "server session"; - serverSession = Outer->ServerSessions.FindByName(name); - session = serverSession.Get(); - } - if (!session) { - BootstrapError(ConcatStrings(whatSession, " not found by name: ", name)); - return; - } - - TSessionDumpStatus dumpStatus = session->GetStatusRecordInternal(); - - TBusMessageQueuePtr queue = session->GetQueue(); + ticks.EndList(); + } + } + } + ticks.EndList(); + data.EndList(); + + HtmlOutputStream() << " var data = " << data.Str() << ";\n"; + HtmlOutputStream() << " var ticks = " << ticks.Str() << ";\n"; + HtmlOutputStream() << " plotQueueSize('#queue-size-graph', data, ticks);\n"; + } + } + + void ServeSession(TStringBuf name, bool client) { + TIntrusivePtr<TBusClientSession> clientSession; + TIntrusivePtr<TBusServerSession> serverSession; + TBusSession* session; + TStringBuf whatSession; + if (client) { + whatSession = "client session"; + clientSession = Outer->ClientSessions.FindByName(name); + session = clientSession.Get(); + } else { + whatSession = "server session"; + serverSession = Outer->ServerSessions.FindByName(name); + session = serverSession.Get(); + } + if (!session) { + BootstrapError(ConcatStrings(whatSession, " not found by name: ", name)); + return; + } + + TSessionDumpStatus dumpStatus = session->GetStatusRecordInternal(); + + TBusMessageQueuePtr queue = session->GetQueue(); TString queueName = Outer->Queues.FindNameByPtr(session->GetQueue()); - - BreadcrumbSession(name, client); - - TDivGuard container("container"); - - H1(ConcatStrings("MessageBus ", whatSession, " ", '"', name, '"')); - - TBusMessageQueueStatus queueStatus = queue->GetStatusRecordInternal(); - - { - H3(ConcatStrings("queue ", queueName)); - Pre(queueStatus.PrintToString()); - } - - TSessionDumpStatus status = session->GetStatusRecordInternal(); - - if (status.Shutdown) { - BootstrapError("Session shut down"); - return; - } - - H3("Basic"); - Pre(status.Head); - - if (status.ConnectionStatusSummary.Server) { - H3("Acceptors"); - Pre(status.Acceptors); - } - - H3("Connections"); - Pre(status.ConnectionsSummary); - - { - TDivGuard div; - TTagGuard button("button", + + BreadcrumbSession(name, client); + + TDivGuard container("container"); + + H1(ConcatStrings("MessageBus ", whatSession, " ", '"', name, '"')); + + TBusMessageQueueStatus queueStatus = queue->GetStatusRecordInternal(); + + { + H3(ConcatStrings("queue ", queueName)); + Pre(queueStatus.PrintToString()); + } + + TSessionDumpStatus status = session->GetStatusRecordInternal(); + + if (status.Shutdown) { + BootstrapError("Session shut down"); + return; + } + + H3("Basic"); + Pre(status.Head); + + if (status.ConnectionStatusSummary.Server) { + H3("Acceptors"); + Pre(status.Acceptors); + } + + H3("Connections"); + Pre(status.ConnectionsSummary); + + { + TDivGuard div; + TTagGuard button("button", TAttr("type", "button"), TAttr("class", "btn"), TAttr("data-toggle", "collapse"), TAttr("data-target", "#connections")); - Text("Show connection details"); - } - { - TDivGuard div(TAttr("id", "connections"), TAttr("class", "collapse")); - Pre(status.Connections); - } - - H3("TBusSessionConfig"); - Pre(status.Config.PrintToString()); - - if (!client) { - H3("Message process time histogram"); - - const TDurationHistogram& h = + Text("Show connection details"); + } + { + TDivGuard div(TAttr("id", "connections"), TAttr("class", "collapse")); + Pre(status.Connections); + } + + H3("TBusSessionConfig"); + Pre(status.Config.PrintToString()); + + if (!client) { + H3("Message process time histogram"); + + const TDurationHistogram& h = dumpStatus.ConnectionStatusSummary.WriterStatus.Incremental.ProcessDurationHistogram; - - { - TDivGuard div; - TDivGuard div2(TAttr("id", "h"), TAttr("style", "height: 300px")); - } - - { - TScriptFunctionGuard script; - - NJsonWriter::TBuf buf(NJsonWriter::HEM_ESCAPE_HTML); - buf.BeginList(); - for (unsigned i = 0; i < h.Times.size(); ++i) { + + { + TDivGuard div; + TDivGuard div2(TAttr("id", "h"), TAttr("style", "height: 300px")); + } + + { + TScriptFunctionGuard script; + + NJsonWriter::TBuf buf(NJsonWriter::HEM_ESCAPE_HTML); + buf.BeginList(); + for (unsigned i = 0; i < h.Times.size(); ++i) { TString label = TDurationHistogram::LabelBefore(i); - buf.BeginList(); - buf.WriteString(label); - buf.WriteLongLong(h.Times[i]); - buf.EndList(); - } - buf.EndList(); - - HtmlOutputStream() << " var hist = " << buf.Str() << ";\n"; - HtmlOutputStream() << " plotHist('#h', hist);\n"; - } - } - } - - void ServeDefault() { - if (!Outer->Queues) { - BootstrapError("no queues"); - return; - } - - BreadcrumbRoot(); - - TDivGuard container("container"); - - H1("MessageBus queues"); - - for (unsigned i = 0; i < Outer->Queues.size(); ++i) { + buf.BeginList(); + buf.WriteString(label); + buf.WriteLongLong(h.Times[i]); + buf.EndList(); + } + buf.EndList(); + + HtmlOutputStream() << " var hist = " << buf.Str() << ";\n"; + HtmlOutputStream() << " plotHist('#h', hist);\n"; + } + } + } + + void ServeDefault() { + if (!Outer->Queues) { + BootstrapError("no queues"); + return; + } + + BreadcrumbRoot(); + + TDivGuard container("container"); + + H1("MessageBus queues"); + + for (unsigned i = 0; i < Outer->Queues.size(); ++i) { TString queueName = Outer->Queues.Entries[i].first; - TBusMessageQueuePtr queue = Outer->Queues.Entries[i].second; - - HnWithSmall(3, queueName, "(queue)"); - - ServeSessionsOfQueue(queue, true); - } - } - + TBusMessageQueuePtr queue = Outer->Queues.Entries[i].second; + + HnWithSmall(3, queueName, "(queue)"); + + ServeSessionsOfQueue(queue, true); + } + } + void WriteQueueSensors(NMonitoring::TDeprecatedJsonWriter& sj, TStringBuf queueName, TBusMessageQueue* queue) { - auto status = queue->GetStatusRecordInternal(); + auto status = queue->GetStatusRecordInternal(); sj.OpenMetric(); - sj.WriteLabels("mb_queue", queueName, "sensor", "WorkQueueSize"); - sj.WriteValue(status.ExecutorStatus.WorkQueueSize); + sj.WriteLabels("mb_queue", queueName, "sensor", "WorkQueueSize"); + sj.WriteValue(status.ExecutorStatus.WorkQueueSize); sj.CloseMetric(); - } - + } + void WriteMessageCounterSensors(NMonitoring::TDeprecatedJsonWriter& sj, TStringBuf labelName, TStringBuf sessionName, bool read, const TMessageCounter& counter) { - TStringBuf readOrWrite = read ? "read" : "write"; - + TStringBuf readOrWrite = read ? "read" : "write"; + sj.OpenMetric(); - sj.WriteLabels(labelName, sessionName, "mb_dir", readOrWrite, "sensor", "MessageBytes"); - sj.WriteValue(counter.BytesData); - sj.WriteModeDeriv(); + sj.WriteLabels(labelName, sessionName, "mb_dir", readOrWrite, "sensor", "MessageBytes"); + sj.WriteValue(counter.BytesData); + sj.WriteModeDeriv(); sj.CloseMetric(); - + sj.OpenMetric(); - sj.WriteLabels(labelName, sessionName, "mb_dir", readOrWrite, "sensor", "MessageCount"); - sj.WriteValue(counter.Count); - sj.WriteModeDeriv(); + sj.WriteLabels(labelName, sessionName, "mb_dir", readOrWrite, "sensor", "MessageCount"); + sj.WriteValue(counter.Count); + sj.WriteModeDeriv(); sj.CloseMetric(); - } - + } + void WriteSessionStatus(NMonitoring::TDeprecatedJsonWriter& sj, TStringBuf sessionName, bool client, TBusSession* session) { - TStringBuf labelName = client ? "mb_client_session" : "mb_server_session"; - - auto status = session->GetStatusRecordInternal(); - + TStringBuf labelName = client ? "mb_client_session" : "mb_server_session"; + + auto status = session->GetStatusRecordInternal(); + sj.OpenMetric(); - sj.WriteLabels(labelName, sessionName, "sensor", "InFlightCount"); - sj.WriteValue(status.Status.InFlightCount); + sj.WriteLabels(labelName, sessionName, "sensor", "InFlightCount"); + sj.WriteValue(status.Status.InFlightCount); sj.CloseMetric(); - + sj.OpenMetric(); - sj.WriteLabels(labelName, sessionName, "sensor", "InFlightSize"); - sj.WriteValue(status.Status.InFlightSize); + sj.WriteLabels(labelName, sessionName, "sensor", "InFlightSize"); + sj.WriteValue(status.Status.InFlightSize); sj.CloseMetric(); - + sj.OpenMetric(); - sj.WriteLabels(labelName, sessionName, "sensor", "SendQueueSize"); - sj.WriteValue(status.ConnectionStatusSummary.WriterStatus.SendQueueSize); + sj.WriteLabels(labelName, sessionName, "sensor", "SendQueueSize"); + sj.WriteValue(status.ConnectionStatusSummary.WriterStatus.SendQueueSize); sj.CloseMetric(); - - if (client) { + + if (client) { sj.OpenMetric(); - sj.WriteLabels(labelName, sessionName, "sensor", "AckMessagesSize"); - sj.WriteValue(status.ConnectionStatusSummary.WriterStatus.AckMessagesSize); + sj.WriteLabels(labelName, sessionName, "sensor", "AckMessagesSize"); + sj.WriteValue(status.ConnectionStatusSummary.WriterStatus.AckMessagesSize); sj.CloseMetric(); - } - - WriteMessageCounterSensors(sj, labelName, sessionName, false, + } + + WriteMessageCounterSensors(sj, labelName, sessionName, false, status.ConnectionStatusSummary.WriterStatus.Incremental.MessageCounter); - WriteMessageCounterSensors(sj, labelName, sessionName, true, + WriteMessageCounterSensors(sj, labelName, sessionName, true, status.ConnectionStatusSummary.ReaderStatus.Incremental.MessageCounter); - } - + } + void ServeSolomonJson(const TString& q, const TString& cs, const TString& ss) { Y_UNUSED(q); Y_UNUSED(cs); Y_UNUSED(ss); - bool all = q == "" && cs == "" && ss == ""; - + bool all = q == "" && cs == "" && ss == ""; + NMonitoring::TDeprecatedJsonWriter sj(&Os); - - sj.OpenDocument(); + + sj.OpenDocument(); sj.OpenMetrics(); - - for (unsigned i = 0; i < Outer->Queues.size(); ++i) { + + for (unsigned i = 0; i < Outer->Queues.size(); ++i) { TString queueName = Outer->Queues.Entries[i].first; - TBusMessageQueuePtr queue = Outer->Queues.Entries[i].second; - if (all || q == queueName) { - WriteQueueSensors(sj, queueName, &*queue); - } - + TBusMessageQueuePtr queue = Outer->Queues.Entries[i].second; + if (all || q == queueName) { + WriteQueueSensors(sj, queueName, &*queue); + } + TVector<TString> clientNames = Outer->ClientSessions.GetNamesForQueue(queue.Get()); TVector<TString> serverNames = Outer->ServerSessions.GetNamesForQueue(queue.Get()); TVector<TString> moduleNames = Outer->Modules.GetNamesForQueue(queue.Get()); - for (auto& sessionName : clientNames) { - if (all || cs == sessionName) { - auto session = Outer->ClientSessions.FindByName(sessionName); - WriteSessionStatus(sj, sessionName, true, &*session); - } - } - - for (auto& sessionName : serverNames) { - if (all || ss == sessionName) { - auto session = Outer->ServerSessions.FindByName(sessionName); - WriteSessionStatus(sj, sessionName, false, &*session); - } - } - } - + for (auto& sessionName : clientNames) { + if (all || cs == sessionName) { + auto session = Outer->ClientSessions.FindByName(sessionName); + WriteSessionStatus(sj, sessionName, true, &*session); + } + } + + for (auto& sessionName : serverNames) { + if (all || ss == sessionName) { + auto session = Outer->ServerSessions.FindByName(sessionName); + WriteSessionStatus(sj, sessionName, false, &*session); + } + } + } + sj.CloseMetrics(); - sj.CloseDocument(); - } - + sj.CloseDocument(); + } + void ServeStatic(IOutputStream& os, TStringBuf path) { if (path.EndsWith(".js")) { - os << HTTP_OK_JS; + os << HTTP_OK_JS; } else if (path.EndsWith(".png")) { - os << HTTP_OK_PNG; - } else { - os << HTTP_OK_BIN; - } + os << HTTP_OK_PNG; + } else { + os << HTTP_OK_BIN; + } TBlob blob = Singleton<TWwwStaticLoader>()->ObjectBlobByKey(TString("/") + TString(path)); - os.Write(blob.Data(), blob.Size()); - } - - void HeaderJsCss() { - LinkStylesheet("//yandex.st/bootstrap/3.0.2/css/bootstrap.css"); - LinkFavicon("?file=bus-ico.png"); - ScriptHref("//yandex.st/jquery/2.0.3/jquery.js"); - ScriptHref("//yandex.st/bootstrap/3.0.2/js/bootstrap.js"); - ScriptHref("//cdnjs.cloudflare.com/ajax/libs/flot/0.8.1/jquery.flot.min.js"); - ScriptHref("//cdnjs.cloudflare.com/ajax/libs/flot/0.8.1/jquery.flot.categories.min.js"); - ScriptHref("?file=messagebus.js"); - } - - void Serve() { - THtmlOutputStreamPushPop pp(&Os); - - TCgiParameters::const_iterator file = CgiParams.Find("file"); - if (file != CgiParams.end()) { - ServeStatic(Os, file->second); - return; - } - - bool solomonJson = false; - TCgiParameters::const_iterator fmt = CgiParams.Find("fmt"); - if (fmt != CgiParams.end()) { - if (fmt->second == "solomon-json") { - solomonJson = true; - } - } - - TCgiParameters::const_iterator cs = CgiParams.Find("cs"); - TCgiParameters::const_iterator ss = CgiParams.Find("ss"); - TCgiParameters::const_iterator q = CgiParams.Find("q"); - - if (solomonJson) { - Os << HTTP_OK_JSON; - + os.Write(blob.Data(), blob.Size()); + } + + void HeaderJsCss() { + LinkStylesheet("//yandex.st/bootstrap/3.0.2/css/bootstrap.css"); + LinkFavicon("?file=bus-ico.png"); + ScriptHref("//yandex.st/jquery/2.0.3/jquery.js"); + ScriptHref("//yandex.st/bootstrap/3.0.2/js/bootstrap.js"); + ScriptHref("//cdnjs.cloudflare.com/ajax/libs/flot/0.8.1/jquery.flot.min.js"); + ScriptHref("//cdnjs.cloudflare.com/ajax/libs/flot/0.8.1/jquery.flot.categories.min.js"); + ScriptHref("?file=messagebus.js"); + } + + void Serve() { + THtmlOutputStreamPushPop pp(&Os); + + TCgiParameters::const_iterator file = CgiParams.Find("file"); + if (file != CgiParams.end()) { + ServeStatic(Os, file->second); + return; + } + + bool solomonJson = false; + TCgiParameters::const_iterator fmt = CgiParams.Find("fmt"); + if (fmt != CgiParams.end()) { + if (fmt->second == "solomon-json") { + solomonJson = true; + } + } + + TCgiParameters::const_iterator cs = CgiParams.Find("cs"); + TCgiParameters::const_iterator ss = CgiParams.Find("ss"); + TCgiParameters::const_iterator q = CgiParams.Find("q"); + + if (solomonJson) { + Os << HTTP_OK_JSON; + TString qp = q != CgiParams.end() ? q->first : ""; TString csp = cs != CgiParams.end() ? cs->first : ""; TString ssp = ss != CgiParams.end() ? ss->first : ""; - ServeSolomonJson(qp, csp, ssp); - } else { - Os << HTTP_OK_HTML; - - Doctype(); - - TTagGuard html("html"); - { - TTagGuard head("head"); - - HeaderJsCss(); - // ✉ 🚌 - Title(TChars("MessageBus", false)); - } - - TTagGuard body("body"); - - if (cs != CgiParams.end()) { - ServeSession(cs->second, true); - } else if (ss != CgiParams.end()) { - ServeSession(ss->second, false); - } else if (q != CgiParams.end()) { - ServeQueue(q->second); - } else { - ServeDefault(); - } - } - } - }; - + ServeSolomonJson(qp, csp, ssp); + } else { + Os << HTTP_OK_HTML; + + Doctype(); + + TTagGuard html("html"); + { + TTagGuard head("head"); + + HeaderJsCss(); + // ✉ 🚌 + Title(TChars("MessageBus", false)); + } + + TTagGuard body("body"); + + if (cs != CgiParams.end()) { + ServeSession(cs->second, true); + } else if (ss != CgiParams.end()) { + ServeSession(ss->second, false); + } else if (q != CgiParams.end()) { + ServeQueue(q->second); + } else { + ServeDefault(); + } + } + } + }; + void ServeHttp(IOutputStream& os, const TCgiParameters& queryArgs, const TBusWww::TOptionalParams& params) { - TGuard<TMutex> g(Mutex); - - TRequest request(this, os, queryArgs, params); - - request.Serve(); - } -}; - -NBus::TBusWww::TBusWww() - : Impl(new TImpl) -{ -} - + TGuard<TMutex> g(Mutex); + + TRequest request(this, os, queryArgs, params); + + request.Serve(); + } +}; + +NBus::TBusWww::TBusWww() + : Impl(new TImpl) +{ +} + NBus::TBusWww::~TBusWww() { -} - +} + void NBus::TBusWww::RegisterClientSession(TBusClientSessionPtr s) { - Impl->RegisterClientSession(s); -} - + Impl->RegisterClientSession(s); +} + void TBusWww::RegisterServerSession(TBusServerSessionPtr s) { - Impl->RegisterServerSession(s); -} - + Impl->RegisterServerSession(s); +} + void TBusWww::RegisterQueue(TBusMessageQueuePtr q) { Impl->RegisterQueue(q); } -void TBusWww::RegisterModule(TBusModule* module) { - Impl->RegisterModule(module); -} - +void TBusWww::RegisterModule(TBusModule* module) { + Impl->RegisterModule(module); +} + void TBusWww::ServeHttp(IOutputStream& httpOutputStream, const TCgiParameters& queryArgs, const TBusWww::TOptionalParams& params) { - Impl->ServeHttp(httpOutputStream, queryArgs, params); -} - -struct TBusWwwHttpServer::TImpl: public THttpServer::ICallBack { - TIntrusivePtr<TBusWww> Www; - THttpServer HttpServer; - - static THttpServer::TOptions MakeHttpServerOptions(unsigned port) { + Impl->ServeHttp(httpOutputStream, queryArgs, params); +} + +struct TBusWwwHttpServer::TImpl: public THttpServer::ICallBack { + TIntrusivePtr<TBusWww> Www; + THttpServer HttpServer; + + static THttpServer::TOptions MakeHttpServerOptions(unsigned port) { Y_VERIFY(port > 0); - THttpServer::TOptions r; - r.Port = port; - return r; - } - - TImpl(TIntrusivePtr<TBusWww> www, unsigned port) - : Www(www) - , HttpServer(this, MakeHttpServerOptions(port)) - { - HttpServer.Start(); - } - - struct TClientRequestImpl: public TClientRequest { - TBusWwwHttpServer::TImpl* const Outer; - - TClientRequestImpl(TBusWwwHttpServer::TImpl* outer) - : Outer(outer) + THttpServer::TOptions r; + r.Port = port; + return r; + } + + TImpl(TIntrusivePtr<TBusWww> www, unsigned port) + : Www(www) + , HttpServer(this, MakeHttpServerOptions(port)) + { + HttpServer.Start(); + } + + struct TClientRequestImpl: public TClientRequest { + TBusWwwHttpServer::TImpl* const Outer; + + TClientRequestImpl(TBusWwwHttpServer::TImpl* outer) + : Outer(outer) { } - + bool Reply(void*) override { - Outer->ServeRequest(Input(), Output()); - return true; - } - }; - + Outer->ServeRequest(Input(), Output()); + return true; + } + }; + TString MakeSimpleResponse(unsigned code, TString text, TString content = "") { - if (!content) { - TStringStream contentSs; - contentSs << code << " " << text; - content = contentSs.Str(); - } - TStringStream ss; - ss << "HTTP/1.1 " + if (!content) { + TStringStream contentSs; + contentSs << code << " " << text; + content = contentSs.Str(); + } + TStringStream ss; + ss << "HTTP/1.1 " << code << " " << text << "\r\nConnection: Close\r\n\r\n" << content; - return ss.Str(); - } - - void ServeRequest(THttpInput& input, THttpOutput& output) { - TCgiParameters cgiParams; - try { - THttpRequestHeader header; - THttpHeaderParser parser; - parser.Init(&header); - if (parser.Execute(input.FirstLine()) < 0) { - HtmlOutputStream() << MakeSimpleResponse(400, "Bad request"); - return; - } - THttpURL url; - if (url.Parse(header.GetUrl()) != THttpURL::ParsedOK) { - HtmlOutputStream() << MakeSimpleResponse(400, "Invalid url"); - return; - } - cgiParams.Scan(url.Get(THttpURL::FieldQuery)); - - TBusWww::TOptionalParams params; + return ss.Str(); + } + + void ServeRequest(THttpInput& input, THttpOutput& output) { + TCgiParameters cgiParams; + try { + THttpRequestHeader header; + THttpHeaderParser parser; + parser.Init(&header); + if (parser.Execute(input.FirstLine()) < 0) { + HtmlOutputStream() << MakeSimpleResponse(400, "Bad request"); + return; + } + THttpURL url; + if (url.Parse(header.GetUrl()) != THttpURL::ParsedOK) { + HtmlOutputStream() << MakeSimpleResponse(400, "Invalid url"); + return; + } + cgiParams.Scan(url.Get(THttpURL::FieldQuery)); + + TBusWww::TOptionalParams params; //params.ParentLinks.emplace_back(); - //params.ParentLinks.back().Title = "temp"; - //params.ParentLinks.back().Href = "http://wiki.yandex-team.ru/"; - - Www->ServeHttp(output, cgiParams, params); - } catch (...) { - output << MakeSimpleResponse(500, "Exception", + //params.ParentLinks.back().Title = "temp"; + //params.ParentLinks.back().Href = "http://wiki.yandex-team.ru/"; + + Www->ServeHttp(output, cgiParams, params); + } catch (...) { + output << MakeSimpleResponse(500, "Exception", TString() + "Exception: " + CurrentExceptionMessage()); - } - } - + } + } + TClientRequest* CreateClient() override { - return new TClientRequestImpl(this); - } - + return new TClientRequestImpl(this); + } + ~TImpl() override { - HttpServer.Stop(); - } -}; - -NBus::TBusWwwHttpServer::TBusWwwHttpServer(TIntrusivePtr<TBusWww> www, unsigned port) - : Impl(new TImpl(www, port)) -{ -} - + HttpServer.Stop(); + } +}; + +NBus::TBusWwwHttpServer::TBusWwwHttpServer(TIntrusivePtr<TBusWww> www, unsigned port) + : Impl(new TImpl(www, port)) +{ +} + NBus::TBusWwwHttpServer::~TBusWwwHttpServer() { -} +} diff --git a/library/cpp/messagebus/www/www.h b/library/cpp/messagebus/www/www.h index 6e6f5f582c..6cd652b477 100644 --- a/library/cpp/messagebus/www/www.h +++ b/library/cpp/messagebus/www/www.h @@ -1,45 +1,45 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/ybus.h> #include <library/cpp/messagebus/oldmodule/module.h> #include <util/generic/ptr.h> #include <util/generic/string.h> #include <library/cpp/cgiparam/cgiparam.h> - -namespace NBus { + +namespace NBus { class TBusWww: public TAtomicRefCount<TBusWww> { public: struct TLink { TString Title; TString Href; }; - + struct TOptionalParams { TVector<TLink> ParentLinks; }; - + TBusWww(); ~TBusWww(); - + void RegisterClientSession(TBusClientSessionPtr); void RegisterServerSession(TBusServerSessionPtr); void RegisterQueue(TBusMessageQueuePtr); void RegisterModule(TBusModule*); - + void ServeHttp(IOutputStream& httpOutputStream, const TCgiParameters& queryArgs, const TOptionalParams& params = TOptionalParams()); - + struct TImpl; THolder<TImpl> Impl; }; - + class TBusWwwHttpServer { public: TBusWwwHttpServer(TIntrusivePtr<TBusWww> www, unsigned port); ~TBusWwwHttpServer(); - + struct TImpl; THolder<TImpl> Impl; }; - + } diff --git a/library/cpp/messagebus/www/ya.make b/library/cpp/messagebus/www/ya.make index f3e1300290..972390cea3 100644 --- a/library/cpp/messagebus/www/ya.make +++ b/library/cpp/messagebus/www/ya.make @@ -1,19 +1,19 @@ -LIBRARY() - +LIBRARY() + OWNER(g:messagebus) - -SRCS( - html_output.cpp - www.cpp -) - -ARCHIVE( - NAME www_static.inc - messagebus.js - bus-ico.png -) - -PEERDIR( + +SRCS( + html_output.cpp + www.cpp +) + +ARCHIVE( + NAME www_static.inc + messagebus.js + bus-ico.png +) + +PEERDIR( library/cpp/archive library/cpp/cgiparam library/cpp/html/pcdata @@ -24,6 +24,6 @@ PEERDIR( library/cpp/messagebus/oldmodule library/cpp/monlib/deprecated/json library/cpp/uri -) - -END() +) + +END() diff --git a/library/cpp/messagebus/ya.make b/library/cpp/messagebus/ya.make index a8fdf6de92..e13cf06dea 100644 --- a/library/cpp/messagebus/ya.make +++ b/library/cpp/messagebus/ya.make @@ -1,7 +1,7 @@ LIBRARY() OWNER(g:messagebus) - + IF (SANITIZER_TYPE == "undefined") NO_SANITIZE() ENDIF() diff --git a/library/cpp/messagebus/ybus.h b/library/cpp/messagebus/ybus.h index dcd06824f0..de21ad8521 100644 --- a/library/cpp/messagebus/ybus.h +++ b/library/cpp/messagebus/ybus.h @@ -1,20 +1,20 @@ #pragma once /// Asynchronous Messaging Library implements framework for sending and -/// receiving messages between loosely connected processes. +/// receiving messages between loosely connected processes. #include "coreconn.h" -#include "defs.h" -#include "handler.h" -#include "handler_impl.h" -#include "local_flags.h" +#include "defs.h" +#include "handler.h" +#include "handler_impl.h" +#include "local_flags.h" #include "locator.h" -#include "message.h" +#include "message.h" #include "message_status.h" #include "network.h" #include "queue_config.h" #include "remote_connection_status.h" -#include "session.h" +#include "session.h" #include "session_config.h" #include "socket_addr.h" @@ -24,8 +24,8 @@ #include <library/cpp/codecs/codecs.h> #include <util/generic/array_ref.h> -#include <util/generic/buffer.h> -#include <util/generic/noncopyable.h> +#include <util/generic/buffer.h> +#include <util/generic/noncopyable.h> #include <util/generic/ptr.h> #include <util/stream/input.h> #include <util/system/atomic.h> @@ -49,7 +49,7 @@ namespace NBus { /// and destination server. Protocol object is reponsible for serializing in-memory /// message and reply into the wire, retuning name of the service and resource /// distribution key for given protocol. - + /// Protocol object should transparently handle messages and replies. /// This is interface only class, actuall instances of the protocols /// should be created using templates inhereted from this base class. @@ -105,24 +105,24 @@ namespace NBus { public: TBusSyncSourceSession(TIntrusivePtr< ::NBus::NPrivate::TBusSyncSourceSessionImpl> session); ~TBusSyncSourceSession(); - + void Shutdown(); - + TBusMessage* SendSyncMessage(TBusMessage* pMessage, EMessageStatus& status, const TNetAddr* addr = nullptr); - + int RegisterService(const char* hostname, TBusKey start = YBUS_KEYMIN, TBusKey end = YBUS_KEYMAX, EIpVersion ipVersion = EIP_VERSION_4); - + int GetInFlight(); - + const TBusProtocol* GetProto() const; const TBusClientSession* GetBusClientSessionWorkaroundDoNotUse() const; // It's for TLoadBalancedProtocol::GetDestination() function that really needs TBusClientSession* unlike all other protocols. Look at review 32425 (http://rb.yandex-team.ru/arc/r/32425/) for more information. private: TIntrusivePtr< ::NBus::NPrivate::TBusSyncSourceSessionImpl> Session; }; - + using TBusSyncClientSessionPtr = TIntrusivePtr<TBusSyncSourceSession>; - + /////////////////////////////////////////////////////////////////// /// \brief Main message queue object, need one per application class TBusMessageQueue: public TAtomicRefCount<TBusMessageQueue> { @@ -132,7 +132,7 @@ namespace NBus { friend struct ::NBus::NPrivate::TBusSessionImpl; friend class ::NBus::NPrivate::TAcceptor; friend struct ::NBus::TBusServerSession; - + private: const TBusQueueConfig Config; TMutex Lock; @@ -144,16 +144,16 @@ namespace NBus { TAtomic Running; TSystemEvent ShutdownComplete; - + private: /// constructor is protected, used NBus::CreateMessageQueue() to create a instance TBusMessageQueue(const TBusQueueConfig& config, NActor::TExecutorPtr executor, TBusLocator* locator, const char* name); - + public: TString GetNameInternal() const; ~TBusMessageQueue(); - + void Stop(); bool IsRunning(); @@ -161,17 +161,17 @@ namespace NBus { void EnqueueWork(TArrayRef< ::NActor::IWorkItem* const> w) { WorkQueue->EnqueueWork(w); } - + ::NActor::TExecutor* GetExecutor() { return WorkQueue.Get(); } - + TString GetStatus(ui16 flags = YBUS_STATUS_CONNS) const; // without sessions NPrivate::TBusMessageQueueStatus GetStatusRecordInternal() const; TString GetStatusSelf() const; TString GetStatusSingleLine() const; - + TBusLocator* GetLocator() const { return Locator.Get(); } diff --git a/library/cpp/monlib/deprecated/json/ut/ya.make b/library/cpp/monlib/deprecated/json/ut/ya.make index 556b0c8291..18315993b5 100644 --- a/library/cpp/monlib/deprecated/json/ut/ya.make +++ b/library/cpp/monlib/deprecated/json/ut/ya.make @@ -1,12 +1,12 @@ UNITTEST_FOR(library/cpp/monlib/deprecated/json) - + OWNER( jamel g:solomon ) - -SRCS( + +SRCS( writer_ut.cpp -) - -END() +) + +END() diff --git a/library/cpp/monlib/deprecated/json/writer.cpp b/library/cpp/monlib/deprecated/json/writer.cpp index 9917288687..a581f2e07a 100644 --- a/library/cpp/monlib/deprecated/json/writer.cpp +++ b/library/cpp/monlib/deprecated/json/writer.cpp @@ -1,36 +1,36 @@ #include "writer.h" - + namespace NMonitoring { TDeprecatedJsonWriter::TDeprecatedJsonWriter(IOutputStream* out) : JsonWriter(out, false) , State(STATE_ROOT) { } - + void TDeprecatedJsonWriter::TransitionState(EState current, EState next) { if (State != current) { ythrow yexception() << "wrong state"; } State = next; } - + void TDeprecatedJsonWriter::OpenDocument() { TransitionState(STATE_ROOT, STATE_DOCUMENT); JsonWriter.OpenMap(); - } - + } + void TDeprecatedJsonWriter::CloseDocument() { TransitionState(STATE_DOCUMENT, STATE_ROOT); JsonWriter.CloseMap(); JsonWriter.Flush(); } - + void TDeprecatedJsonWriter::OpenCommonLabels() { TransitionState(STATE_DOCUMENT, STATE_COMMON_LABELS); JsonWriter.Write("commonLabels"); JsonWriter.OpenMap(); } - + void TDeprecatedJsonWriter::CloseCommonLabels() { TransitionState(STATE_COMMON_LABELS, STATE_DOCUMENT); JsonWriter.CloseMap(); @@ -51,50 +51,50 @@ namespace NMonitoring { TransitionState(STATE_METRICS, STATE_DOCUMENT); JsonWriter.CloseArray(); } - + void TDeprecatedJsonWriter::OpenMetric() { TransitionState(STATE_METRICS, STATE_METRIC); JsonWriter.OpenMap(); } - + void TDeprecatedJsonWriter::CloseMetric() { TransitionState(STATE_METRIC, STATE_METRICS); JsonWriter.CloseMap(); } - + void TDeprecatedJsonWriter::OpenLabels() { TransitionState(STATE_METRIC, STATE_LABELS); JsonWriter.Write("labels"); JsonWriter.OpenMap(); } - + void TDeprecatedJsonWriter::CloseLabels() { TransitionState(STATE_LABELS, STATE_METRIC); JsonWriter.CloseMap(); } - + void TDeprecatedJsonWriter::WriteLabel(TStringBuf name, TStringBuf value) { TransitionState(STATE_LABELS, STATE_LABELS); JsonWriter.Write(name, value); } - + void TDeprecatedJsonWriter::WriteModeDeriv() { TransitionState(STATE_METRIC, STATE_METRIC); JsonWriter.Write("mode", "deriv"); } - + void TDeprecatedJsonWriter::WriteValue(long long value) { TransitionState(STATE_METRIC, STATE_METRIC); JsonWriter.Write("value", value); } - + void TDeprecatedJsonWriter::WriteDoubleValue(double value) { TransitionState(STATE_METRIC, STATE_METRIC); JsonWriter.Write("value", value); } - + void TDeprecatedJsonWriter::WriteTs(ui64 ts) { TransitionState(STATE_METRIC, STATE_METRIC); JsonWriter.Write("ts", ts); } -} +} diff --git a/library/cpp/monlib/deprecated/json/writer.h b/library/cpp/monlib/deprecated/json/writer.h index 2ea8ce40c1..183288143c 100644 --- a/library/cpp/monlib/deprecated/json/writer.h +++ b/library/cpp/monlib/deprecated/json/writer.h @@ -1,7 +1,7 @@ -#pragma once - +#pragma once + #include <library/cpp/json/json_writer.h> - + namespace NMonitoring { /** * Deprecated writer of Solomon JSON format @@ -12,24 +12,24 @@ namespace NMonitoring { * particular format. */ class TDeprecatedJsonWriter { - private: - NJson::TJsonWriter JsonWriter; - enum EState { - STATE_ROOT, - STATE_DOCUMENT, + private: + NJson::TJsonWriter JsonWriter; + enum EState { + STATE_ROOT, + STATE_DOCUMENT, STATE_COMMON_LABELS, STATE_METRICS, STATE_METRIC, - STATE_LABELS, - }; - EState State; + STATE_LABELS, + }; + EState State; - public: + public: explicit TDeprecatedJsonWriter(IOutputStream* out); - - void OpenDocument(); - void CloseDocument(); - + + void OpenDocument(); + void CloseDocument(); + void OpenCommonLabels(); void CloseCommonLabels(); @@ -37,40 +37,40 @@ namespace NMonitoring { void OpenMetrics(); void CloseMetrics(); - + void OpenMetric(); void CloseMetric(); - - void OpenLabels(); - void CloseLabels(); - - void WriteLabel(TStringBuf name, TStringBuf value); - - template <typename... T> - void WriteLabels(T... pairs) { - OpenLabels(); - WriteLabelsInner(pairs...); - CloseLabels(); - } - - void WriteModeDeriv(); - - void WriteValue(long long value); - void WriteDoubleValue(double d); + + void OpenLabels(); + void CloseLabels(); + + void WriteLabel(TStringBuf name, TStringBuf value); + + template <typename... T> + void WriteLabels(T... pairs) { + OpenLabels(); + WriteLabelsInner(pairs...); + CloseLabels(); + } + + void WriteModeDeriv(); + + void WriteValue(long long value); + void WriteDoubleValue(double d); void WriteTs(ui64 ts); - private: - void WriteLabelsInner(TStringBuf name, TStringBuf value) { - WriteLabel(name, value); - } - + private: + void WriteLabelsInner(TStringBuf name, TStringBuf value) { + WriteLabel(name, value); + } + template <typename... T> - void WriteLabelsInner(TStringBuf name, TStringBuf value, T... pairs) { - WriteLabel(name, value); - WriteLabelsInner(pairs...); - } - - inline void TransitionState(EState current, EState next); - }; + void WriteLabelsInner(TStringBuf name, TStringBuf value, T... pairs) { + WriteLabel(name, value); + WriteLabelsInner(pairs...); + } + + inline void TransitionState(EState current, EState next); + }; } diff --git a/library/cpp/monlib/deprecated/json/writer_ut.cpp b/library/cpp/monlib/deprecated/json/writer_ut.cpp index cd5c4e4d78..1f9fc8f393 100644 --- a/library/cpp/monlib/deprecated/json/writer_ut.cpp +++ b/library/cpp/monlib/deprecated/json/writer_ut.cpp @@ -1,32 +1,32 @@ #include "writer.h" #include <library/cpp/testing/unittest/registar.h> - + using namespace NMonitoring; - + Y_UNIT_TEST_SUITE(JsonWriterTests) { Y_UNIT_TEST(One) { - TStringStream ss; + TStringStream ss; TDeprecatedJsonWriter w(&ss); - w.OpenDocument(); + w.OpenDocument(); w.OpenMetrics(); - - for (int i = 0; i < 5; ++i) { + + for (int i = 0; i < 5; ++i) { w.OpenMetric(); - w.OpenLabels(); + w.OpenLabels(); w.WriteLabel("user", TString("") + (char)('a' + i)); w.WriteLabel("name", "NWrites"); - w.CloseLabels(); - if (i % 2 == 0) { - w.WriteModeDeriv(); - } - w.WriteValue(10l); + w.CloseLabels(); + if (i % 2 == 0) { + w.WriteModeDeriv(); + } + w.WriteValue(10l); w.CloseMetric(); - } - + } + w.CloseMetrics(); - w.CloseDocument(); - - //Cout << ss.Str() << "\n"; - } -} + w.CloseDocument(); + + //Cout << ss.Str() << "\n"; + } +} diff --git a/library/cpp/monlib/deprecated/json/ya.make b/library/cpp/monlib/deprecated/json/ya.make index cf49d7367b..0ca903ee62 100644 --- a/library/cpp/monlib/deprecated/json/ya.make +++ b/library/cpp/monlib/deprecated/json/ya.make @@ -1,26 +1,26 @@ -LIBRARY() - +LIBRARY() + # Deprecated writer of Solomon JSON format -# https://wiki.yandex-team.ru/solomon/api/dataformat/json +# https://wiki.yandex-team.ru/solomon/api/dataformat/json # # This writer will be deleted soon, so please consider to use # high level library library/cpp/monlib/encode which is decoupled from the # particular format. - + OWNER( jamel g:solomon ) - + SRCS( writer.h writer.cpp ) -PEERDIR( +PEERDIR( library/cpp/json -) - -END() +) + +END() RECURSE_FOR_TESTS(ut) diff --git a/library/cpp/monlib/dynamic_counters/counters.cpp b/library/cpp/monlib/dynamic_counters/counters.cpp index 8a73c388eb..3635d87d0d 100644 --- a/library/cpp/monlib/dynamic_counters/counters.cpp +++ b/library/cpp/monlib/dynamic_counters/counters.cpp @@ -2,10 +2,10 @@ #include <library/cpp/monlib/service/pages/templates.h> -#include <util/generic/cast.h> - -using namespace NMonitoring; - +#include <util/generic/cast.h> + +using namespace NMonitoring; + namespace { TDynamicCounters* AsDynamicCounters(const TIntrusivePtr<TCountableBase>& ptr) { return dynamic_cast<TDynamicCounters*>(ptr.Get()); @@ -53,7 +53,7 @@ TDynamicCounters::TDynamicCounters(EVisibility vis) TDynamicCounters::~TDynamicCounters() { } - + TDynamicCounters::TCounterPtr TDynamicCounters::GetExpiringCounter(const TString& value, bool derivative, EVisibility vis) { return GetExpiringNamedCounter("sensor", value, derivative, vis); } @@ -68,8 +68,8 @@ TDynamicCounters::TCounterPtr TDynamicCounters::GetCounter(const TString& value, TDynamicCounters::TCounterPtr TDynamicCounters::GetNamedCounter(const TString& name, const TString& value, bool derivative, EVisibility vis) { return AsCounterRef(GetNamedCounterImpl<false, TCounterForPtr>(name, value, derivative, vis)); -} - +} + THistogramPtr TDynamicCounters::GetHistogram(const TString& value, IHistogramCollectorPtr collector, bool derivative, EVisibility vis) { return GetNamedHistogram("sensor", value, std::move(collector), derivative, vis); } @@ -126,7 +126,7 @@ TIntrusivePtr<TDynamicCounters> TDynamicCounters::GetSubgroup(const TString& nam } } return res; -} +} TIntrusivePtr<TDynamicCounters> TDynamicCounters::FindSubgroup(const TString& name, const TString& value) const { TReadGuard g(Lock); @@ -186,7 +186,7 @@ void TDynamicCounters::RegisterSubgroup(const TString& name, const TString& valu void TDynamicCounters::OutputHtml(IOutputStream& os) const { HTML(os) { PRE() { - OutputPlainText(os); + OutputPlainText(os); } } } @@ -199,7 +199,7 @@ void TDynamicCounters::EnumerateSubgroups(const std::function<void(const TString } } } - + void TDynamicCounters::OutputPlainText(IOutputStream& os, const TString& indent) const { auto snap = ReadSnapshot(); // mark private records in plain text output @@ -232,18 +232,18 @@ void TDynamicCounters::OutputPlainText(IOutputStream& os, const TString& indent) } os << ": " << snapshot->Value(i) << '\n'; } - } - } - + } + } + for (const auto& [key, value] : snap) { if (const auto subgroup = AsDynamicCounters(value)) { - os << "\n"; + os << "\n"; os << indent << key.LabelName << "=" << key.LabelValue << ":\n"; subgroup->OutputPlainText(os, indent + INDENT); - } - } -} - + } + } +} + void TDynamicCounters::Accept(const TString& labelName, const TString& labelValue, ICountableConsumer& consumer) const { if (!IsVisible(Visibility(), consumer.Visibility())) { return; diff --git a/library/cpp/monlib/dynamic_counters/counters.h b/library/cpp/monlib/dynamic_counters/counters.h index 548e92ef39..dc178cfbe0 100644 --- a/library/cpp/monlib/dynamic_counters/counters.h +++ b/library/cpp/monlib/dynamic_counters/counters.h @@ -1,5 +1,5 @@ -#pragma once - +#pragma once + #include <library/cpp/monlib/counters/counters.h> #include <library/cpp/monlib/metrics/histogram_collector.h> @@ -7,14 +7,14 @@ #include <library/cpp/containers/stack_vector/stack_vec.h> #include <util/generic/cast.h> -#include <util/generic/map.h> -#include <util/generic/ptr.h> +#include <util/generic/map.h> +#include <util/generic/ptr.h> #include <util/string/cast.h> #include <util/system/rwlock.h> #include <functional> - -namespace NMonitoring { + +namespace NMonitoring { struct TCounterForPtr; struct TDynamicCounters; struct ICountableConsumer; @@ -44,8 +44,8 @@ namespace NMonitoring { protected: EVisibility Visibility_{EVisibility::Unspecified}; - }; - + }; + inline bool IsVisible(TCountableBase::EVisibility myLevel, TCountableBase::EVisibility consumerLevel) { if (myLevel == TCountableBase::EVisibility::Private && consumerLevel != TCountableBase::EVisibility::Private) { @@ -114,8 +114,8 @@ namespace NMonitoring { using TDeprecatedCounter::operator-=; using TDeprecatedCounter::operator=; using TDeprecatedCounter::operator!; - }; - + }; + struct TExpiringCounter: public TCounterForPtr { explicit TExpiringCounter(bool derivative = false, EVisibility vis = EVisibility::Public) : TCounterForPtr{derivative} @@ -185,34 +185,34 @@ namespace NMonitoring { #pragma warning(pop) #endif - struct TDynamicCounters; - - typedef TIntrusivePtr<TDynamicCounters> TDynamicCounterPtr; - struct TDynamicCounters: public TCountableBase { - public: + struct TDynamicCounters; + + typedef TIntrusivePtr<TDynamicCounters> TDynamicCounterPtr; + struct TDynamicCounters: public TCountableBase { + public: using TCounterPtr = TIntrusivePtr<TCounterForPtr>; using TOnLookupPtr = void (*)(const char *methodName, const TString &name, const TString &value); - - private: + + private: TRWMutex Lock; TCounterPtr LookupCounter; // Counts lookups by name TOnLookupPtr OnLookup = nullptr; // Called on each lookup if not nullptr, intended for lightweight tracing. - - typedef TIntrusivePtr<TCountableBase> TCountablePtr; - - struct TChildId { + + typedef TIntrusivePtr<TCountableBase> TCountablePtr; + + struct TChildId { TString LabelName; TString LabelValue; TChildId() { } TChildId(const TString& labelName, const TString& labelValue) - : LabelName(labelName) - , LabelValue(labelValue) - { - } + : LabelName(labelName) + , LabelValue(labelValue) + { + } auto AsTuple() const { return std::make_tuple(std::cref(LabelName), std::cref(LabelValue)); - } + } friend bool operator <(const TChildId& x, const TChildId& y) { return x.AsTuple() < y.AsTuple(); } @@ -222,8 +222,8 @@ namespace NMonitoring { friend bool operator !=(const TChildId& x, const TChildId& y) { return x.AsTuple() != y.AsTuple(); } - }; - + }; + using TCounters = TMap<TChildId, TCountablePtr>; using TLabels = TVector<TChildId>; @@ -231,7 +231,7 @@ namespace NMonitoring { mutable TCounters Counters; mutable TAtomic ExpiringCount = 0; - public: + public: TDynamicCounters(TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public); TDynamicCounters(const TDynamicCounters *origin) @@ -240,7 +240,7 @@ namespace NMonitoring { {} ~TDynamicCounters() override; - + // This counter allows to track lookups by name within the whole subtree void SetLookupCounter(TCounterPtr lookupCounter) { TWriteGuard g(Lock); @@ -328,7 +328,7 @@ namespace NMonitoring { void RemoveCounter(const TString &value); void RemoveNamedCounter(const TString& name, const TString &value); - + TIntrusivePtr<TDynamicCounters> GetSubgroup(const TString& name, const TString& value); TIntrusivePtr<TDynamicCounters> FindSubgroup(const TString& name, const TString& value) const; void RemoveSubgroup(const TString& name, const TString& value); @@ -348,12 +348,12 @@ namespace NMonitoring { // mostly for debugging purposes -- use accept with encoder instead void OutputPlainText(IOutputStream& os, const TString& indent = "") const; - + void Accept( const TString& labelName, const TString& labelValue, ICountableConsumer& consumer) const override; - private: + private: TCounters Resign() { TCounters counters; TWriteGuard g(Lock); @@ -369,6 +369,6 @@ namespace NMonitoring { template <class TCounterType> TCountablePtr FindNamedCounterImpl(const TString& name, const TString& value) const; - }; - -} + }; + +} diff --git a/library/cpp/monlib/dynamic_counters/page.cpp b/library/cpp/monlib/dynamic_counters/page.cpp index 2ddc74bd88..5124a47bb3 100644 --- a/library/cpp/monlib/dynamic_counters/page.cpp +++ b/library/cpp/monlib/dynamic_counters/page.cpp @@ -1,14 +1,14 @@ #include "page.h" #include "encode.h" - + #include <library/cpp/monlib/service/pages/templates.h> #include <library/cpp/string_utils/quote/quote.h> #include <util/string/split.h> #include <util/system/tls.h> - -using namespace NMonitoring; - + +using namespace NMonitoring; + namespace { Y_POD_STATIC_THREAD(TDynamicCounters*) currentCounters(nullptr); @@ -74,10 +74,10 @@ void TDynamicCountersPage::Output(NMonitoring::IMonHttpRequest& request) { if (!format) { currentCounters = counters.Get(); - THtmlMonPage::Output(request); + THtmlMonPage::Output(request); currentCounters = nullptr; return; - } + } IOutputStream& out = request.Output(); if (*format == EFormat::JSON) { @@ -93,7 +93,7 @@ void TDynamicCountersPage::Output(NMonitoring::IMonHttpRequest& request) { auto encoder = CreateEncoder(&out, *format, visibility); counters->Accept(TString(), TString(), *encoder); out.Flush(); -} +} void TDynamicCountersPage::HandleAbsentSubgroup(IMonHttpRequest& request) { if (UnknownGroupPolicy == EUnknownGroupPolicy::Error) { @@ -110,7 +110,7 @@ void TDynamicCountersPage::BeforePre(IMonHttpRequest& request) { HTML(out) { DIV() { out << "<a href='" << request.GetPath() << "/json'>Counters as JSON</a>"; - out << " for <a href='https://wiki.yandex-team.ru/solomon/'>Solomon</a>"; + out << " for <a href='https://wiki.yandex-team.ru/solomon/'>Solomon</a>"; } H5() { @@ -131,10 +131,10 @@ void TDynamicCountersPage::BeforePre(IMonHttpRequest& request) { } } } - + void TDynamicCountersPage::OutputText(IOutputStream& out, IMonHttpRequest&) { currentCounters->OutputPlainText(out); -} +} void TDynamicCountersPage::SetUnknownGroupPolicy(EUnknownGroupPolicy value) { UnknownGroupPolicy = value; diff --git a/library/cpp/monlib/dynamic_counters/page.h b/library/cpp/monlib/dynamic_counters/page.h index c318ded739..1f0ef6a5ea 100644 --- a/library/cpp/monlib/dynamic_counters/page.h +++ b/library/cpp/monlib/dynamic_counters/page.h @@ -1,24 +1,24 @@ -#pragma once - +#pragma once + #include "counters.h" #include <library/cpp/monlib/service/pages/pre_mon_page.h> -#include <util/generic/ptr.h> - +#include <util/generic/ptr.h> + #include <functional> - -namespace NMonitoring { + +namespace NMonitoring { enum class EUnknownGroupPolicy { Error, // send 404 Ignore, // send 204 }; - struct TDynamicCountersPage: public TPreMonPage { + struct TDynamicCountersPage: public TPreMonPage { public: using TOutputCallback = std::function<void()>; - private: + private: const TIntrusivePtr<TDynamicCounters> Counters; TOutputCallback OutputCallback; EUnknownGroupPolicy UnknownGroupPolicy {EUnknownGroupPolicy::Error}; @@ -26,19 +26,19 @@ namespace NMonitoring { private: void HandleAbsentSubgroup(IMonHttpRequest& request); - public: + public: TDynamicCountersPage(const TString& path, const TString& title, TIntrusivePtr<TDynamicCounters> counters, TOutputCallback outputCallback = nullptr) : TPreMonPage(path, title) - , Counters(counters) + , Counters(counters) , OutputCallback(outputCallback) { } - + void Output(NMonitoring::IMonHttpRequest& request) override; - + void BeforePre(NMonitoring::IMonHttpRequest& request) override; void OutputText(IOutputStream& out, NMonitoring::IMonHttpRequest&) override; @@ -47,4 +47,4 @@ namespace NMonitoring { /// If set to Ignore, responds with 204 if the requested subgroup is not found void SetUnknownGroupPolicy(EUnknownGroupPolicy value); }; -} +} diff --git a/library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto b/library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto index 275903bd9e..fd23eb372b 100644 --- a/library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto +++ b/library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto @@ -1,37 +1,37 @@ import "google/protobuf/descriptor.proto"; - + package NMonProto; - + option java_package = "ru.yandex.monlib.proto"; option java_outer_classname = "MetricMetaProto"; - + enum EMetricType { GAUGE = 1; RATE = 2; -} - +} + enum EMemOnly { - DEFAULT = 0; - STORE = 1; - MEM_ONLY = 2; -} - + DEFAULT = 0; + STORE = 1; + MEM_ONLY = 2; +} + message TMetricMeta { optional EMetricType Type = 1; - optional bool Path = 2; - optional string Keys = 3; - optional bool MemOnly = 4; - optional bool IgnorePath = 5; + optional bool Path = 2; + optional string Keys = 3; + optional bool MemOnly = 4; + optional bool IgnorePath = 5; optional string CustomPath = 6; -} - -enum THistogramBase { - MICROSECOND = 3; - MILLISECOND = 6; - SECOND = 9; - MINUTE = 12; - HOUR = 15; -} +} + +enum THistogramBase { + MICROSECOND = 3; + MILLISECOND = 6; + SECOND = 9; + MINUTE = 12; + HOUR = 15; +} message THistogramEntry { optional uint64 Multiplier = 1; @@ -40,34 +40,34 @@ message THistogramEntry { message THistogram { optional THistogramBase Base = 1; - optional string BaseStr = 2; + optional string BaseStr = 2; repeated THistogramEntry Entries = 5; } - -// field of this type is recognized by Solomon + +// field of this type is recognized by Solomon message TExtraLabelMetrics { - optional string labelName = 1; - - message TValue { - optional string labelValue = 1; - // used only if != 0 - optional uint64 labelValueUint = 21; - - optional uint64 longValue = 2; - optional double doubleValue = 3; - optional THistogram histogramValue = 4; - + optional string labelName = 1; + + message TValue { + optional string labelValue = 1; + // used only if != 0 + optional uint64 labelValueUint = 21; + + optional uint64 longValue = 2; + optional double doubleValue = 3; + optional THistogram histogramValue = 4; + optional EMetricType type = 7; optional EMemOnly memOnly = 8; - optional bool dropHost = 9; - + optional bool dropHost = 9; + repeated TExtraLabelMetrics children = 17; - } - - repeated TValue values = 2; -} - -extend google.protobuf.FieldOptions { + } + + repeated TValue values = 2; +} + +extend google.protobuf.FieldOptions { optional TMetricMeta Metric = 1719; -} - +} + diff --git a/library/cpp/monlib/messagebus/mon_messagebus.cpp b/library/cpp/monlib/messagebus/mon_messagebus.cpp index 5d6c7b0214..355b4386cd 100644 --- a/library/cpp/monlib/messagebus/mon_messagebus.cpp +++ b/library/cpp/monlib/messagebus/mon_messagebus.cpp @@ -1,11 +1,11 @@ #include <library/cpp/messagebus/www/www.h> - -#include "mon_messagebus.h" - -using namespace NMonitoring; - + +#include "mon_messagebus.h" + +using namespace NMonitoring; + void TBusNgMonPage::Output(NMonitoring::IMonHttpRequest& request) { - NBus::TBusWww::TOptionalParams params; + NBus::TBusWww::TOptionalParams params; params.ParentLinks.push_back(NBus::TBusWww::TLink{"/", request.GetServiceTitle()}); BusWww->ServeHttp(request.Output(), request.GetParams(), params); -} +} diff --git a/library/cpp/monlib/messagebus/mon_messagebus.h b/library/cpp/monlib/messagebus/mon_messagebus.h index dbbc618d7b..e1fa73c69f 100644 --- a/library/cpp/monlib/messagebus/mon_messagebus.h +++ b/library/cpp/monlib/messagebus/mon_messagebus.h @@ -1,16 +1,16 @@ -#pragma once - +#pragma once + #include <library/cpp/messagebus/ybus.h> #include <library/cpp/messagebus/www/www.h> - + #include <library/cpp/monlib/service/pages/mon_page.h> - -namespace NMonitoring { + +namespace NMonitoring { template <class TBusSmth> class TBusSmthMonPage: public NMonitoring::IMonPage { private: TBusSmth* Smth; - + public: explicit TBusSmthMonPage(const TString& name, const TString& title, TBusSmth* smth) : IMonPage("msgbus/" + name, title) @@ -26,14 +26,14 @@ namespace NMonitoring { request.Output() << "</pre>"; } }; - + using TBusQueueMonPage = TBusSmthMonPage<NBus::TBusMessageQueue>; using TBusModuleMonPage = TBusSmthMonPage<NBus::TBusModule>; - + class TBusNgMonPage: public NMonitoring::IMonPage { public: TIntrusivePtr<NBus::TBusWww> BusWww; - + public: TBusNgMonPage() : IMonPage("messagebus", "MessageBus") diff --git a/library/cpp/monlib/messagebus/mon_service_messagebus.cpp b/library/cpp/monlib/messagebus/mon_service_messagebus.cpp index 34ea259033..4dd144ebe8 100644 --- a/library/cpp/monlib/messagebus/mon_service_messagebus.cpp +++ b/library/cpp/monlib/messagebus/mon_service_messagebus.cpp @@ -1,8 +1,8 @@ -#include "mon_service_messagebus.h" - -using namespace NMonitoring; - +#include "mon_service_messagebus.h" + +using namespace NMonitoring; + TMonServiceMessageBus::TMonServiceMessageBus(ui16 port, const TString& title) - : TMonService2(port, title) + : TMonService2(port, title) { } diff --git a/library/cpp/monlib/messagebus/mon_service_messagebus.h b/library/cpp/monlib/messagebus/mon_service_messagebus.h index d3e05886d4..fe791e8a9b 100644 --- a/library/cpp/monlib/messagebus/mon_service_messagebus.h +++ b/library/cpp/monlib/messagebus/mon_service_messagebus.h @@ -1,20 +1,20 @@ -#pragma once - +#pragma once + #include "mon_messagebus.h" #include <library/cpp/monlib/service/monservice.h> -#include <util/system/mutex.h> - -namespace NMonitoring { +#include <util/system/mutex.h> + +namespace NMonitoring { class TMonServiceMessageBus: public TMonService2 { private: TMutex Mtx; TIntrusivePtr<NMonitoring::TBusNgMonPage> BusNgMonPage; - + public: TMonServiceMessageBus(ui16 port, const TString& title); - + private: NBus::TBusWww* RegisterBusNgMonPage() { TGuard<TMutex> g(Mtx); @@ -24,20 +24,20 @@ namespace NMonitoring { } return BusNgMonPage->BusWww.Get(); } - + public: void RegisterClientSession(NBus::TBusClientSessionPtr clientSession) { RegisterBusNgMonPage()->RegisterClientSession(clientSession); - } - + } + void RegisterServerSession(NBus::TBusServerSessionPtr serverSession) { RegisterBusNgMonPage()->RegisterServerSession(serverSession); } - + void RegisterQueue(NBus::TBusMessageQueuePtr queue) { RegisterBusNgMonPage()->RegisterQueue(queue); } - + void RegisterModule(NBus::TBusModule* module) { RegisterBusNgMonPage()->RegisterModule(module); } diff --git a/library/cpp/monlib/messagebus/ya.make b/library/cpp/monlib/messagebus/ya.make index fb85222a61..a0b5362296 100644 --- a/library/cpp/monlib/messagebus/ya.make +++ b/library/cpp/monlib/messagebus/ya.make @@ -1,16 +1,16 @@ -LIBRARY() - +LIBRARY() + OWNER(g:solomon) - -SRCS( - mon_messagebus.cpp - mon_service_messagebus.cpp -) - -PEERDIR( + +SRCS( + mon_messagebus.cpp + mon_service_messagebus.cpp +) + +PEERDIR( library/cpp/messagebus library/cpp/messagebus/www library/cpp/monlib/dynamic_counters -) - -END() +) + +END() diff --git a/library/cpp/monlib/service/mon_service_http_request.cpp b/library/cpp/monlib/service/mon_service_http_request.cpp index b8d1d27b98..5d805631d9 100644 --- a/library/cpp/monlib/service/mon_service_http_request.cpp +++ b/library/cpp/monlib/service/mon_service_http_request.cpp @@ -1,8 +1,8 @@ #include "mon_service_http_request.h" -#include "monservice.h" - -using namespace NMonitoring; - +#include "monservice.h" + +using namespace NMonitoring; + IMonHttpRequest::~IMonHttpRequest() { } @@ -10,9 +10,9 @@ TMonService2HttpRequest::~TMonService2HttpRequest() { } TString TMonService2HttpRequest::GetServiceTitle() const { - return MonService->GetTitle(); -} - + return MonService->GetTitle(); +} + IOutputStream& TMonService2HttpRequest::Output() { return *Out; } diff --git a/library/cpp/monlib/service/mon_service_http_request.h b/library/cpp/monlib/service/mon_service_http_request.h index 8dd75044cf..b4f2f8f0c5 100644 --- a/library/cpp/monlib/service/mon_service_http_request.h +++ b/library/cpp/monlib/service/mon_service_http_request.h @@ -1,13 +1,13 @@ -#pragma once - +#pragma once + #include "service.h" -#include <util/stream/output.h> - -namespace NMonitoring { +#include <util/stream/output.h> + +namespace NMonitoring { class TMonService2; class IMonPage; - + // XXX: IHttpRequest is already taken struct IMonHttpRequest { virtual ~IMonHttpRequest(); @@ -40,12 +40,12 @@ namespace NMonitoring { IMonPage* const MonPage; const TString PathInfo; TMonService2HttpRequest* const Parent; - + TMonService2HttpRequest( IOutputStream* out, const IHttpRequest* httpRequest, - TMonService2* monService, IMonPage* monPage, + TMonService2* monService, IMonPage* monPage, const TString& pathInfo, - TMonService2HttpRequest* parent) + TMonService2HttpRequest* parent) : Out(out) , HttpRequest(httpRequest) , MonService(monService) @@ -54,9 +54,9 @@ namespace NMonitoring { , Parent(parent) { } - + ~TMonService2HttpRequest() override; - + IOutputStream& Output() override; HTTP_METHOD GetMethod() const override; TStringBuf GetPath() const override; @@ -67,7 +67,7 @@ namespace NMonitoring { TStringBuf GetPostContent() const override { return HttpRequest->GetPostContent(); } - + TStringBuf GetHeader(TStringBuf name) const override; TStringBuf GetCookie(TStringBuf name) const override; const THttpHeaders& GetHeaders() const override; @@ -86,5 +86,5 @@ namespace NMonitoring { TString GetServiceTitle() const override; }; - + } diff --git a/library/cpp/monlib/service/monservice.cpp b/library/cpp/monlib/service/monservice.cpp index 49a1c941e4..d1b9cda1d2 100644 --- a/library/cpp/monlib/service/monservice.cpp +++ b/library/cpp/monlib/service/monservice.cpp @@ -1,17 +1,17 @@ -#include "monservice.h" +#include "monservice.h" #include <library/cpp/malloc/api/malloc.h> #include <library/cpp/string_utils/base64/base64.h> #include <library/cpp/svnversion/svnversion.h> -#include <util/generic/map.h> +#include <util/generic/map.h> #include <util/generic/ptr.h> -#include <util/system/hostname.h> +#include <util/system/hostname.h> #include <google/protobuf/text_format.h> - -using namespace NMonitoring; - + +using namespace NMonitoring; + TMonService2::TMonService2(ui16 port, const TString& host, ui32 threads, const TString& title, THolder<IAuthProvider> auth) : TMonService2(HttpServerOptions(port, host, threads), title, std::move(auth)) { @@ -19,15 +19,15 @@ TMonService2::TMonService2(ui16 port, const TString& host, ui32 threads, const T TMonService2::TMonService2(const THttpServerOptions& options, const TString& title, THolder<IAuthProvider> auth) : NMonitoring::TMtHttpServer(options, std::bind(&TMonService2::ServeRequest, this, std::placeholders::_1, std::placeholders::_2)) - , Title(title) - , IndexMonPage(new TIndexMonPage("", Title)) + , Title(title) + , IndexMonPage(new TIndexMonPage("", Title)) , AuthProvider_{std::move(auth)} -{ +{ Y_VERIFY(!!title); time_t t = time(nullptr); - ctime_r(&t, StartTime); -} - + ctime_r(&t, StartTime); +} + TMonService2::TMonService2(const THttpServerOptions& options, TSimpleSharedPtr<IThreadPool> pool, const TString& title, THolder<IAuthProvider> auth) : NMonitoring::TMtHttpServer(options, std::bind(&TMonService2::ServeRequest, this, std::placeholders::_1, std::placeholders::_2), std::move(pool)) , Title(title) @@ -50,33 +50,33 @@ TMonService2::TMonService2(ui16 port, const TString& title, THolder<IAuthProvide } void TMonService2::OutputIndex(IOutputStream& out) { - IndexMonPage->OutputIndex(out, true); -} - + IndexMonPage->OutputIndex(out, true); +} + void TMonService2::OutputIndexPage(IOutputStream& out) { - out << HTTPOKHTML; - out << "<html>\n"; - IndexMonPage->OutputHead(out); - OutputIndexBody(out); - out << "</html>\n"; -} - + out << HTTPOKHTML; + out << "<html>\n"; + IndexMonPage->OutputHead(out); + OutputIndexBody(out); + out << "</html>\n"; +} + void TMonService2::OutputIndexBody(IOutputStream& out) { - out << "<body>\n"; - - // part of common navbar - out << "<ol class='breadcrumb'>\n"; - out << "<li class='active'>" << Title << "</li>\n"; - out << "</ol>\n"; - - out << "<div class='container'>\n" - << "<h2>" << Title << "</h2>\n"; - OutputIndex(out); - out - << "<div>\n" - << "</body>\n"; -} - + out << "<body>\n"; + + // part of common navbar + out << "<ol class='breadcrumb'>\n"; + out << "<li class='active'>" << Title << "</li>\n"; + out << "</ol>\n"; + + out << "<div class='container'>\n" + << "<h2>" << Title << "</h2>\n"; + OutputIndex(out); + out + << "<div>\n" + << "</body>\n"; +} + void TMonService2::ServeRequest(IOutputStream& out, const NMonitoring::IHttpRequest& request) { TString path = request.GetPath(); Y_VERIFY(path.StartsWith('/')); @@ -95,34 +95,34 @@ void TMonService2::ServeRequest(IOutputStream& out, const NMonitoring::IHttpRequ } } - if (path == "/") { - OutputIndexPage(out); - } else { - TMonService2HttpRequest monService2HttpRequest( + if (path == "/") { + OutputIndexPage(out); + } else { + TMonService2HttpRequest monService2HttpRequest( &out, &request, this, IndexMonPage.Get(), path, nullptr); - IndexMonPage->Output(monService2HttpRequest); - } -} - + IndexMonPage->Output(monService2HttpRequest); + } +} + void TMonService2::Register(IMonPage* page) { - IndexMonPage->Register(page); -} - + IndexMonPage->Register(page); +} + void TMonService2::Register(TMonPagePtr page) { IndexMonPage->Register(std::move(page)); } TIndexMonPage* TMonService2::RegisterIndexPage(const TString& path, const TString& title) { return IndexMonPage->RegisterIndexPage(path, title); -} - +} + IMonPage* TMonService2::FindPage(const TString& relativePath) { - return IndexMonPage->FindPage(relativePath); -} - + return IndexMonPage->FindPage(relativePath); +} + TIndexMonPage* TMonService2::FindIndexPage(const TString& relativePath) { - return IndexMonPage->FindIndexPage(relativePath); -} + return IndexMonPage->FindIndexPage(relativePath); +} void TMonService2::SortPages() { IndexMonPage->SortPages(); diff --git a/library/cpp/monlib/service/monservice.h b/library/cpp/monlib/service/monservice.h index 288c6089a1..8f5e52fcdb 100644 --- a/library/cpp/monlib/service/monservice.h +++ b/library/cpp/monlib/service/monservice.h @@ -1,5 +1,5 @@ -#pragma once - +#pragma once + #include "service.h" #include "auth.h" #include "mon_service_http_request.h" @@ -7,18 +7,18 @@ #include <library/cpp/monlib/service/pages/index_mon_page.h> #include <library/cpp/monlib/service/pages/mon_page.h> -#include <util/system/progname.h> +#include <util/system/progname.h> #include <functional> - -namespace NMonitoring { + +namespace NMonitoring { class TMonService2: public TMtHttpServer { protected: const TString Title; char StartTime[26]; TIntrusivePtr<TIndexMonPage> IndexMonPage; THolder<IAuthProvider> AuthProvider_; - + public: static THttpServerOptions HttpServerOptions(ui16 port, const TString& host, ui32 threads) { THttpServerOptions opts(port); @@ -32,7 +32,7 @@ namespace NMonitoring { opts.EnableRejectExcessConnections(true); return opts; } - + static THttpServerOptions HttpServerOptions(ui16 port, ui32 threads) { return HttpServerOptions(port, TString(), threads); } @@ -43,31 +43,31 @@ namespace NMonitoring { explicit TMonService2(ui16 port, const TString& host, ui32 threads, const TString& title = GetProgramName(), THolder<IAuthProvider> auth = nullptr); explicit TMonService2(const THttpServerOptions& options, const TString& title = GetProgramName(), THolder<IAuthProvider> auth = nullptr); explicit TMonService2(const THttpServerOptions& options, TSimpleSharedPtr<IThreadPool> pool, const TString& title = GetProgramName(), THolder<IAuthProvider> auth = nullptr); - + ~TMonService2() override { } - + const char* GetStartTime() const { return StartTime; } - + const TString& GetTitle() const { return Title; } - + virtual void ServeRequest(IOutputStream& out, const NMonitoring::IHttpRequest& request); virtual void OutputIndex(IOutputStream& out); virtual void OutputIndexPage(IOutputStream& out); virtual void OutputIndexBody(IOutputStream& out); - + void Register(IMonPage* page); void Register(TMonPagePtr page); TIndexMonPage* RegisterIndexPage(const TString& path, const TString& title); - + IMonPage* FindPage(const TString& relativePath); TIndexMonPage* FindIndexPage(const TString& relativePath); void SortPages(); }; - + } diff --git a/library/cpp/monlib/service/pages/diag_mon_page.cpp b/library/cpp/monlib/service/pages/diag_mon_page.cpp index cf073e9224..2493ff4fba 100644 --- a/library/cpp/monlib/service/pages/diag_mon_page.cpp +++ b/library/cpp/monlib/service/pages/diag_mon_page.cpp @@ -1,9 +1,9 @@ -#include "diag_mon_page.h" - -using namespace NMonitoring; - +#include "diag_mon_page.h" + +using namespace NMonitoring; + void TDiagMonPage::OutputText(IOutputStream& out, NMonitoring::IMonHttpRequest& request) { out << "uri: " << request.GetUri() << "\n"; out << "path: " << request.GetPath() << "\n"; out << "path info: " << request.GetPathInfo() << "\n"; -} +} diff --git a/library/cpp/monlib/service/pages/diag_mon_page.h b/library/cpp/monlib/service/pages/diag_mon_page.h index bb16711700..761194d4ec 100644 --- a/library/cpp/monlib/service/pages/diag_mon_page.h +++ b/library/cpp/monlib/service/pages/diag_mon_page.h @@ -1,16 +1,16 @@ -#pragma once - -#include "pre_mon_page.h" - -namespace NMonitoring { +#pragma once + +#include "pre_mon_page.h" + +namespace NMonitoring { // internal diagnostics page struct TDiagMonPage: public TPreMonPage { TDiagMonPage() : TPreMonPage("diag", "Diagnostics Page") { } - + void OutputText(IOutputStream& out, NMonitoring::IMonHttpRequest&) override; }; - + } diff --git a/library/cpp/monlib/service/pages/html_mon_page.cpp b/library/cpp/monlib/service/pages/html_mon_page.cpp index 7b2a7cb135..eb4eb3b66c 100644 --- a/library/cpp/monlib/service/pages/html_mon_page.cpp +++ b/library/cpp/monlib/service/pages/html_mon_page.cpp @@ -1,20 +1,20 @@ -#include "html_mon_page.h" - +#include "html_mon_page.h" + #include <library/cpp/monlib/service/pages/templates.h> - -using namespace NMonitoring; - + +using namespace NMonitoring; + void THtmlMonPage::Output(NMonitoring::IMonHttpRequest& request) { IOutputStream& out = request.Output(); - out << HTTPOKHTML; + out << HTTPOKHTML; HTML(out) { - out << "<!DOCTYPE html>\n"; + out << "<!DOCTYPE html>\n"; HTML_TAG() { HEAD() { - if (!!Title) { - out << "<title>" << Title << "</title>\n"; - } + if (!!Title) { + out << "<title>" << Title << "</title>\n"; + } out << "<link rel='stylesheet' href='https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css'>\n"; out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/jquery/2.1.3/jquery.min.js'></script>\n"; out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js'></script>\n"; @@ -35,17 +35,17 @@ void THtmlMonPage::Output(NMonitoring::IMonHttpRequest& request) { } BODY() { OutputNavBar(out); - + DIV_CLASS("container") { - if (!!Title) { - out << "<h2>" << Title << "</h2>"; - } - OutputContent(request); + if (!!Title) { + out << "<h2>" << Title << "</h2>"; + } + OutputContent(request); } } } } -} +} void THtmlMonPage::NotFound(NMonitoring::IMonHttpRequest& request) const { IOutputStream& out = request.Output(); diff --git a/library/cpp/monlib/service/pages/html_mon_page.h b/library/cpp/monlib/service/pages/html_mon_page.h index a3e260866e..e87c53b62b 100644 --- a/library/cpp/monlib/service/pages/html_mon_page.h +++ b/library/cpp/monlib/service/pages/html_mon_page.h @@ -1,8 +1,8 @@ -#pragma once - -#include "mon_page.h" - -namespace NMonitoring { +#pragma once + +#include "mon_page.h" + +namespace NMonitoring { struct THtmlMonPage: public IMonPage { THtmlMonPage(const TString& path, const TString& title = TString(), @@ -11,9 +11,9 @@ namespace NMonitoring { , OutputTableSorterJsCss(outputTableSorterJsCss) { } - + void Output(NMonitoring::IMonHttpRequest& request) override; - + void NotFound(NMonitoring::IMonHttpRequest& request) const; void NoContent(NMonitoring::IMonHttpRequest& request) const; @@ -21,5 +21,5 @@ namespace NMonitoring { bool OutputTableSorterJsCss; }; - + } diff --git a/library/cpp/monlib/service/pages/index_mon_page.cpp b/library/cpp/monlib/service/pages/index_mon_page.cpp index 108c1945cd..83ff8b529a 100644 --- a/library/cpp/monlib/service/pages/index_mon_page.cpp +++ b/library/cpp/monlib/service/pages/index_mon_page.cpp @@ -1,72 +1,72 @@ #include "index_mon_page.h" -#include <util/generic/cast.h> +#include <util/generic/cast.h> #include <util/string/ascii.h> - -using namespace NMonitoring; - + +using namespace NMonitoring; + void TIndexMonPage::OutputIndexPage(IMonHttpRequest& request) { request.Output() << HTTPOKHTML; request.Output() << "<html>\n"; OutputHead(request.Output()); - OutputBody(request); + OutputBody(request); request.Output() << "</html>\n"; -} - +} + void TIndexMonPage::Output(IMonHttpRequest& request) { TStringBuf pathInfo = request.GetPathInfo(); if (pathInfo.empty() || pathInfo == TStringBuf("/")) { - OutputIndexPage(request); - return; - } - + OutputIndexPage(request); + return; + } + Y_VERIFY(pathInfo.StartsWith('/')); - - TMonPagePtr found; - // analogous to CGI PATH_INFO - { - TGuard<TMutex> g(Mtx); + + TMonPagePtr found; + // analogous to CGI PATH_INFO + { + TGuard<TMutex> g(Mtx); TStringBuf pathTmp = request.GetPathInfo(); - for (;;) { - TPagesByPath::iterator i = PagesByPath.find(pathTmp); - if (i != PagesByPath.end()) { - found = i->second; + for (;;) { + TPagesByPath::iterator i = PagesByPath.find(pathTmp); + if (i != PagesByPath.end()) { + found = i->second; pathInfo = request.GetPathInfo().substr(pathTmp.size()); Y_VERIFY(pathInfo.empty() || pathInfo.StartsWith('/')); - break; - } - size_t slash = pathTmp.find_last_of('/'); + break; + } + size_t slash = pathTmp.find_last_of('/'); Y_VERIFY(slash != TString::npos); - pathTmp = pathTmp.substr(0, slash); - if (!pathTmp) { - break; - } - } - } + pathTmp = pathTmp.substr(0, slash); + if (!pathTmp) { + break; + } + } + } if (found) { THolder<IMonHttpRequest> child(request.MakeChild(found.Get(), TString{pathInfo})); found->Output(*child); - } else { + } else { request.Output() << HTTPNOTFOUND; - } -} - + } +} + void TIndexMonPage::OutputIndex(IOutputStream& out, bool pathEndsWithSlash) { - TGuard<TMutex> g(Mtx); + TGuard<TMutex> g(Mtx); for (auto& Page : Pages) { IMonPage* page = Page.Get(); - if (page->IsInIndex()) { + if (page->IsInIndex()) { TString pathToDir = ""; - if (!pathEndsWithSlash) { - pathToDir = this->GetPath() + "/"; - } - out << "<a href='" << pathToDir << page->GetPath() << "'>" << page->GetTitle() << "</a><br/>\n"; - } - } -} - + if (!pathEndsWithSlash) { + pathToDir = this->GetPath() + "/"; + } + out << "<a href='" << pathToDir << page->GetPath() << "'>" << page->GetTitle() << "</a><br/>\n"; + } + } +} + void TIndexMonPage::Register(TMonPagePtr page) { - TGuard<TMutex> g(Mtx); + TGuard<TMutex> g(Mtx); auto insres = PagesByPath.insert(std::make_pair("/" + page->GetPath(), page)); if (insres.second) { // new unique page just inserted, update Pages @@ -81,8 +81,8 @@ void TIndexMonPage::Register(TMonPagePtr page) { insres.first->second = page; } page->Parent = this; -} - +} + TIndexMonPage* TIndexMonPage::RegisterIndexPage(const TString& path, const TString& title) { TGuard<TMutex> g(Mtx); TIndexMonPage* page = VerifyDynamicCast<TIndexMonPage*>(FindPage(path)); @@ -92,50 +92,50 @@ TIndexMonPage* TIndexMonPage::RegisterIndexPage(const TString& path, const TStri page = new TIndexMonPage(path, title); Register(page); return VerifyDynamicCast<TIndexMonPage*>(page); -} - +} + IMonPage* TIndexMonPage::FindPage(const TString& relativePath) { - TGuard<TMutex> g(Mtx); - + TGuard<TMutex> g(Mtx); + Y_VERIFY(!relativePath.StartsWith('/')); - TPagesByPath::iterator i = PagesByPath.find("/" + relativePath); - if (i == PagesByPath.end()) { + TPagesByPath::iterator i = PagesByPath.find("/" + relativePath); + if (i == PagesByPath.end()) { return nullptr; - } else { - return i->second.Get(); - } -} - + } else { + return i->second.Get(); + } +} + TIndexMonPage* TIndexMonPage::FindIndexPage(const TString& relativePath) { - return VerifyDynamicCast<TIndexMonPage*>(FindPage(relativePath)); -} - + return VerifyDynamicCast<TIndexMonPage*>(FindPage(relativePath)); +} + void TIndexMonPage::OutputCommonJsCss(IOutputStream& out) { out << "<link rel='stylesheet' href='https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css'>\n"; out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/jquery/2.1.3/jquery.min.js'></script>\n"; out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js'></script>\n"; -} - +} + void TIndexMonPage::OutputHead(IOutputStream& out) { - out << "<head>\n"; - OutputCommonJsCss(out); - out << "<title>" << Title << "</title>\n"; - out << "</head>\n"; -} - + out << "<head>\n"; + OutputCommonJsCss(out); + out << "<title>" << Title << "</title>\n"; + out << "</head>\n"; +} + void TIndexMonPage::OutputBody(IMonHttpRequest& req) { auto& out = req.Output(); out << "<body>\n"; - - // part of common navbar + + // part of common navbar OutputNavBar(out); - + out << "<div class='container'>\n" << "<h2>" << Title << "</h2>\n"; OutputIndex(out, req.GetPathInfo().EndsWith('/')); out << "<div>\n" - << "</body>\n"; -} + << "</body>\n"; +} void TIndexMonPage::SortPages() { TGuard<TMutex> g(Mtx); diff --git a/library/cpp/monlib/service/pages/index_mon_page.h b/library/cpp/monlib/service/pages/index_mon_page.h index 9a1ff45145..bf514a3105 100644 --- a/library/cpp/monlib/service/pages/index_mon_page.h +++ b/library/cpp/monlib/service/pages/index_mon_page.h @@ -1,38 +1,38 @@ -#pragma once - -#include "mon_page.h" - -namespace NMonitoring { +#pragma once + +#include "mon_page.h" + +namespace NMonitoring { struct TIndexMonPage: public IMonPage { TMutex Mtx; typedef TVector<TMonPagePtr> TPages; TPages Pages; typedef THashMap<TString, TMonPagePtr> TPagesByPath; TPagesByPath PagesByPath; - + TIndexMonPage(const TString& path, const TString& title) : IMonPage(path, title) { } - + ~TIndexMonPage() override { } - + void Output(IMonHttpRequest& request) override; void OutputIndexPage(IMonHttpRequest& request); virtual void OutputIndex(IOutputStream& out, bool pathEndsWithSlash); virtual void OutputCommonJsCss(IOutputStream& out); void OutputHead(IOutputStream& out); void OutputBody(IMonHttpRequest& out); - + void Register(TMonPagePtr page); TIndexMonPage* RegisterIndexPage(const TString& path, const TString& title); IMonPage* FindPage(const TString& relativePath); TIndexMonPage* FindIndexPage(const TString& relativePath); - + void SortPages(); void ClearPages(); }; - + } diff --git a/library/cpp/monlib/service/pages/mon_page.cpp b/library/cpp/monlib/service/pages/mon_page.cpp index d5860f56b3..72033b1699 100644 --- a/library/cpp/monlib/service/pages/mon_page.cpp +++ b/library/cpp/monlib/service/pages/mon_page.cpp @@ -1,14 +1,14 @@ -#include "mon_page.h" - -using namespace NMonitoring; - +#include "mon_page.h" + +using namespace NMonitoring; + IMonPage::IMonPage(const TString& path, const TString& title) - : Path(path) - , Title(title) -{ + : Path(path) + , Title(title) +{ Y_VERIFY(!Path.StartsWith('/')); Y_VERIFY(!Path.EndsWith('/')); -} +} void IMonPage::OutputNavBar(IOutputStream& out) { TVector<const IMonPage*> parents; diff --git a/library/cpp/monlib/service/pages/mon_page.h b/library/cpp/monlib/service/pages/mon_page.h index 3d85131536..e396612bb0 100644 --- a/library/cpp/monlib/service/pages/mon_page.h +++ b/library/cpp/monlib/service/pages/mon_page.h @@ -1,12 +1,12 @@ -#pragma once - +#pragma once + #include <library/cpp/monlib/service/service.h> #include <library/cpp/monlib/service/mon_service_http_request.h> #include <util/generic/string.h> -#include <util/generic/ptr.h> - -namespace NMonitoring { +#include <util/generic/ptr.h> + +namespace NMonitoring { static const char HTTPOKTEXT[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/plain\r\nConnection: Close\r\n\r\n"; static const char HTTPOKBIN[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/octet-stream\r\nConnection: Close\r\n\r\n"; static const char HTTPOKHTML[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n"; @@ -19,48 +19,48 @@ namespace NMonitoring { static const char HTTPNOTFOUND[] = "HTTP/1.1 404 Invalid URI\r\nConnection: Close\r\n\r\nInvalid URL\r\n"; static const char HTTPUNAUTHORIZED[] = "HTTP/1.1 401 Unauthorized\r\nConnection: Close\r\n\r\nUnauthorized\r\n"; static const char HTTPFORBIDDEN[] = "HTTP/1.1 403 Forbidden\r\nConnection: Close\r\n\r\nForbidden\r\n"; - + // Fonts static const char HTTPOKFONTEOT[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/vnd.ms-fontobject\r\nConnection: Close\r\n\r\n"; static const char HTTPOKFONTTTF[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/x-font-ttf\r\nConnection: Close\r\n\r\n"; static const char HTTPOKFONTWOFF[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/font-woff\r\nConnection: Close\r\n\r\n"; static const char HTTPOKFONTWOFF2[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/font-woff2\r\nConnection: Close\r\n\r\n"; - + // Images static const char HTTPOKPNG[] = "HTTP/1.1 200 Ok\r\nContent-Type: image/png\r\nConnection: Close\r\n\r\n"; static const char HTTPOKSVG[] = "HTTP/1.1 200 Ok\r\nContent-Type: image/svg+xml\r\nConnection: Close\r\n\r\n"; class IMonPage; - + using TMonPagePtr = TIntrusivePtr<IMonPage>; - + class IMonPage: public TAtomicRefCount<IMonPage> { public: const TString Path; const TString Title; const IMonPage* Parent = nullptr; - + public: IMonPage(const TString& path, const TString& title = TString()); - + virtual ~IMonPage() { } - + void OutputNavBar(IOutputStream& out); virtual const TString& GetPath() const { return Path; } - + virtual const TString& GetTitle() const { return Title; } - + bool IsInIndex() const { return !Title.empty(); } - + virtual void Output(IMonHttpRequest& request) = 0; }; - -} + +} diff --git a/library/cpp/monlib/service/pages/pre_mon_page.cpp b/library/cpp/monlib/service/pages/pre_mon_page.cpp index c2244d559a..fc03a19b80 100644 --- a/library/cpp/monlib/service/pages/pre_mon_page.cpp +++ b/library/cpp/monlib/service/pages/pre_mon_page.cpp @@ -1,18 +1,18 @@ -#include "pre_mon_page.h" - -using namespace NMonitoring; - +#include "pre_mon_page.h" + +using namespace NMonitoring; + void TPreMonPage::OutputContent(NMonitoring::IMonHttpRequest& request) { auto& out = request.Output(); if (PreTag) { - BeforePre(request); + BeforePre(request); out << "<pre>\n"; OutputText(out, request); out << "</pre>\n"; } else { OutputText(out, request); } -} - +} + void TPreMonPage::BeforePre(NMonitoring::IMonHttpRequest&) { -} +} diff --git a/library/cpp/monlib/service/pages/pre_mon_page.h b/library/cpp/monlib/service/pages/pre_mon_page.h index e9cc871d8c..c9a923d39a 100644 --- a/library/cpp/monlib/service/pages/pre_mon_page.h +++ b/library/cpp/monlib/service/pages/pre_mon_page.h @@ -1,8 +1,8 @@ -#pragma once - -#include "html_mon_page.h" - -namespace NMonitoring { +#pragma once + +#include "html_mon_page.h" + +namespace NMonitoring { struct TPreMonPage: public THtmlMonPage { TPreMonPage(const TString& path, const TString& title = TString(), @@ -12,15 +12,15 @@ namespace NMonitoring { , PreTag(preTag) { } - + void OutputContent(NMonitoring::IMonHttpRequest& request) override; - + // hook to customize output virtual void BeforePre(NMonitoring::IMonHttpRequest& request); - + // put your text here virtual void OutputText(IOutputStream& out, NMonitoring::IMonHttpRequest&) = 0; - + const bool PreTag; }; diff --git a/library/cpp/monlib/service/pages/templates.cpp b/library/cpp/monlib/service/pages/templates.cpp index a155b3bab4..ece12bea71 100644 --- a/library/cpp/monlib/service/pages/templates.cpp +++ b/library/cpp/monlib/service/pages/templates.cpp @@ -1,9 +1,9 @@ #include "templates.h" namespace NMonitoring { - extern const char HtmlTag[] = "html"; - extern const char HeadTag[] = "head"; - extern const char BodyTag[] = "body"; + extern const char HtmlTag[] = "html"; + extern const char HeadTag[] = "head"; + extern const char BodyTag[] = "body"; extern const char DivTag[] = "div"; extern const char TableTag[] = "table"; extern const char TableHeadTag[] = "thead"; @@ -15,14 +15,14 @@ namespace NMonitoring { extern const char LabelTag[] = "label"; extern const char SpanTag[] = "span"; extern const char CaptionTag[] = "caption"; - extern const char PreTag[] = "pre"; + extern const char PreTag[] = "pre"; extern const char ParaTag[] = "p"; - extern const char H1Tag[] = "h1"; - extern const char H2Tag[] = "h2"; - extern const char H3Tag[] = "h3"; - extern const char H4Tag[] = "h4"; - extern const char H5Tag[] = "h5"; - extern const char H6Tag[] = "h6"; + extern const char H1Tag[] = "h1"; + extern const char H2Tag[] = "h2"; + extern const char H3Tag[] = "h3"; + extern const char H4Tag[] = "h4"; + extern const char H5Tag[] = "h5"; + extern const char H6Tag[] = "h6"; extern const char SmallTag[] = "small"; extern const char StrongTag[] = "strong"; extern const char ListTag[] = "li"; diff --git a/library/cpp/monlib/service/pages/templates.h b/library/cpp/monlib/service/pages/templates.h index 0c70fb8555..b4656f059f 100644 --- a/library/cpp/monlib/service/pages/templates.h +++ b/library/cpp/monlib/service/pages/templates.h @@ -19,7 +19,7 @@ #define TAG_CLASS_ID(name, cls, id) WITH_SCOPED(tmp, NMonitoring::name(__stream, cls, "", id)) #define TAG_CLASS_FOR(name, cls, for0) WITH_SCOPED(tmp, NMonitoring::name(__stream, cls, for0)) #define TAG_ATTRS(name, ...) WITH_SCOPED(tmp, NMonitoring::name(__stream, ##__VA_ARGS__)) - + #define HTML(str) WITH_SCOPED(__stream, NMonitoring::TOutputStreamRef(str)) #define HEAD() TAG(THead) @@ -54,7 +54,7 @@ #define PARA() TAG(TPara) #define PARA_CLASS(cls) TAG_CLASS(TPara, cls) - + #define H1() TAG(TH1) #define H1_CLASS(cls) TAG_CLASS(TH1, cls) #define H2() TAG(TH2) @@ -235,9 +235,9 @@ namespace NMonitoring { extern const char DTermTag[3]; extern const char DDescTag[3]; - typedef TTag<HtmlTag> THtml; - typedef TTag<HeadTag> THead; - typedef TTag<BodyTag> TBody; + typedef TTag<HtmlTag> THtml; + typedef TTag<HeadTag> THead; + typedef TTag<BodyTag> TBody; typedef TTag<DivTag> TDiv; typedef TTag<TableTag> TTable; typedef TTag<TableHeadTag> TTableHead; @@ -249,14 +249,14 @@ namespace NMonitoring { typedef TTag<LabelTag> TLabelC; typedef TTag<SpanTag> TSpanC; typedef TTag<CaptionTag> TCaption; - typedef TTag<PreTag> TPre; + typedef TTag<PreTag> TPre; typedef TTag<ParaTag> TPara; - typedef TTag<H1Tag> TH1; - typedef TTag<H2Tag> TH2; - typedef TTag<H3Tag> TH3; - typedef TTag<H4Tag> TH4; - typedef TTag<H5Tag> TH5; - typedef TTag<H6Tag> TH6; + typedef TTag<H1Tag> TH1; + typedef TTag<H2Tag> TH2; + typedef TTag<H3Tag> TH3; + typedef TTag<H4Tag> TH4; + typedef TTag<H5Tag> TH5; + typedef TTag<H6Tag> TH6; typedef TTag<SmallTag> TSMALL; typedef TTag<StrongTag> TSTRONG; typedef TTag<ListTag> TLIST; diff --git a/library/cpp/monlib/service/pages/version_mon_page.cpp b/library/cpp/monlib/service/pages/version_mon_page.cpp index 0afc042cc1..41e29417da 100644 --- a/library/cpp/monlib/service/pages/version_mon_page.cpp +++ b/library/cpp/monlib/service/pages/version_mon_page.cpp @@ -1,16 +1,16 @@ #include <library/cpp/svnversion/svnversion.h> #include <library/cpp/build_info/build_info.h> #include <library/cpp/malloc/api/malloc.h> - -#include "version_mon_page.h" - -using namespace NMonitoring; - + +#include "version_mon_page.h" + +using namespace NMonitoring; + void TVersionMonPage::OutputText(IOutputStream& out, NMonitoring::IMonHttpRequest&) { - const char* version = GetProgramSvnVersion(); - out << version; + const char* version = GetProgramSvnVersion(); + out << version; if (!TString(version).EndsWith("\n")) - out << "\n"; + out << "\n"; out << GetBuildInfo() << "\n\n"; - out << "linked with malloc: " << NMalloc::MallocInfo().Name << "\n"; -} + out << "linked with malloc: " << NMalloc::MallocInfo().Name << "\n"; +} diff --git a/library/cpp/monlib/service/pages/version_mon_page.h b/library/cpp/monlib/service/pages/version_mon_page.h index 2b342c679a..f7649947e4 100644 --- a/library/cpp/monlib/service/pages/version_mon_page.h +++ b/library/cpp/monlib/service/pages/version_mon_page.h @@ -1,15 +1,15 @@ -#pragma once - -#include "pre_mon_page.h" - -namespace NMonitoring { +#pragma once + +#include "pre_mon_page.h" + +namespace NMonitoring { struct TVersionMonPage: public TPreMonPage { TVersionMonPage(const TString& path = "ver", const TString& title = "Version") : TPreMonPage(path, title) { } - + void OutputText(IOutputStream& out, NMonitoring::IMonHttpRequest&) override; }; - + } diff --git a/library/cpp/monlib/ya.make b/library/cpp/monlib/ya.make index b0cd3d0149..9bd236d6fd 100644 --- a/library/cpp/monlib/ya.make +++ b/library/cpp/monlib/ya.make @@ -2,7 +2,7 @@ OWNER( g:solomon jamel ) - + RECURSE( consumers counters diff --git a/library/cpp/on_disk/chunks/chunked_helpers.cpp b/library/cpp/on_disk/chunks/chunked_helpers.cpp index 5d57b12050..b7adba2753 100644 --- a/library/cpp/on_disk/chunks/chunked_helpers.cpp +++ b/library/cpp/on_disk/chunks/chunked_helpers.cpp @@ -4,7 +4,7 @@ TBlob GetBlock(const TBlob& blob, size_t index) { TChunkedDataReader reader(blob); - if (index >= reader.GetBlocksCount()) + if (index >= reader.GetBlocksCount()) ythrow yexception() << "index " << index << " is >= than block count " << reader.GetBlocksCount(); size_t begin = (const char*)reader.GetBlock(index) - (const char*)blob.Data(); return blob.SubBlob(begin, begin + reader.GetBlockLen(index)); diff --git a/library/cpp/packers/packers.h b/library/cpp/packers/packers.h index f8dbb72777..1bde1b59aa 100644 --- a/library/cpp/packers/packers.h +++ b/library/cpp/packers/packers.h @@ -21,11 +21,11 @@ public: void PackLeaf(char*, const T&, size_t) const { } - size_t MeasureLeaf(const T&) const { + size_t MeasureLeaf(const T&) const { return 0; } - size_t SkipLeaf(const char*) const { + size_t SkipLeaf(const char*) const { return 0; } }; @@ -98,13 +98,13 @@ namespace NPackers { class TIntegralPacker { // can pack only integral types <= ui64 public: void UnpackLeaf(const char* p, T& t) const; - void PackLeaf(char* buffer, const T& data, size_t size) const; - size_t MeasureLeaf(const T& data) const; - size_t SkipLeaf(const char* p) const; + void PackLeaf(char* buffer, const T& data, size_t size) const; + size_t MeasureLeaf(const T& data) const; + size_t SkipLeaf(const char* p) const; }; template <> - inline size_t TIntegralPacker<ui64>::MeasureLeaf(const ui64& val) const { + inline size_t TIntegralPacker<ui64>::MeasureLeaf(const ui64& val) const { constexpr size_t MAX_SIZE = sizeof(ui64) + sizeof(ui64) / 8; ui64 value = val; @@ -118,7 +118,7 @@ namespace NPackers { } template <> - inline void TIntegralPacker<ui64>::PackLeaf(char* buffer, const ui64& val, size_t len) const { + inline void TIntegralPacker<ui64>::PackLeaf(char* buffer, const ui64& val, size_t len) const { ui64 value = val; int lenmask = 0; @@ -145,7 +145,7 @@ namespace NPackers { } template <> - inline size_t TIntegralPacker<ui64>::SkipLeaf(const char* p) const { + inline size_t TIntegralPacker<ui64>::SkipLeaf(const char* p) const { return SkipTable[(ui8)*p]; } @@ -183,17 +183,17 @@ namespace NPackers { template <class T> inline void TIntegralPacker<T>::PackLeaf(char* buffer, const T& data, size_t size) const { - TIntegralPacker<ui64>().PackLeaf(buffer, ConvertIntegral<T>(data), size); + TIntegralPacker<ui64>().PackLeaf(buffer, ConvertIntegral<T>(data), size); } template <class T> inline size_t TIntegralPacker<T>::MeasureLeaf(const T& data) const { - return TIntegralPacker<ui64>().MeasureLeaf(ConvertIntegral<T>(data)); + return TIntegralPacker<ui64>().MeasureLeaf(ConvertIntegral<T>(data)); } template <class T> inline size_t TIntegralPacker<T>::SkipLeaf(const char* p) const { - return TIntegralPacker<ui64>().SkipLeaf(p); + return TIntegralPacker<ui64>().SkipLeaf(p); } //------------------------------------------- @@ -257,14 +257,14 @@ namespace NPackers { void UnpackLeaf(const char* p, TStringType& t) const; void PackLeaf(char* buffer, const TStringType& data, size_t size) const; size_t MeasureLeaf(const TStringType& data) const; - size_t SkipLeaf(const char* p) const; + size_t SkipLeaf(const char* p) const; }; template <class TStringType> inline void TStringPacker<TStringType>::UnpackLeaf(const char* buf, TStringType& t) const { size_t len; TIntegralPacker<size_t>().UnpackLeaf(buf, len); - size_t start = TIntegralPacker<size_t>().SkipLeaf(buf); + size_t start = TIntegralPacker<size_t>().SkipLeaf(buf); t = TStringType((const typename TStringType::char_type*)(buf + start), len); } @@ -273,7 +273,7 @@ namespace NPackers { size_t len = str.size(); size_t lenChar = len * sizeof(typename TStringType::char_type); size_t start = size - lenChar; - TIntegralPacker<size_t>().PackLeaf(buf, len, TIntegralPacker<size_t>().MeasureLeaf(len)); + TIntegralPacker<size_t>().PackLeaf(buf, len, TIntegralPacker<size_t>().MeasureLeaf(len)); memcpy(buf + start, str.data(), lenChar); } diff --git a/library/cpp/packers/ut/packers_ut.cpp b/library/cpp/packers/ut/packers_ut.cpp index 7c83c34067..18ce2150d1 100644 --- a/library/cpp/packers/ut/packers_ut.cpp +++ b/library/cpp/packers/ut/packers_ut.cpp @@ -11,8 +11,8 @@ #include <util/generic/ptr.h> #include <util/generic/ylimits.h> -#include <util/folder/dirut.h> - +#include <util/folder/dirut.h> + #include <util/random/random.h> #include <util/string/hex.h> diff --git a/library/cpp/protobuf/util/is_equal.cpp b/library/cpp/protobuf/util/is_equal.cpp index 9a0e94b57e..227408006e 100644 --- a/library/cpp/protobuf/util/is_equal.cpp +++ b/library/cpp/protobuf/util/is_equal.cpp @@ -4,8 +4,8 @@ #include <google/protobuf/descriptor.h> #include <util/generic/yexception.h> -#include <util/string/cast.h> -#include <util/string/vector.h> +#include <util/string/cast.h> +#include <util/string/vector.h> namespace NProtoBuf { template <bool useDefault> @@ -19,7 +19,7 @@ namespace NProtoBuf { return value1 == value2; } }; - + template <bool useDefault> struct TCompareValue<FieldDescriptor::CPPTYPE_MESSAGE, useDefault> { static inline bool IsEqual(const Message* value1, const Message* value2, TVector<TString>* differentPath) { @@ -113,7 +113,7 @@ namespace NProtoBuf { const Descriptor* descr = m1.GetDescriptor(); if (descr != m2.GetDescriptor()) { return false; - } + } for (int i = 0; i < descr->field_count(); ++i) if (!IsEqualField<useDefault>(m1, m2, *descr->field(i), differentPath)) { return false; @@ -148,14 +148,14 @@ namespace NProtoBuf { const Descriptor* descr = m1.GetDescriptor(); if (descr != m2.GetDescriptor()) { return false; - } + } return IsEqualField<useDefault>(m1, m2, field, differentPath); } bool IsEqualField(const Message& m1, const Message& m2, const FieldDescriptor& field) { return IsEqualFieldImpl<false>(m1, m2, field, nullptr); - } - + } + bool IsEqualFieldDefault(const Message& m1, const Message& m2, const FieldDescriptor& field) { return IsEqualFieldImpl<true>(m1, m2, field, nullptr); } diff --git a/library/cpp/protobuf/util/is_equal.h b/library/cpp/protobuf/util/is_equal.h index b351b0e730..13c0aae63d 100644 --- a/library/cpp/protobuf/util/is_equal.h +++ b/library/cpp/protobuf/util/is_equal.h @@ -8,7 +8,7 @@ namespace google { class FieldDescriptor; } } - + namespace NProtoBuf { using ::google::protobuf::FieldDescriptor; using ::google::protobuf::Message; @@ -23,7 +23,7 @@ namespace NProtoBuf { bool IsEqual(const Message& m1, const Message& m2, TString* differentPath); bool IsEqualField(const Message& m1, const Message& m2, const FieldDescriptor& field); - + // Non-strict version: optional field without explicit value is compared // using its default value. bool IsEqualDefault(const Message& m1, const Message& m2); diff --git a/library/cpp/protobuf/util/is_equal_ut.cpp b/library/cpp/protobuf/util/is_equal_ut.cpp index 73c6e41a82..3ca4c90dd5 100644 --- a/library/cpp/protobuf/util/is_equal_ut.cpp +++ b/library/cpp/protobuf/util/is_equal_ut.cpp @@ -1,8 +1,8 @@ -#include "is_equal.h" +#include "is_equal.h" #include <library/cpp/protobuf/util/ut/sample_for_is_equal.pb.h> - + #include <library/cpp/testing/unittest/registar.h> - + #include <google/protobuf/descriptor.h> Y_UNIT_TEST_SUITE(ProtobufIsEqual) { @@ -18,37 +18,37 @@ Y_UNIT_TEST_SUITE(ProtobufIsEqual) { } Y_UNIT_TEST(IsEqual1) { - TSampleForIsEqual a; - TSampleForIsEqual b; - - a.SetName("aaa"); - b.SetName("bbb"); - + TSampleForIsEqual a; + TSampleForIsEqual b; + + a.SetName("aaa"); + b.SetName("bbb"); + TString path; - - bool equal = NProtoBuf::IsEqual(a, b, &path); - UNIT_ASSERT(!equal); - UNIT_ASSERT_VALUES_EQUAL("Name", path); + + bool equal = NProtoBuf::IsEqual(a, b, &path); + UNIT_ASSERT(!equal); + UNIT_ASSERT_VALUES_EQUAL("Name", path); UNIT_ASSERT(!NProtoBuf::IsEqualField(a, b, *NameDescr)); - } - + } + Y_UNIT_TEST(IsEqual2) { - TSampleForIsEqual a; - TSampleForIsEqual b; - - a.MutableInner()->SetBrbrbr("aaa"); - b.MutableInner()->SetBrbrbr("bbb"); - + TSampleForIsEqual a; + TSampleForIsEqual b; + + a.MutableInner()->SetBrbrbr("aaa"); + b.MutableInner()->SetBrbrbr("bbb"); + TString path; - - bool equal = NProtoBuf::IsEqual(a, b, &path); - UNIT_ASSERT(!equal); - UNIT_ASSERT_VALUES_EQUAL("Inner/Brbrbr", path); + + bool equal = NProtoBuf::IsEqual(a, b, &path); + UNIT_ASSERT(!equal); + UNIT_ASSERT_VALUES_EQUAL("Inner/Brbrbr", path); bool equalField = NProtoBuf::IsEqualField(a, b, *InnerDescr); UNIT_ASSERT(!equalField); - } + } Y_UNIT_TEST(IsEqual3) { TSampleForIsEqual a; @@ -85,4 +85,4 @@ Y_UNIT_TEST_SUITE(ProtobufIsEqual) { UNIT_ASSERT(!NProtoBuf::IsEqualField(a, b, *NameDescr)); UNIT_ASSERT(NProtoBuf::IsEqualFieldDefault(a, b, *NameDescr)); } -} +} diff --git a/library/cpp/protobuf/util/repeated_field_utils.h b/library/cpp/protobuf/util/repeated_field_utils.h index 9d53a797d8..c07bd84647 100644 --- a/library/cpp/protobuf/util/repeated_field_utils.h +++ b/library/cpp/protobuf/util/repeated_field_utils.h @@ -1,20 +1,20 @@ -#pragma once - +#pragma once + #include <google/protobuf/repeated_field.h> #include <util/generic/vector.h> - -template <typename T> -void RemoveRepeatedPtrFieldElement(google::protobuf::RepeatedPtrField<T>* repeated, unsigned index) { - google::protobuf::RepeatedPtrField<T> r; + +template <typename T> +void RemoveRepeatedPtrFieldElement(google::protobuf::RepeatedPtrField<T>* repeated, unsigned index) { + google::protobuf::RepeatedPtrField<T> r; Y_ASSERT(index < (unsigned)repeated->size()); for (unsigned i = 0; i < (unsigned)repeated->size(); ++i) { - if (i == index) { - continue; - } - r.Add()->Swap(repeated->Mutable(i)); - } - r.Swap(repeated); -} + if (i == index) { + continue; + } + r.Add()->Swap(repeated->Mutable(i)); + } + r.Swap(repeated); +} namespace NProtoBuf { /// Move item to specified position diff --git a/library/cpp/protobuf/util/ut/sample_for_is_equal.proto b/library/cpp/protobuf/util/ut/sample_for_is_equal.proto index d2257d7f6b..a91c16deaa 100644 --- a/library/cpp/protobuf/util/ut/sample_for_is_equal.proto +++ b/library/cpp/protobuf/util/ut/sample_for_is_equal.proto @@ -1,8 +1,8 @@ -message TInner { - optional string Brbrbr = 3; -} - -message TSampleForIsEqual { - optional string Name = 1; - optional TInner Inner = 5; -} +message TInner { + optional string Brbrbr = 3; +} + +message TSampleForIsEqual { + optional string Name = 1; + optional TInner Inner = 5; +} diff --git a/library/cpp/protobuf/util/ut/ya.make b/library/cpp/protobuf/util/ut/ya.make index be07c51347..701ba9a8c8 100644 --- a/library/cpp/protobuf/util/ut/ya.make +++ b/library/cpp/protobuf/util/ut/ya.make @@ -1,10 +1,10 @@ -OWNER(nga) - +OWNER(nga) + UNITTEST_FOR(library/cpp/protobuf/util) - -SRCS( + +SRCS( extensions.proto - sample_for_is_equal.proto + sample_for_is_equal.proto sample_for_simple_reflection.proto common_ut.proto pb_io_ut.cpp @@ -14,6 +14,6 @@ SRCS( repeated_field_utils_ut.cpp walk_ut.cpp merge_ut.cpp -) - -END() +) + +END() diff --git a/library/cpp/protobuf/util/ya.make b/library/cpp/protobuf/util/ya.make index ed47ab6f2a..b62028af58 100644 --- a/library/cpp/protobuf/util/ya.make +++ b/library/cpp/protobuf/util/ya.make @@ -16,7 +16,7 @@ SRCS( path.cpp pb_io.cpp pb_utils.h - repeated_field_utils.h + repeated_field_utils.h simple_reflection.cpp walk.cpp ) diff --git a/library/cpp/sighandler/async_signals_handler.cpp b/library/cpp/sighandler/async_signals_handler.cpp index ebe1eef9b6..00ce1c18fb 100644 --- a/library/cpp/sighandler/async_signals_handler.cpp +++ b/library/cpp/sighandler/async_signals_handler.cpp @@ -4,11 +4,11 @@ #if !defined(_win_) -#include <errno.h> +#include <errno.h> #include <fcntl.h> -#include <signal.h> +#include <signal.h> #include <string.h> - + #include <unistd.h> #if defined(_linux_) @@ -191,7 +191,7 @@ namespace { TAsyncSignalsHandler* SIGNALS_HANDLER = nullptr; } -void SetAsyncSignalHandler(int signum, TAutoPtr<TEventHandler> handler) { +void SetAsyncSignalHandler(int signum, TAutoPtr<TEventHandler> handler) { static TAtomic lock; if (Y_UNLIKELY(SIGNALS_HANDLER == nullptr)) { @@ -214,12 +214,12 @@ void SetAsyncSignalHandler(int, TAutoPtr<TEventHandler>) { #endif -namespace { +namespace { template <typename TFunc> class TFunctionEventHandler: public TEventHandler { TFunc Func; - public: + public: TFunctionEventHandler(TFunc func) { if (func) Func = func; @@ -230,14 +230,14 @@ namespace { Func(signum); } - return 0; - } - }; -} - -void SetAsyncSignalHandler(int signum, void (*handler)(int)) { + return 0; + } + }; +} + +void SetAsyncSignalHandler(int signum, void (*handler)(int)) { SetAsyncSignalHandler(signum, new TFunctionEventHandler<void (*)(int)>(handler)); -} +} void SetAsyncSignalFunction(int signum, std::function<void(int)> func) { typedef std::function<void(int)> TFunc; diff --git a/library/cpp/sighandler/async_signals_handler.h b/library/cpp/sighandler/async_signals_handler.h index a9f81fcd9d..da36365ace 100644 --- a/library/cpp/sighandler/async_signals_handler.h +++ b/library/cpp/sighandler/async_signals_handler.h @@ -1,14 +1,14 @@ #pragma once -#include <util/generic/ptr.h> +#include <util/generic/ptr.h> #include <functional> - + struct TEventHandler { virtual ~TEventHandler() { } virtual int Handle(int signum) = 0; }; -void SetAsyncSignalHandler(int signum, TAutoPtr<TEventHandler> handler); -void SetAsyncSignalHandler(int signum, void (*handler)(int)); +void SetAsyncSignalHandler(int signum, TAutoPtr<TEventHandler> handler); +void SetAsyncSignalHandler(int signum, void (*handler)(int)); void SetAsyncSignalFunction(int signum, std::function<void(int)> func); diff --git a/library/cpp/streams/lz/lz.h b/library/cpp/streams/lz/lz.h index 063828b1e9..3a2eaad88b 100644 --- a/library/cpp/streams/lz/lz.h +++ b/library/cpp/streams/lz/lz.h @@ -16,7 +16,7 @@ * See http://altdevblogaday.com/2011/04/22/survey-of-fast-compression-algorithms-part-1/ * for some comparisons. */ - + struct TDecompressorError: public yexception { }; diff --git a/library/cpp/string_utils/indent_text/indent_text.cpp b/library/cpp/string_utils/indent_text/indent_text.cpp index 07fc9d4200..09a4f6bca8 100644 --- a/library/cpp/string_utils/indent_text/indent_text.cpp +++ b/library/cpp/string_utils/indent_text/indent_text.cpp @@ -1,25 +1,25 @@ #include "indent_text.h" -#include <util/stream/str.h> - +#include <util/stream/str.h> + TString IndentText(TStringBuf text, TStringBuf indent) { - if (text.empty()) + if (text.empty()) return TString(); - - TStringStream ss; + + TStringStream ss; ss.Reserve(text.size() + 20); - - char pc = 0; - for (size_t i = 0; i < text.size(); ++i) { - if (i == 0 || pc == '\n') - ss << indent; - - char c = text.at(i); - ss << c; - pc = c; - } - if (pc != '\n') - ss << '\n'; - - return ss.Str(); -} + + char pc = 0; + for (size_t i = 0; i < text.size(); ++i) { + if (i == 0 || pc == '\n') + ss << indent; + + char c = text.at(i); + ss << c; + pc = c; + } + if (pc != '\n') + ss << '\n'; + + return ss.Str(); +} diff --git a/library/cpp/string_utils/indent_text/indent_text.h b/library/cpp/string_utils/indent_text/indent_text.h index 9951073e2a..7117d6c0ee 100644 --- a/library/cpp/string_utils/indent_text/indent_text.h +++ b/library/cpp/string_utils/indent_text/indent_text.h @@ -1,6 +1,6 @@ -#pragma once - +#pragma once + #include <util/generic/string.h> -#include <util/generic/strbuf.h> - +#include <util/generic/strbuf.h> + TString IndentText(TStringBuf text, TStringBuf indent = TStringBuf(" ")); diff --git a/library/cpp/string_utils/url/url_ut.cpp b/library/cpp/string_utils/url/url_ut.cpp index ca0ab74948..1588013893 100644 --- a/library/cpp/string_utils/url/url_ut.cpp +++ b/library/cpp/string_utils/url/url_ut.cpp @@ -3,18 +3,18 @@ #include <util/string/cast.h> #include <library/cpp/testing/unittest/registar.h> - + Y_UNIT_TEST_SUITE(TUtilUrlTest) { Y_UNIT_TEST(TestGetHostAndGetHostAndPort) { - UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHost("ya.ru/bebe")); + UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHost("ya.ru/bebe")); UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHostAndPort("ya.ru/bebe")); - UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHost("ya.ru")); + UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHost("ya.ru")); UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHostAndPort("ya.ru")); - UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHost("ya.ru:8080")); + UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHost("ya.ru:8080")); UNIT_ASSERT_VALUES_EQUAL("ya.ru:8080", GetHostAndPort("ya.ru:8080")); - UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHost("ya.ru/bebe:8080")); + UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHost("ya.ru/bebe:8080")); UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHostAndPort("ya.ru/bebe:8080")); - UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHost("ya.ru:8080/bebe")); + UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHost("ya.ru:8080/bebe")); UNIT_ASSERT_VALUES_EQUAL("ya.ru", GetHost("https://ya.ru:8080/bebe")); UNIT_ASSERT_VALUES_EQUAL("www.ya.ru", GetHost("www.ya.ru:8080/bebe")); UNIT_ASSERT_VALUES_EQUAL("www.ya.ru", GetHost("https://www.ya.ru:8080/bebe")); @@ -25,7 +25,7 @@ Y_UNIT_TEST_SUITE(TUtilUrlTest) { // check simple string UNIT_ASSERT_VALUES_EQUAL("some_blender_url", GetHost("some_blender_url")); UNIT_ASSERT_VALUES_EQUAL("", GetHost("")); - } + } Y_UNIT_TEST(TestGetPathAndQuery) { UNIT_ASSERT_VALUES_EQUAL("/", GetPathAndQuery("ru.wikipedia.org")); @@ -278,4 +278,4 @@ Y_UNIT_TEST_SUITE(TUtilUrlTest) { UNIT_ASSERT_VALUES_EQUAL(false, DoesUrlPathStartWithToken("http://bebe", "bebe")); UNIT_ASSERT_VALUES_EQUAL(false, DoesUrlPathStartWithToken("https://bebe/", "bebe")); } -} +} diff --git a/library/cpp/terminate_handler/sample/exception/main.cpp b/library/cpp/terminate_handler/sample/exception/main.cpp index e764101d0e..35bfae8874 100644 --- a/library/cpp/terminate_handler/sample/exception/main.cpp +++ b/library/cpp/terminate_handler/sample/exception/main.cpp @@ -1,15 +1,15 @@ -#include <util/generic/yexception.h> - - -void Foo(unsigned i = 0) { - if (i >= 10) { - ythrow yexception() << "from Foo()"; - } else { - Foo(i + 1); - } -} - -int main() { - Foo(); - return 0; -} +#include <util/generic/yexception.h> + + +void Foo(unsigned i = 0) { + if (i >= 10) { + ythrow yexception() << "from Foo()"; + } else { + Foo(i + 1); + } +} + +int main() { + Foo(); + return 0; +} diff --git a/library/cpp/terminate_handler/sample/exception/ya.make b/library/cpp/terminate_handler/sample/exception/ya.make index 077586fe14..958c26f89a 100644 --- a/library/cpp/terminate_handler/sample/exception/ya.make +++ b/library/cpp/terminate_handler/sample/exception/ya.make @@ -1,13 +1,13 @@ PROGRAM(exception_sample) - -OWNER(nga) - -SRCS( - main.cpp -) - -PEERDIR( + +OWNER(nga) + +SRCS( + main.cpp +) + +PEERDIR( library/cpp/terminate_handler -) - -END() +) + +END() diff --git a/library/cpp/terminate_handler/sample/pure-virtual/main.cpp b/library/cpp/terminate_handler/sample/pure-virtual/main.cpp index 6e9c9fbff4..58217d5f24 100644 --- a/library/cpp/terminate_handler/sample/pure-virtual/main.cpp +++ b/library/cpp/terminate_handler/sample/pure-virtual/main.cpp @@ -1,22 +1,22 @@ - -struct TFoo { - TFoo() { - Baz(); - } - - void Baz() { - Bar(); - } - - virtual void Bar() = 0; -}; - -struct TQux: public TFoo { + +struct TFoo { + TFoo() { + Baz(); + } + + void Baz() { + Bar(); + } + + virtual void Bar() = 0; +}; + +struct TQux: public TFoo { void Bar() override { } -}; - -int main() { - TQux(); - return 0; -} +}; + +int main() { + TQux(); + return 0; +} diff --git a/library/cpp/terminate_handler/sample/pure-virtual/ya.make b/library/cpp/terminate_handler/sample/pure-virtual/ya.make index 27ef18f3a0..4100da630d 100644 --- a/library/cpp/terminate_handler/sample/pure-virtual/ya.make +++ b/library/cpp/terminate_handler/sample/pure-virtual/ya.make @@ -1,13 +1,13 @@ -PROGRAM() - -OWNER(nga) - -SRCS( - main.cpp -) - -PEERDIR( +PROGRAM() + +OWNER(nga) + +SRCS( + main.cpp +) + +PEERDIR( library/cpp/terminate_handler -) - -END() +) + +END() diff --git a/library/cpp/terminate_handler/sample/rethrow/main.cpp b/library/cpp/terminate_handler/sample/rethrow/main.cpp index 57e0722a3d..fcd8592613 100644 --- a/library/cpp/terminate_handler/sample/rethrow/main.cpp +++ b/library/cpp/terminate_handler/sample/rethrow/main.cpp @@ -1,20 +1,20 @@ -#include <util/generic/yexception.h> - - -void Bar() { - ythrow yexception() << "from Foo()"; -} - -void Foo() { - try { - Bar(); - } catch (...) { - Cerr << "caught; rethrowing\n"; - throw; - } -} - -int main() { - Foo(); - return 0; -} +#include <util/generic/yexception.h> + + +void Bar() { + ythrow yexception() << "from Foo()"; +} + +void Foo() { + try { + Bar(); + } catch (...) { + Cerr << "caught; rethrowing\n"; + throw; + } +} + +int main() { + Foo(); + return 0; +} diff --git a/library/cpp/terminate_handler/sample/rethrow/ya.make b/library/cpp/terminate_handler/sample/rethrow/ya.make index 27ef18f3a0..4100da630d 100644 --- a/library/cpp/terminate_handler/sample/rethrow/ya.make +++ b/library/cpp/terminate_handler/sample/rethrow/ya.make @@ -1,13 +1,13 @@ -PROGRAM() - -OWNER(nga) - -SRCS( - main.cpp -) - -PEERDIR( +PROGRAM() + +OWNER(nga) + +SRCS( + main.cpp +) + +PEERDIR( library/cpp/terminate_handler -) - -END() +) + +END() diff --git a/library/cpp/terminate_handler/sample/segv/main.cpp b/library/cpp/terminate_handler/sample/segv/main.cpp index 0b29cc193e..52851bdb19 100644 --- a/library/cpp/terminate_handler/sample/segv/main.cpp +++ b/library/cpp/terminate_handler/sample/segv/main.cpp @@ -1,15 +1,15 @@ -#include "../../segv_handler.h" - -void Bar(int* x) { - *x = 11; -} - -void Foo(int* x) { - Bar(x); -} - -int main() { - InstallSegvHandler(); +#include "../../segv_handler.h" + +void Bar(int* x) { + *x = 11; +} + +void Foo(int* x) { + Bar(x); +} + +int main() { + InstallSegvHandler(); Foo((int*)1); - return 0; -} + return 0; +} diff --git a/library/cpp/terminate_handler/sample/segv/ya.make b/library/cpp/terminate_handler/sample/segv/ya.make index 27ef18f3a0..4100da630d 100644 --- a/library/cpp/terminate_handler/sample/segv/ya.make +++ b/library/cpp/terminate_handler/sample/segv/ya.make @@ -1,13 +1,13 @@ -PROGRAM() - -OWNER(nga) - -SRCS( - main.cpp -) - -PEERDIR( +PROGRAM() + +OWNER(nga) + +SRCS( + main.cpp +) + +PEERDIR( library/cpp/terminate_handler -) - -END() +) + +END() diff --git a/library/cpp/terminate_handler/sample/ya.make b/library/cpp/terminate_handler/sample/ya.make index f60f58e799..af089abc65 100644 --- a/library/cpp/terminate_handler/sample/ya.make +++ b/library/cpp/terminate_handler/sample/ya.make @@ -1,6 +1,6 @@ -RECURSE( +RECURSE( exception pure-virtual rethrow segv -) +) diff --git a/library/cpp/terminate_handler/segv_handler.cpp b/library/cpp/terminate_handler/segv_handler.cpp index fc720eff18..f24ece4125 100644 --- a/library/cpp/terminate_handler/segv_handler.cpp +++ b/library/cpp/terminate_handler/segv_handler.cpp @@ -1,34 +1,34 @@ -#include <util/system/platform.h> -#include <util/system/yassert.h> -#include <util/stream/output.h> -#include <util/system/backtrace.h> - -#ifdef _unix_ -#include <signal.h> -#include <errno.h> -#include <stdlib.h> +#include <util/system/platform.h> +#include <util/system/yassert.h> +#include <util/stream/output.h> +#include <util/system/backtrace.h> + +#ifdef _unix_ +#include <signal.h> +#include <errno.h> +#include <stdlib.h> #include <unistd.h> -#endif - -#include "segv_handler.h" - -#ifndef _win_ -static void SegvHandler(int sig) { +#endif + +#include "segv_handler.h" + +#ifndef _win_ +static void SegvHandler(int sig) { Y_UNUSED(sig); - const char msg[] = "Got SEGV\n"; + const char msg[] = "Got SEGV\n"; Y_UNUSED(write(STDERR_FILENO, msg, sizeof(msg))); - //PrintBackTrace(); - sig_t r = signal(SIGSEGV, SIG_DFL); - if (r == SIG_ERR) { - abort(); - } - // returning back and failing -} -#endif // !_win_ - -void InstallSegvHandler() { -#ifndef _win_ - sig_t r = signal(SIGSEGV, &SegvHandler); + //PrintBackTrace(); + sig_t r = signal(SIGSEGV, SIG_DFL); + if (r == SIG_ERR) { + abort(); + } + // returning back and failing +} +#endif // !_win_ + +void InstallSegvHandler() { +#ifndef _win_ + sig_t r = signal(SIGSEGV, &SegvHandler); Y_VERIFY(r != SIG_ERR, "signal failed: %s", strerror(errno)); -#endif // !_win_ -} +#endif // !_win_ +} diff --git a/library/cpp/terminate_handler/segv_handler.h b/library/cpp/terminate_handler/segv_handler.h index 5f53810460..c9f9051c7d 100644 --- a/library/cpp/terminate_handler/segv_handler.h +++ b/library/cpp/terminate_handler/segv_handler.h @@ -1,3 +1,3 @@ -#pragma once - -void InstallSegvHandler(); +#pragma once + +void InstallSegvHandler(); diff --git a/library/cpp/terminate_handler/terminate_handler.cpp b/library/cpp/terminate_handler/terminate_handler.cpp index 30f17ae4bf..d7e8fbed95 100644 --- a/library/cpp/terminate_handler/terminate_handler.cpp +++ b/library/cpp/terminate_handler/terminate_handler.cpp @@ -1,15 +1,15 @@ #include <cstdlib> -#include <exception> - -#include <util/stream/output.h> -#include <util/system/backtrace.h> -#include <util/generic/yexception.h> - +#include <exception> + +#include <util/stream/output.h> +#include <util/system/backtrace.h> +#include <util/generic/yexception.h> + namespace { // Avoid infinite recursion if std::terminate is triggered anew by the // FancyTerminateHandler. thread_local int TerminateCount = 0; - + void FancyTerminateHandler() { switch (++TerminateCount) { case 1: @@ -21,7 +21,7 @@ namespace { abort(); break; } - + if (std::current_exception()) { Cerr << "Uncaught exception: " << CurrentExceptionMessage() << '\n'; } else { @@ -29,8 +29,8 @@ namespace { } PrintBackTrace(); Cerr.Flush(); - abort(); - } - + abort(); + } + [[maybe_unused]] auto _ = std::set_terminate(&FancyTerminateHandler); -} +} diff --git a/library/cpp/terminate_handler/ya.make b/library/cpp/terminate_handler/ya.make index 40ca71a5cc..70a9712fed 100644 --- a/library/cpp/terminate_handler/ya.make +++ b/library/cpp/terminate_handler/ya.make @@ -1,13 +1,13 @@ -LIBRARY() - +LIBRARY() + OWNER( ilnurkh eeight ) - -SRCS( + +SRCS( GLOBAL terminate_handler.cpp - segv_handler.cpp -) - -END() + segv_handler.cpp +) + +END() diff --git a/library/cpp/testing/unittest/registar.cpp b/library/cpp/testing/unittest/registar.cpp index bfb87970d1..3679b768ed 100644 --- a/library/cpp/testing/unittest/registar.cpp +++ b/library/cpp/testing/unittest/registar.cpp @@ -5,10 +5,10 @@ #include <util/generic/bt_exception.h> #include <util/random/fast.h> -#include <util/string/printf.h> +#include <util/string/printf.h> #include <util/system/backtrace.h> #include <util/system/guard.h> -#include <util/system/tls.h> +#include <util/system/tls.h> #include <util/system/error.h> #include <util/string/cast.h> @@ -27,13 +27,13 @@ TString NUnitTest::RandomString(size_t len, ui32 seed) { return ret; } - + Y_POD_STATIC_THREAD(bool) UnittestThread; Y_POD_STATIC_THREAD(NUnitTest::TTestBase*) currentTest; ::NUnitTest::TRaiseErrorHandler RaiseErrorHandler; - + void ::NUnitTest::NPrivate::RaiseError(const char* what, const TString& msg, bool fatalFailure) { Y_VERIFY(UnittestThread, "%s in non-unittest thread with message:\n%s", what, msg.data()); Y_VERIFY(GetCurrentTest()); @@ -51,17 +51,17 @@ void ::NUnitTest::NPrivate::RaiseError(const char* what, const TString& msg, boo return; } throw TAssertException(); -} - +} + void ::NUnitTest::SetRaiseErrorHandler(::NUnitTest::TRaiseErrorHandler handler) { Y_VERIFY(UnittestThread); RaiseErrorHandler = std::move(handler); } -void ::NUnitTest::NPrivate::SetUnittestThread(bool unittestThread) { +void ::NUnitTest::NPrivate::SetUnittestThread(bool unittestThread) { Y_VERIFY(UnittestThread != unittestThread, "state check"); - UnittestThread = unittestThread; -} + UnittestThread = unittestThread; +} void ::NUnitTest::NPrivate::SetCurrentTest(TTestBase* test) { Y_VERIFY(!test || !currentTest, "state check"); diff --git a/library/cpp/testing/unittest/registar.h b/library/cpp/testing/unittest/registar.h index 594e6681e7..44517a0092 100644 --- a/library/cpp/testing/unittest/registar.h +++ b/library/cpp/testing/unittest/registar.h @@ -38,7 +38,7 @@ namespace NUnitTest { void SetCurrentTest(TTestBase*); TTestBase* GetCurrentTest(); } - + extern bool ShouldColorizeDiff; extern bool ContinueOnFail; TString ColoredDiff(TStringBuf s1, TStringBuf s2, const TString& delims = TString(), bool reverse = false); @@ -122,19 +122,19 @@ namespace NUnitTest { void Finish(const TFinish& descr); unsigned GoodTests() const noexcept; - + unsigned FailTests() const noexcept; unsigned GoodTestsInCurrentUnit() const noexcept; unsigned FailTestsInCurrentUnit() const noexcept; - // Should execute test suite? + // Should execute test suite? virtual bool CheckAccess(TString /*name*/, size_t /*num*/); - // Should execute a test whitin suite? + // Should execute a test whitin suite? virtual bool CheckAccessTest(TString /*suite*/, const char* /*name*/); - + virtual void Run(std::function<void()> f, const TString& /*suite*/, const char* /*name*/, bool /*forceFork*/); // This process is forked for current test @@ -157,7 +157,7 @@ namespace NUnitTest { virtual void OnFinish(const TFinish* /*finish*/); virtual void OnBeforeTest(const TTest* /*test*/); - + void AddTestError(const TTest& test); void AddTestFinish(const TTest& test); @@ -176,7 +176,7 @@ namespace NUnitTest { virtual ~ITestBaseFactory(); - // name of test suite + // name of test suite virtual TString Name() const noexcept = 0; virtual TTestBase* ConstructTest() = 0; @@ -210,9 +210,9 @@ namespace NUnitTest { protected: bool CheckAccessTest(const char* test); - + void BeforeTest(const char* func); - + void Finish(const char* func, TTestContext* context); void AtStart(); @@ -433,7 +433,7 @@ public: \ auto&& failMsg = Sprintf("%s != %s %s", ToString(_a).data(), ToString(_b).data(), (::TStringBuilder() << C).data()); \ UNIT_FAIL_IMPL("strings equal assertion failed", failMsg); \ } \ - } while (false) + } while (false) #define UNIT_ASSERT_STRINGS_EQUAL(A, B) UNIT_ASSERT_STRINGS_EQUAL_C(A, B, "") @@ -702,7 +702,7 @@ public: \ return false; } } - + //values #define UNIT_ASSERT_VALUES_EQUAL_IMPL(A, B, C, EQflag, EQstr, NEQstr) \ do { \ @@ -720,7 +720,7 @@ public: \ UNIT_FAIL_IMPL("assertion failed", failMsg); \ } \ } while (false) - + #define UNIT_ASSERT_VALUES_EQUAL_C(A, B, C) \ UNIT_ASSERT_VALUES_EQUAL_IMPL(A, B, C, true, "==", "!=") diff --git a/library/cpp/testing/unittest/utmain.cpp b/library/cpp/testing/unittest/utmain.cpp index 6cc2bfbbb1..305bc6b40f 100644 --- a/library/cpp/testing/unittest/utmain.cpp +++ b/library/cpp/testing/unittest/utmain.cpp @@ -216,7 +216,7 @@ public: inline void SetPrintBeforeSuite(bool print) { PrintBeforeSuite_ = print; } - + inline void SetPrintAfterSuite(bool print) { PrintAfterSuite_ = print; } @@ -224,7 +224,7 @@ public: inline void SetPrintBeforeTest(bool print) { PrintBeforeTest_ = print; } - + inline void SetPrintAfterTest(bool print) { PrintAfterTest_ = print; } @@ -286,7 +286,7 @@ public: inline void SetLoop(bool loop) { Loop = loop; } - + inline bool IsLoop() const { return Loop; } @@ -300,17 +300,17 @@ private: TraceProcessor->UnitStart(*unit); if (IsForked) { return; - } + } if (PrintBeforeSuite_ || PrintBeforeTest_) { fprintf(stderr, "%s<-----%s %s\n", LightBlueColor().data(), OldColor().data(), unit->name.data()); } } - + void OnUnitStop(const TUnit* unit) override { TraceProcessor->UnitStop(*unit); if (IsForked) { return; - } + } if (!PrintAfterSuite_) { return; } @@ -329,12 +329,12 @@ private: TraceProcessor->BeforeTest(*test); if (IsForked) { return; - } + } if (PrintBeforeTest_) { fprintf(stderr, "[%sexec%s] %s::%s...\n", LightBlueColor().data(), OldColor().data(), test->unit->name.data(), test->name); } } - + void OnError(const TError* descr) override { TraceProcessor->Error(*descr); if (!IsForked && ForkExitedCorrectly) { @@ -454,19 +454,19 @@ private: if (EnabledTests_.empty()) { return true; } - + if (EnabledTests_.find(TString() + suite + "::*") != EnabledTests_.end()) { return true; } - + return EnabledTests_.find(name) != EnabledTests_.end(); } - + void Run(std::function<void()> f, const TString& suite, const char* name, const bool forceFork) override { if (!(ForkTests || forceFork) || GetIsForked()) { return f(); - } - + } + TList<TString> args(1, "--is-forked-internal"); args.push_back(Sprintf("+%s::%s", suite.data(), name)); @@ -614,7 +614,7 @@ static int DoUsage(const char* progname) { << " -l, --list print a list of available tests\n" << " -A --list-verbose print a list of available subtests\n" << " --print-before-test print each test name before running it\n" - << " --print-before-suite print each test suite name before running it\n" + << " --print-before-suite print each test suite name before running it\n" << " --show-fails print a list of all failed tests at the end\n" << " --dont-show-fails do not print a list of all failed tests at the end\n" << " --continue-on-fail print a message and continue running test suite instead of break\n" @@ -686,9 +686,9 @@ int NUnitTest::RunMain(int argc, char** argv) { } else if (strcmp(name, "--list-verbose") == 0 || strcmp(name, "-A") == 0) { listTests = LIST_VERBOSE; } else if (strcmp(name, "--print-before-suite=false") == 0) { - processor.SetPrintBeforeSuite(false); - } else if (strcmp(name, "--print-before-test=false") == 0) { - processor.SetPrintBeforeTest(false); + processor.SetPrintBeforeSuite(false); + } else if (strcmp(name, "--print-before-test=false") == 0) { + processor.SetPrintBeforeTest(false); } else if (strcmp(name, "--print-before-suite") == 0) { processor.SetPrintBeforeSuite(true); } else if (strcmp(name, "--print-before-test") == 0) { @@ -709,10 +709,10 @@ int NUnitTest::RunMain(int argc, char** argv) { processor.SetEnd(FromString<size_t>(argv[i])); } else if (strcmp(name, "--fork-tests") == 0) { processor.SetForkTests(true); - } else if (strcmp(name, "--is-forked-internal") == 0) { + } else if (strcmp(name, "--is-forked-internal") == 0) { processor.SetIsForked(true); - } else if (strcmp(name, "--loop") == 0) { - processor.SetLoop(true); + } else if (strcmp(name, "--loop") == 0) { + processor.SetLoop(true); } else if (strcmp(name, "--trace-path") == 0) { ++i; processor.BeQuiet(); @@ -733,8 +733,8 @@ int NUnitTest::RunMain(int argc, char** argv) { size_t assign = param.find('='); Singleton<::NPrivate::TTestEnv>()->AddTestParam(param.substr(0, assign), param.substr(assign + 1)); } else if (TString(name).StartsWith("--")) { - return DoUsage(argv[0]), 1; - } else if (*name == '-') { + return DoUsage(argv[0]), 1; + } else if (*name == '-') { processor.Disable(name + 1); } else if (*name == '+') { processor.Enable(name + 1); @@ -750,15 +750,15 @@ int NUnitTest::RunMain(int argc, char** argv) { TTestFactory::Instance().SetProcessor(&processor); unsigned ret; - for (;;) { + for (;;) { ret = TTestFactory::Instance().Execute(); if (!processor.GetIsForked() && ret && processor.GetPrintSummary()) { - Cerr << "SOME TESTS FAILED!!!!" << Endl; - } - + Cerr << "SOME TESTS FAILED!!!!" << Endl; + } + if (0 != ret || !processor.IsLoop()) { break; - } + } } return ret; #ifndef UT_SKIP_EXCEPTIONS diff --git a/library/cpp/uri/common.h b/library/cpp/uri/common.h index ebe011731d..8025357763 100644 --- a/library/cpp/uri/common.h +++ b/library/cpp/uri/common.h @@ -487,7 +487,7 @@ namespace NUri { const char* FieldToString(const TField::EField& t); const char* ParsedStateToString(const TState::EParsed& t); const char* SchemeKindToString(const TScheme::EKind& t); - + } Y_DECLARE_OUT_SPEC(inline, NUri::TField::EField, out, t) { diff --git a/library/cpp/uri/uri.h b/library/cpp/uri/uri.h index 8481ff6780..3b6c19fe4a 100644 --- a/library/cpp/uri/uri.h +++ b/library/cpp/uri/uri.h @@ -616,7 +616,7 @@ namespace NUri { const char* LinkTypeToString(const TUri::TLinkType& t); } - + Y_DECLARE_OUT_SPEC(inline, NUri::TUri, out, url) { url.Print(out); } |