feat(hos_client_create, hos_client_destory): 多次调用destory不会导致重复释放

This commit is contained in:
彭宣正
2020-12-14 17:24:58 +08:00
parent 505d529c32
commit 10b370e486
55976 changed files with 8544395 additions and 2 deletions

View File

@@ -0,0 +1,148 @@
/**
* 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;
};
}
}

View File

@@ -0,0 +1,25 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#if defined (USE_WINDOWS_DLL_SEMANTICS) || defined (_WIN32)
#ifdef _MSC_VER
#pragma warning(disable : 4251)
#endif // _MSC_VER
#ifdef USE_IMPORT_EXPORT
#ifdef AWS_QUEUES_EXPORTS
#define AWS_QUEUES_API __declspec(dllexport)
#else // AWS_QUEUES_EXPORTS
#define AWS_QUEUES_API __declspec(dllimport)
#endif // AWS_QUEUES_EXPORTS
#else // USE_IMPORT_EXPORT
#define AWS_QUEUES_API
#endif // USE_IMPORT_EXPORT
#else // defined (USE_WINDOWS_DLL_SEMANTICS) || defined (_WIN32)
#define AWS_QUEUES_API
#endif // defined (USE_WINDOWS_DLL_SEMANTICS) || defined (_WIN32)

View File

@@ -0,0 +1,130 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#pragma once
#include <aws/queues/Queue.h>
#include <aws/sqs/model/Message.h>
#include <aws/queues/Queues_EXPORTS.h>
#include <memory>
#include <aws/core/client/AsyncCallerContext.h>
#include <aws/sqs/SQSClient.h>
namespace Aws
{
namespace SQS
{
namespace Model
{
class DeleteMessageRequest;
class SendMessageRequest;
}
}
namespace Queues
{
namespace Sqs
{
/**
* SQS implementation of the Queue interface. See Queue documentation for more details.
*/
class AWS_QUEUES_API SQSQueue : public Queue<Aws::SQS::Model::Message>
{
typedef std::function<void(const SQSQueue*, const Aws::SQS::Model::GetQueueAttributesOutcome&)> QueueAttributeSuccessEventHandler;
typedef std::function<void(const SQSQueue*, const Aws::SQS::Model::GetQueueAttributesRequest&)> QueueAttributeFailedEventHandler;
typedef std::function<void(const SQSQueue*, const Aws::SQS::Model::GetQueueAttributesRequest&)> QueueArnFailedEventHandler;
typedef std::function<void(const SQSQueue*, const Aws::String&)> QueueArnSuccessEventHandler;
public:
/**
* Notification that getting a queue arn was successful.
*/
inline void SetQueueArnSuccessEventHandler(const QueueArnSuccessEventHandler& messageHandler) { m_queueArnSuccessHandler = messageHandler; }
inline void SetQueueArnSuccessEventHandler(QueueArnSuccessEventHandler&& messageHandler) { m_queueArnSuccessHandler = messageHandler; }
/**
* Notification that getting a queue arn was successful.
*/
inline void SetQueueArnFailedEventHandler(const QueueArnFailedEventHandler& messageHandler) { m_queueArnFailedHandler = messageHandler; }
inline void SetQueueArnFailedEventHandler(QueueArnFailedEventHandler&& messageHandler) { m_queueArnFailedHandler = messageHandler; }
/**
* Notification that getting a queue attribute was successful.
*/
inline void SetQueueAttributeSuccessEventHandler(const QueueAttributeSuccessEventHandler& messageHandler) { m_queueAttributeSuccessHandler = messageHandler; }
inline void SetQueueAttributeSuccessEventHandler(QueueAttributeSuccessEventHandler&& messageHandler) { m_queueAttributeSuccessHandler = messageHandler; }
/**
* Notification that getting a queue attribute failed.
*/
inline void SetQueueAttributeFailedEventHandler(const QueueAttributeFailedEventHandler& messageHandler) { m_queueAttributeFailedHandler = messageHandler; }
inline void SetQueueAttributeFailedEventHandler(QueueAttributeFailedEventHandler&& messageHandler) { m_queueAttributeFailedHandler = messageHandler; }
inline const QueueArnSuccessEventHandler& GetQueueArnSuccessEventHandler() const { return m_queueArnSuccessHandler; }
inline const QueueArnFailedEventHandler& GetQueueArnFailedEventHandler() const { return m_queueArnFailedHandler; }
inline const QueueAttributeSuccessEventHandler& GetQueueAttributeSuccessEventHandler() const { return m_queueAttributeSuccessHandler; }
inline const QueueAttributeFailedEventHandler& GetQueueAttributeFailedEventHandler() const { return m_queueAttributeFailedHandler; }
/**
* Queue name is the name of the queue that the client should poll, push, and/or delete messages on. Call EnsureQueueIsInitialized to create the
* queue if it does not exist. You can call GetQueueUrl after IsInitialized() returns true to get your actual Queue URL.
*/
SQSQueue(const std::shared_ptr<SQS::SQSClient>& client, const char* queueName, unsigned visibilityTimeout, unsigned pollingFrequencyMs = 10000);
/**
* Will continue polling until a message is received or StopPolling is called.
*/
Aws::SQS::Model::Message Top() const override;
/**
* Does not block. Register for notifications of success or failure with the appropriate handlers.
*/
void Delete(const Aws::SQS::Model::Message&) override;
/**
* Does not block. Register for notifications of success or failure with the appropriate handlers.
*/
void Push(const Aws::SQS::Model::Message&) override;
/**
* Does not block. Register for notifications of success or failure with the appropriate handlers.
*/
void RequestArn();
/**
* At the very least, this gets your queue url. If the queue does not exist, this will create it.
*/
void EnsureQueueIsInitialized();
inline bool IsInitialized() const { return !m_queueUrl.empty(); }
inline const Aws::String& GetQueueUrl() const { return m_queueUrl; }
private:
std::shared_ptr<SQS::SQSClient> m_client;
Aws::String m_queueUrl;
Aws::String m_queueName;
unsigned m_visibilityTimeout;
void OnMessageDeletedOutcomeReceived(const SQS::SQSClient*, const SQS::Model::DeleteMessageRequest&,
const SQS::Model::DeleteMessageOutcome& deleteMessageOutcome, const std::shared_ptr<const Client::AsyncCallerContext>&);
void OnMessageSentOutcomeReceived(const SQS::SQSClient*, const SQS::Model::SendMessageRequest&,
const SQS::Model::SendMessageOutcome& deleteMessageOutcome, const std::shared_ptr<const Client::AsyncCallerContext>&);
void OnGetQueueAttributesOutcomeReceived(const SQS::SQSClient*, const SQS::Model::GetQueueAttributesRequest&,
const SQS::Model::GetQueueAttributesOutcome& deleteMessageOutcome, const std::shared_ptr<const Client::AsyncCallerContext>&);
QueueArnSuccessEventHandler m_queueArnSuccessHandler;
QueueArnFailedEventHandler m_queueArnFailedHandler;
QueueAttributeSuccessEventHandler m_queueAttributeSuccessHandler;
QueueAttributeFailedEventHandler m_queueAttributeFailedHandler;
};
}
}
}