@@ -171,7 +171,7 @@ void RedisConnection::FireAndForgetQuery(Query query, QueryAffects affects, bool
171171 auto item (Shared<Query>::Make (std::move (query)));
172172
173173 asio::post (m_Strand, [this , item, highPriority, affects, ctime = std::chrono::steady_clock::now ()]() {
174- auto qitem = WriteQueueItem{item, nullptr , nullptr , nullptr , nullptr , ctime, affects, highPriority};
174+ auto qitem = WriteQueueItem{item, ctime, affects, highPriority};
175175 if (highPriority) {
176176 m_Queues.PushFront (std::move (qitem));
177177 } else {
@@ -201,7 +201,7 @@ void RedisConnection::FireAndForgetQueries(RedisConnection::Queries queries, Que
201201 auto item (Shared<Queries>::Make (std::move (queries)));
202202
203203 asio::post (m_Strand, [this , item, affects, ctime = std::chrono::steady_clock::now ()]() {
204- m_Queues.Writes .push_back (WriteQueueItem{nullptr , item, nullptr , nullptr , nullptr , ctime, affects});
204+ m_Queues.Writes .push_back (WriteQueueItem{item, ctime, affects});
205205 m_QueuedWrites.Set ();
206206 IncreasePendingQueries (item->size ());
207207 });
@@ -228,7 +228,7 @@ RedisConnection::Reply RedisConnection::GetResultOfQuery(RedisConnection::Query
228228 auto item (Shared<std::pair<Query, std::promise<Reply>>>::Make (std::move (query), std::move (promise)));
229229
230230 asio::post (m_Strand, [this , item, affects, ctime = std::chrono::steady_clock::now ()]() {
231- m_Queues.Writes .push_back (WriteQueueItem{nullptr , nullptr , item, nullptr , nullptr , ctime, affects});
231+ m_Queues.Writes .push_back (WriteQueueItem{item, ctime, affects});
232232 m_QueuedWrites.Set ();
233233 IncreasePendingQueries (1 );
234234 });
@@ -261,7 +261,7 @@ RedisConnection::Replies RedisConnection::GetResultsOfQueries(Queries queries, Q
261261 auto item (Shared<std::pair<Queries, std::promise<Replies>>>::Make (std::move (queries), std::move (promise)));
262262
263263 asio::post (m_Strand, [this , item, highPriority, affects, ctime = std::chrono::steady_clock::now ()]() {
264- auto qitem = WriteQueueItem{nullptr , nullptr , nullptr , item, nullptr , ctime, affects, highPriority};
264+ auto qitem = WriteQueueItem{item, ctime, affects, highPriority};
265265 if (highPriority) {
266266 m_Queues.PushFront (std::move (qitem));
267267 } else {
@@ -281,7 +281,7 @@ void RedisConnection::EnqueueCallback(const std::function<void(boost::asio::yiel
281281 AssertNotStopped ();
282282
283283 asio::post (m_Strand, [this , callback, ctime = std::chrono::steady_clock::now ()]() {
284- m_Queues.Writes .push_back (WriteQueueItem{nullptr , nullptr , nullptr , nullptr , callback, ctime});
284+ m_Queues.Writes .push_back (WriteQueueItem{callback, ctime});
285285 m_QueuedWrites.Set ();
286286 });
287287}
@@ -516,7 +516,14 @@ void RedisConnection::WriteLoop(asio::yield_context& yc)
516516 auto queuedWrite (std::move (m_Queues.Writes .front ()));
517517 m_Queues.Writes .pop_front ();
518518
519- WriteItem (yc, std::move (queuedWrite));
519+ std::visit (
520+ [this , &yc, &queuedWrite](const auto & item) {
521+ if (WriteItem (item, yc)) {
522+ RecordAffected (queuedWrite.Affects , Utility::GetTime ());
523+ }
524+ },
525+ queuedWrite.Item
526+ );
520527 }
521528
522529 m_QueuedWrites.Clear ();
@@ -559,111 +566,138 @@ void RedisConnection::LogStats(asio::yield_context& yc)
559566}
560567
561568/* *
562- * Send next and schedule receiving the response
569+ * Write a single Redis query in a fire-and-forget manner.
570+ *
571+ * @param item Redis query
563572 *
564- * @param next Redis queries
573+ * @return true on success, false on failure.
565574 */
566- void RedisConnection::WriteItem (boost::asio::yield_context& yc, RedisConnection::WriteQueueItem next )
575+ bool RedisConnection::WriteItem (const FireAndForgetQ& item, boost::asio::yield_context& yc)
567576{
568- if (next.FireAndForgetQuery ) {
569- auto & item (*next.FireAndForgetQuery );
570- DecreasePendingQueries (1 );
577+ DecreasePendingQueries (1 );
571578
572- try {
573- WriteOne (item, yc);
574- } catch (const std::exception& ex) {
575- Log msg (LogCritical, " IcingaDB" , " Error during sending query" );
576- LogQuery (item, msg);
577- msg << " which has been fired and forgotten: " << ex.what ();
579+ try {
580+ WriteOne (* item, yc);
581+ } catch (const std::exception& ex) {
582+ Log msg (LogCritical, " IcingaDB" , " Error during sending query" );
583+ LogQuery (* item, msg);
584+ msg << " which has been fired and forgotten: " << ex.what ();
578585
579- return ;
580- }
581-
582- if (m_Queues.FutureResponseActions .empty () || m_Queues.FutureResponseActions .back ().Action != ResponseAction::Ignore) {
583- m_Queues.FutureResponseActions .emplace (FutureResponseAction{1 , ResponseAction::Ignore});
584- } else {
585- ++m_Queues.FutureResponseActions .back ().Amount ;
586- }
586+ return false ;
587+ }
587588
588- m_QueuedReads.Set ();
589+ if (m_Queues.FutureResponseActions .empty () || m_Queues.FutureResponseActions .back ().Action != ResponseAction::Ignore) {
590+ m_Queues.FutureResponseActions .emplace (FutureResponseAction{1 , ResponseAction::Ignore});
591+ } else {
592+ ++m_Queues.FutureResponseActions .back ().Amount ;
589593 }
590594
591- if (next. FireAndForgetQueries ) {
592- auto & item (*next. FireAndForgetQueries ) ;
593- size_t i = 0 ;
595+ m_QueuedReads. Set ();
596+ return true ;
597+ }
594598
595- DecreasePendingQueries (item.size ());
599+ /* *
600+ * Write multiple Redis queries in a fire-and-forget manner.
601+ *
602+ * @param item Redis queries
603+ *
604+ * @return true on success, false on failure.
605+ */
606+ bool RedisConnection::WriteItem (const FireAndForgetQs& item, boost::asio::yield_context& yc)
607+ {
608+ size_t i = 0 ;
596609
597- try {
598- for (auto & query : item) {
599- WriteOne (query, yc);
600- ++i;
601- }
602- } catch (const std::exception& ex) {
603- Log msg (LogCritical, " IcingaDB" , " Error during sending query" );
604- LogQuery (item[i], msg);
605- msg << " which has been fired and forgotten: " << ex.what ();
610+ DecreasePendingQueries (item->size ());
606611
607- return ;
612+ try {
613+ for (auto & query : *item) {
614+ WriteOne (query, yc);
615+ ++i;
608616 }
617+ } catch (const std::exception& ex) {
618+ Log msg (LogCritical, " IcingaDB" , " Error during sending query" );
619+ LogQuery ((*item)[i], msg);
620+ msg << " which has been fired and forgotten: " << ex.what ();
609621
610- if (m_Queues.FutureResponseActions .empty () || m_Queues.FutureResponseActions .back ().Action != ResponseAction::Ignore) {
611- m_Queues.FutureResponseActions .emplace (FutureResponseAction{item.size (), ResponseAction::Ignore});
612- } else {
613- m_Queues.FutureResponseActions .back ().Amount += item.size ();
614- }
622+ return false ;
623+ }
615624
616- m_QueuedReads.Set ();
625+ if (m_Queues.FutureResponseActions .empty () || m_Queues.FutureResponseActions .back ().Action != ResponseAction::Ignore) {
626+ m_Queues.FutureResponseActions .emplace (FutureResponseAction{item->size (), ResponseAction::Ignore});
627+ } else {
628+ m_Queues.FutureResponseActions .back ().Amount += item->size ();
617629 }
618630
619- if (next. GetResultOfQuery ) {
620- auto & item (*next. GetResultOfQuery ) ;
621- DecreasePendingQueries ( 1 );
631+ m_QueuedReads. Set ();
632+ return true ;
633+ }
622634
623- try {
624- WriteOne (item.first , yc);
625- } catch (const std::exception&) {
626- item.second .set_exception (std::current_exception ());
635+ /* *
636+ * Write a single Redis query and enqueue a response promise to be fulfilled once the response has been received.
637+ *
638+ * @param item Redis query and promise for the response
639+ */
640+ bool RedisConnection::WriteItem (const QueryWithPromise& item, boost::asio::yield_context& yc)
641+ {
642+ DecreasePendingQueries (1 );
627643
628- return ;
629- }
644+ try {
645+ WriteOne (item->first , yc);
646+ } catch (const std::exception&) {
647+ item->second .set_exception (std::current_exception ());
630648
631- m_Queues.ReplyPromises .emplace (std::move (item.second ));
649+ return false ;
650+ }
632651
633- if (m_Queues.FutureResponseActions .empty () || m_Queues.FutureResponseActions .back ().Action != ResponseAction::Deliver) {
634- m_Queues.FutureResponseActions .emplace (FutureResponseAction{1 , ResponseAction::Deliver});
635- } else {
636- ++m_Queues.FutureResponseActions .back ().Amount ;
637- }
652+ m_Queues.ReplyPromises .push (std::move (item->second ));
638653
639- m_QueuedReads.Set ();
654+ if (m_Queues.FutureResponseActions .empty () || m_Queues.FutureResponseActions .back ().Action != ResponseAction::Deliver) {
655+ m_Queues.FutureResponseActions .emplace (FutureResponseAction{1 , ResponseAction::Deliver});
656+ } else {
657+ ++m_Queues.FutureResponseActions .back ().Amount ;
640658 }
641659
642- if (next. GetResultsOfQueries ) {
643- auto & item (*next. GetResultsOfQueries ) ;
644- DecreasePendingQueries (item. first . size ());
660+ m_QueuedReads. Set ();
661+ return true ;
662+ }
645663
646- try {
647- for (auto & query : item.first ) {
648- WriteOne (query, yc);
649- }
650- } catch (const std::exception&) {
651- item.second .set_exception (std::current_exception ());
664+ /* *
665+ * Write multiple Redis queries and enqueue a response promise to be fulfilled once all responses have been received.
666+ *
667+ * @param item Redis queries and promise for the responses.
668+ *
669+ * @return true on success, false on failure.
670+ */
671+ bool RedisConnection::WriteItem (const QueriesWithPromise& item, boost::asio::yield_context& yc)
672+ {
673+ DecreasePendingQueries (item->first .size ());
652674
653- return ;
675+ try {
676+ for (auto & query : item->first ) {
677+ WriteOne (query, yc);
654678 }
679+ } catch (const std::exception&) {
680+ item->second .set_exception (std::current_exception ());
655681
656- m_Queues.RepliesPromises .emplace (std::move (item.second ));
657- m_Queues.FutureResponseActions .emplace (FutureResponseAction{item.first .size (), ResponseAction::DeliverBulk});
658-
659- m_QueuedReads.Set ();
682+ return false ;
660683 }
661684
662- if (next.Callback ) {
663- next.Callback (yc);
664- }
685+ m_Queues.RepliesPromises .emplace (std::move (item->second ));
686+ m_Queues.FutureResponseActions .emplace (FutureResponseAction{item->first .size (), ResponseAction::DeliverBulk});
665687
666- RecordAffected (next.Affects , Utility::GetTime ());
688+ m_QueuedReads.Set ();
689+ return true ;
690+ }
691+
692+ /* *
693+ * Invokes the provided callback immediately.
694+ *
695+ * @param item Callback to execute
696+ */
697+ bool RedisConnection::WriteItem (const QueryCallback& item, boost::asio::yield_context& yc)
698+ {
699+ item (yc);
700+ return true ;
667701}
668702
669703/* *
0 commit comments