-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathHttpExecutionTaskManager.cpp
More file actions
130 lines (108 loc) · 4.65 KB
/
Copy pathHttpExecutionTaskManager.cpp
File metadata and controls
130 lines (108 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* Copyright 2017 Sony Corporation
*/
#include "easyhttpcpp/common/CoreLogger.h"
#include "easyhttpcpp/common/CommonException.h"
#include "easyhttpcpp/executorservice/ExecutorServiceException.h"
#include "easyhttpcpp/executorservice/UnboundBlockingQueue.h"
#include "easyhttpcpp/HttpException.h"
#include "HttpExecutionTaskManager.h"
using easyhttpcpp::common::FutureCancellationException;
using easyhttpcpp::common::FutureExecutionException;
using easyhttpcpp::executorservice::ExecutorServiceException;
using easyhttpcpp::executorservice::QueuedThreadPool;
using easyhttpcpp::executorservice::UnboundBlockingQueue;
namespace easyhttpcpp {
static const std::string Tag = "HttpExecutionTaskManager";
HttpExecutionTaskManager::HttpExecutionTaskManager(unsigned int corePoolSizeOfAsyncThreadPool,
unsigned int maximumPoolSizeOfAsyncThreadPool) : m_terminated(false)
{
try {
m_pAsyncThreadPool = new QueuedThreadPool(corePoolSizeOfAsyncThreadPool,
maximumPoolSizeOfAsyncThreadPool, new UnboundBlockingQueue());
} catch (const ExecutorServiceException& e) {
EASYHTTPCPP_LOG_D(Tag, "Can not create QueuedThreadPool. Details:%s", e.getMessage().c_str());
throw HttpExecutionException("Can not create asynchronous thread pool. Check getCause() for details.", e);
}
}
HttpExecutionTaskManager::~HttpExecutionTaskManager()
{
}
void HttpExecutionTaskManager::start(HttpExecutionTask::Ptr pExecutionTask)
{
try {
Poco::FastMutex::ScopedLock lock(m_instanceMutex);
if (m_terminated) {
EASYHTTPCPP_LOG_D(Tag, "HttpExecutionTaskManager was already terminated");
throw HttpIllegalStateException("Failed to execute task, because EasyHttp was invalidated.");
}
if (!m_pAsyncThreadPool) {
EASYHTTPCPP_LOG_D(Tag, "HttpExecutionTaskManager was terminated");
throw HttpIllegalStateException("Failed to execute task, because EasyHttp was released.");
}
m_executionTaskList.push_back(pExecutionTask);
EASYHTTPCPP_LOG_D(Tag, "add HttpExecutionTask.[%p]", pExecutionTask.get());
m_pAsyncThreadPool->start(pExecutionTask);
} catch (const ExecutorServiceException& e) {
removeTask(pExecutionTask);
EASYHTTPCPP_LOG_D(Tag, "QueuedThreadPool::start failed. Details:%s", e.getMessage().c_str());
throw HttpExecutionException("Can not start asynchronous execute. getCause() for details.", e);
}
}
void HttpExecutionTaskManager::gracefulShutdown()
{
ExecutionList executionTaskListCopy;
{
Poco::FastMutex::ScopedLock lock(m_instanceMutex);
if (m_terminated) {
EASYHTTPCPP_LOG_D(Tag, "HttpExecutionTaskManager is already terminated.");
return;
}
m_terminated = true;
// after shutdown, can not execute start method.
m_pAsyncThreadPool->shutdown();
executionTaskListCopy = m_executionTaskList;
}
// cancel all task
for (ExecutionList::iterator itr = executionTaskListCopy.begin(); itr != executionTaskListCopy.end(); itr++) {
(*itr)->cancel(true);
}
// wait for all task to complete.
for (ExecutionList::iterator itr = executionTaskListCopy.begin(); itr != executionTaskListCopy.end(); itr++) {
try {
// wait task.
(*itr)->get();
} catch (const FutureCancellationException& e) {
EASYHTTPCPP_LOG_D(Tag, "HttpExecutionTask got cancelled successfully. Details: %s", e.getMessage().c_str());
// ignore FutureCancellationException.
} catch (const FutureExecutionException& e) {
EASYHTTPCPP_LOG_D(Tag, "HttpExecutionTask completed with error while waiting for completion. Details: %s",
e.getMessage().c_str());
// ignore FutureExecutionException.
}
}
{
Poco::FastMutex::ScopedLock lock(m_instanceMutex);
// wait for all threads to finish completely
m_pAsyncThreadPool->shutdownAndJoinAll();
// release QueuedThreadPool.
m_pAsyncThreadPool = NULL;
}
}
void HttpExecutionTaskManager::onComplete(HttpExecutionTask::Ptr pExecutionTask)
{
removeTask(pExecutionTask);
}
void HttpExecutionTaskManager::removeTask(HttpExecutionTask::Ptr pExecutionTask)
{
Poco::FastMutex::ScopedLock lock(m_instanceMutex);
for (ExecutionList::iterator itr = m_executionTaskList.begin();
itr != m_executionTaskList.end(); itr++) {
if (*itr == pExecutionTask) {
EASYHTTPCPP_LOG_D(Tag, "remove HttpExecutionTask.[%p]", pExecutionTask.get());
m_executionTaskList.erase(itr);
break;
}
}
}
} /* namespace easyhttpcpp */