This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
pxz-hos-client-cpp-module/support/aws-sdk-cpp-master/aws-cpp-sdk-queues/include/aws/queues/Queue.h

149 lines
7.2 KiB
C
Raw Normal View History

/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <aws/core/client/ClientConfiguration.h>
#include <aws/queues/Queues_EXPORTS.h>
#include <thread>
#include <atomic>
#include <functional>
namespace Aws
{
namespace Queues
{
static const char* MEM_TAG = "Aws::Queues::Queue";
/**
* Simple queue class. Allows standard queue operations top, delete, and push. Also has higher level, asynchronous interface
* with callbacks.
*/
template<typename MESSAGE_TYPE>
class Queue
{
typedef std::function<void(const Queue*, const MESSAGE_TYPE&, bool&)> MessageReceivedEventHandler;
typedef std::function<void(const Queue*, const MESSAGE_TYPE&)> MessageDeleteFailedEventHandler;
typedef std::function<void(const Queue*, const MESSAGE_TYPE&)> MessageDeleteSuccessEventHandler;
typedef std::function<void(const Queue*, const MESSAGE_TYPE&)> MessageSendFailedEventHandler;
typedef std::function<void(const Queue*, const MESSAGE_TYPE&)> MessageSendSuccessEventHandler;
public:
/**
* You are responsible for calling StartPolling() if you intend to use the asynchronous pattern.
*
* the value of pollingFrequency is how long to wait between queue polls. If the queue poll exceeds this limit then the next poll will start immediately
* upon completion of the existing poll, this value is useful only if you intend to use this instance for the asynchronous polling model.
*/
Queue(unsigned pollingFrequency) :
m_continue(true), m_pollingFrequencyMs(pollingFrequency), m_pollingThread(nullptr)
{
}
virtual ~Queue()
{
StopPolling();
}
virtual MESSAGE_TYPE Top() const = 0;
virtual void Delete(const MESSAGE_TYPE&) = 0;
virtual void Push(const MESSAGE_TYPE&) = 0;
/**
* Starts a polling thread in the background. You will need to register OnMessageReceived
* to receive the messages. This method can be called after StopPolling to resume polling after
* being paused.
*/
void StartPolling()
{
if(!m_pollingThread)
{
m_continue = true;
m_pollingThread = Aws::MakeUnique<std::thread>(MEM_TAG, &Queue::Main, this);
}
}
/**
* Stops the polling thread. Messages in transit will be handled before termination of the thread.
* Will be called by the destructor so only call this if you want control over when the thread exits.
* This method blocks waiting on the polling thread to stop. After being called, the StartPolling() method
* can be called, and the thread will resume.
*/
void StopPolling()
{
m_continue = false;
if(m_pollingThread)
{
m_pollingThread->join();
m_pollingThread = nullptr;
}
}
inline void SetMessageReceivedEventHandler(const MessageReceivedEventHandler& messageHandler) { m_messageReceivedHandler = messageHandler; }
inline void SetMessageDeleteFailedEventHandler(const MessageDeleteFailedEventHandler& messageHandler) { m_messageDeleteFailedHandler = messageHandler; }
inline void SetMessageDeleteSuccessEventHandler(const MessageDeleteSuccessEventHandler& messageHandler) { m_messageDeleteSuccessHandler = messageHandler; }
inline void SetMessageSendFailedEventHandler(const MessageSendFailedEventHandler& messageHandler) { m_messageSendFailedHandler = messageHandler; }
inline void SetMessageSendSuccessEventHandler(const MessageSendSuccessEventHandler& messageHandler) { m_messageSendSuccessHandler = messageHandler; }
inline void SetMessageReceivedEventHandler(MessageReceivedEventHandler&& messageHandler) { m_messageReceivedHandler = messageHandler; }
inline void SetMessageDeleteFailedEventHandler(MessageDeleteFailedEventHandler&& messageHandler) { m_messageDeleteFailedHandler = messageHandler; }
inline void SetMessageDeleteSuccessEventHandler(MessageDeleteSuccessEventHandler&& messageHandler) { m_messageDeleteSuccessHandler = messageHandler; }
inline void SetMessageSendFailedEventHandler(MessageSendFailedEventHandler&& messageHandler) { m_messageSendFailedHandler = messageHandler; }
inline void SetMessageSendSuccessEventHandler(MessageSendSuccessEventHandler&& messageHandler) { m_messageSendSuccessHandler = messageHandler; }
inline const MessageReceivedEventHandler& GetMessageReceivedEventHandler() const { return m_messageReceivedHandler; }
inline const MessageDeleteFailedEventHandler& GetMessageDeleteFailedEventHandler() const { return m_messageDeleteFailedHandler; }
inline const MessageDeleteSuccessEventHandler& GetMessageDeleteSuccessEventHandler() const { return m_messageDeleteSuccessHandler; }
inline const MessageSendFailedEventHandler& GetMessageSendFailedEventHandler() const { return m_messageSendFailedHandler; }
inline const MessageSendSuccessEventHandler& GetMessageSendSuccessEventHandler() const { return m_messageSendSuccessHandler; }
protected:
std::atomic<bool> m_continue;
private:
void Main()
{
while(m_continue)
{
auto start = std::chrono::system_clock::now();
MESSAGE_TYPE topMessage = Top();
bool deleteMessage = false;
auto& receivedHandler = GetMessageReceivedEventHandler();
if (receivedHandler)
{
receivedHandler(this, topMessage, deleteMessage);
}
if (deleteMessage)
{
Delete(topMessage);
}
if(m_continue)
{
auto stop = std::chrono::system_clock::now();
auto timeTaken = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
if (m_pollingFrequencyMs >= timeTaken.count())
{
std::this_thread::sleep_for(std::chrono::milliseconds(m_pollingFrequencyMs - timeTaken.count()));
}
}
}
}
unsigned m_pollingFrequencyMs;
Aws::UniquePtr<std::thread> m_pollingThread;
// Handlers
MessageReceivedEventHandler m_messageReceivedHandler;
MessageDeleteFailedEventHandler m_messageDeleteFailedHandler;
MessageDeleteSuccessEventHandler m_messageDeleteSuccessHandler;
MessageSendFailedEventHandler m_messageSendFailedHandler;
MessageSendSuccessEventHandler m_messageSendSuccessHandler;
};
}
}