summaryrefslogtreecommitdiff
path: root/cpp/examples/failover
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/examples/failover')
-rw-r--r--cpp/examples/failover/Makefile.am21
-rw-r--r--cpp/examples/failover/replaying_sender.cpp97
-rw-r--r--cpp/examples/failover/resuming_receiver.cpp106
3 files changed, 218 insertions, 6 deletions
diff --git a/cpp/examples/failover/Makefile.am b/cpp/examples/failover/Makefile.am
index 8fe6b8cba7..36969dbd36 100644
--- a/cpp/examples/failover/Makefile.am
+++ b/cpp/examples/failover/Makefile.am
@@ -1,8 +1,9 @@
-examplesdir=$(pkgdatadir)/examples/direct
+examplesdir=$(pkgdatadir)/examples/failover
include $(top_srcdir)/examples/makedist.mk
-noinst_PROGRAMS=direct_producer listener declare_queues
+noinst_PROGRAMS=direct_producer listener declare_queues resuming_receiver replaying_sender
+
direct_producer_SOURCES=direct_producer.cpp
direct_producer_LDADD=$(CLIENT_LIB)
@@ -12,10 +13,18 @@ listener_LDADD=$(CLIENT_LIB)
declare_queues_SOURCES=declare_queues.cpp
declare_queues_LDADD=$(CLIENT_LIB)
-examples_DATA= \
- direct_producer.cpp \
- listener.cpp \
- declare_queues.cpp \
+resuming_receiver_SOURCES=resuming_receiver.cpp
+resuming_receiver_LDADD=$(CLIENT_LIB)
+
+replaying_sender_SOURCES=replaying_sender.cpp
+replaying_sender_LDADD=$(CLIENT_LIB)
+
+examples_DATA= \
+ direct_producer.cpp \
+ listener.cpp \
+ declare_queues.cpp \
+ resuming_receiver.cpp \
+ replaying_sender.cpp \
$(MAKEDIST)
# FIXME aconway 2008-10-10: add verify scripts.
diff --git a/cpp/examples/failover/replaying_sender.cpp b/cpp/examples/failover/replaying_sender.cpp
new file mode 100644
index 0000000000..22a7e1ebd3
--- /dev/null
+++ b/cpp/examples/failover/replaying_sender.cpp
@@ -0,0 +1,97 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <qpid/client/FailoverManager.h>
+#include <qpid/client/Session.h>
+#include <qpid/client/AsyncSession.h>
+#include <qpid/client/Message.h>
+#include <qpid/client/MessageReplayTracker.h>
+#include <qpid/Exception.h>
+
+#include <iostream>
+#include <sstream>
+
+using namespace qpid;
+using namespace qpid::client;
+using namespace qpid::framing;
+
+using namespace std;
+
+class Sender : public FailoverManager::Command
+{
+ public:
+ Sender(const std::string& queue, uint count);
+ void execute(AsyncSession& session, bool isRetry);
+ uint getSent();
+ private:
+ MessageReplayTracker sender;
+ const uint count;
+ uint sent;
+ Message message;
+
+};
+
+Sender::Sender(const std::string& queue, uint count_) : sender(10), count(count_), sent(0)
+{
+ message.getDeliveryProperties().setRoutingKey(queue);
+}
+
+void Sender::execute(AsyncSession& session, bool isRetry)
+{
+ if (isRetry) sender.replay(session);
+ else sender.init(session);
+ while (sent < count) {
+ stringstream message_data;
+ message_data << ++sent;
+ message.setData(message_data.str());
+ message.getHeaders().setInt("sn", sent);
+ sender.send(message);
+ if (count > 1000 && !(sent % 1000)) {
+ std::cout << "sent " << sent << " of " << count << std::endl;
+ }
+ }
+ message.setData("That's all, folks!");
+ sender.send(message);
+}
+
+uint Sender::getSent()
+{
+ return sent;
+}
+
+int main(int argc, char ** argv)
+{
+ ConnectionSettings settings;
+ if (argc > 1) settings.host = argv[1];
+ if (argc > 2) settings.port = atoi(argv[2]);
+
+ FailoverManager connection(settings);
+ Sender sender("message_queue", argc > 3 ? atoi(argv[3]) : 1000);
+ try {
+ connection.execute(sender);
+ std::cout << "Sent " << sender.getSent() << " messages." << std::endl;
+ connection.close();
+ return 0;
+ } catch(const std::exception& error) {
+ std::cout << "Failed: " << error.what() << std::endl;
+ }
+ return 1;
+}
diff --git a/cpp/examples/failover/resuming_receiver.cpp b/cpp/examples/failover/resuming_receiver.cpp
new file mode 100644
index 0000000000..6ac67d8edb
--- /dev/null
+++ b/cpp/examples/failover/resuming_receiver.cpp
@@ -0,0 +1,106 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <qpid/client/FailoverManager.h>
+#include <qpid/client/Session.h>
+#include <qpid/client/Message.h>
+#include <qpid/client/SubscriptionManager.h>
+
+#include <iostream>
+#include <fstream>
+
+
+using namespace qpid;
+using namespace qpid::client;
+using namespace qpid::framing;
+
+using namespace std;
+
+
+class Listener : public MessageListener, public FailoverManager::Command
+{
+ public:
+ Listener();
+ void received(Message& message);
+ void execute(AsyncSession& session, bool isRetry);
+ private:
+ Subscription subscription;
+ uint count;
+ uint skipped;
+ uint lastSn;
+};
+
+Listener::Listener() : count(0), skipped(0), lastSn(0) {}
+
+void Listener::received(Message & message)
+{
+ if (message.getData() == "That's all, folks!") {
+ std::cout << "Shutting down listener for " << message.getDestination()
+ << std::endl;
+
+ std::cout << "Listener received " << count << " messages (" << skipped << " skipped)" << std::endl;
+ subscription.cancel();
+ } else {
+ uint sn = message.getHeaders().getAsInt("sn");
+ if (lastSn < sn) {
+ if (sn - lastSn > 1) {
+ std::cout << "Warning: gap in sequence between " << lastSn << " and " << sn << std::endl;
+ }
+ lastSn = sn;
+ ++count;
+ } else {
+ ++skipped;
+ }
+ }
+}
+
+void Listener::execute(AsyncSession& session, bool isRetry)
+{
+ if (isRetry) {
+ std::cout << "Resuming from " << count << std::endl;
+ }
+ SubscriptionManager subs(session);
+ subscription = subs.subscribe(*this, "message_queue");
+ subs.run();
+}
+
+int main(int argc, char ** argv)
+{
+ ConnectionSettings settings;
+ if (argc > 1) settings.host = argv[1];
+ if (argc > 2) settings.port = atoi(argv[2]);
+
+ FailoverManager connection(settings);
+ Listener listener;
+
+ try {
+ connection.execute(listener);
+ connection.close();
+ std::cout << "Completed without error." << std::endl;
+ return 0;
+ } catch(const std::exception& error) {
+ std::cout << "Failure: " << error.what() << std::endl;
+ }
+ return 1;
+}
+
+
+