# yamq **Repository Path**: RonxBulld/yamq ## Basic Information - **Project Name**: yamq - **Description**: This is the single head file that implement message queue framework. - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-04-29 - **Last Updated**: 2022-05-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README yamq - Yet Another Message Queue --- This is the single head file that implement message queue framework. ## Basics ```c++ #include ``` Create a `Observer` template class inherit from `ObserverBase`, and override `Invoke`. ```c++ class Observer : public yamq::ObserverBase { public: Observer() = default ; ~Observer() override = default ; void Invoke(const yamq::KVdb &kvdb) override { std::cout << kvdb[""] << std::endl; } }; ``` Then, create a serial or parallel `PubSub` instance, ```c++ yamq::PubSub pubsub; ``` or ```c++ yamq::PubSub pubsub(32); ``` and `Observer` instance. ```c++ Observer obi; ``` After that, register this observer instance. ```c++ pubsub.Subscribe("", obi); ``` Alternatively, you can use lambda expressions instead of observer instances. ```c++ pubsub.Subscribe("aaa", [](const yamq::KVdb &kvdb) { std::cout << "Lambda recived: " << kvdb[""] << std::endl; }); ``` Finally, you can broadcast your defined message by calling the `yamq::PubSub::Publish` interface. ```c++ yamq::KVdb kvdb; kvdb[""] = "Resolved."; pubsub.Publish("", kvdb); ``` To subscribe to other message channel, you can modify the first stuff of calling `Subscribe`. Similarly, it can only receive messages with the same first parameter of `Publish`. ```c++ pubsub.Subscribe("other", obi); pubsub.Publish("other", kvdb); ``` ## Deregister observer When the observer object is released, `ObserverBase` will automatically notify all related PubSub objects to deregister it. And, you can use `Disconnect` and `DisconnectAll` to manually control unbinding from any PubSub object. ```c++ obi.DisconnectAll(); obi.Disconnect(&pubsub); ``` ## While destruct When the object is ready for destruction, you need to pay attention to whether your task has stopped, otherwise it will cause some uncertain problems. You can use `DisableAndWait` before this to avoid this problem. ```c++ obk->DisableAndWait(); delete obk; ``` ## Full example Putting all together: ```c++ #include #include class ConsoleOut { private: std::string prompt_; public: explicit ConsoleOut(const std::string &prompt = "") : prompt_(prompt) {} void WriteOut(const std::string &str) { std::cout << prompt_ << ": " << str << std::endl; } }; template class Observer : public yamq::ObserverBase { private: ConsoleOut &console_out_; public: explicit Observer(ConsoleOut &CO) : console_out_(CO) {} void Invoke(const yamq::KVdb &kvdb) override { console_out_.WriteOut(kvdb[""] + kvdb["i"]); } ~Observer() override = default ; }; int main() { ConsoleOut co("Test"); ConsoleOut ck("Echo"); Observer obi(co); Observer *obk = new Observer(ck); yamq::PubSub pubsub; pubsub.Subscribe("aaa", obi); pubsub.Subscribe("aaa", *obk); pubsub.Subscribe("aaa", [](const yamq::KVdb &kvdb) { std::cout << "Lambda recived: " << kvdb[""] << std::endl; }); bool obi_reg = true; yamq::KVdb kvdb; kvdb[""] = "Resolved."; int i = 0; while(i++ < 10000) { kvdb["i"] = std::to_string(i); pubsub.Publish("aaa", kvdb); if ((i >= 5000) && obk) { obk->DisableAndWait(); delete obk; obk = nullptr; } if (obi_reg && (i >= 1000)) { obi.Disconnect(&pubsub); obi_reg = false; } } return 0; } ``` ## Linking This is a header only library.